Updating Microsemi Driver to onos-yang-tools 2.x
Change-Id: I80e3348087518a8f9a742c813b6238371a3f8f97
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000FlowRuleProgrammable.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000FlowRuleProgrammable.java
new file mode 100644
index 0000000..4df22ec
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000FlowRuleProgrammable.java
@@ -0,0 +1,974 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.math.BigInteger;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+
+import org.onlab.packet.EthType;
+import org.onlab.packet.EthType.EtherType;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.drivers.microsemi.yang.MseaSaFilteringNetconfService;
+import org.onosproject.drivers.microsemi.yang.MseaUniEvcServiceNetconfService;
+import org.onosproject.drivers.microsemi.yang.UniSide;
+import org.onosproject.drivers.microsemi.yang.custom.CustomEvcPerUnic;
+import org.onosproject.drivers.microsemi.yang.custom.CustomEvcPerUnin;
+import org.onosproject.drivers.microsemi.yang.utils.CeVlanMapUtils;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowEntry.FlowEntryState;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleProgrammable;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.Criterion.Type;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanHeaderInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfDevice;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFilteringOpParam;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.DefaultSourceIpaddressFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.SourceIpaddressFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.DefaultInterfaceEth0;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.InterfaceEth0;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.interfaceeth0.DefaultSourceAddressRange;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.interfaceeth0.FilterAdminStateEnum;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.interfaceeth0.SourceAddressRange;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.Identifier45;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.ServiceListType;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.VlanIdType;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcService;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcServiceOpParam;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.DefaultMefServices;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.MefServices;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.DefaultFlowMapping;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.FlowMapping;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.TagManipulation;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.DefaultTagOverwrite;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.DefaultTagPop;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.DefaultTagPush;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.TagOverwrite;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.TagPop;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.TagPush;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.tagpush.tagpush.PushTagTypeEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.DefaultProfiles;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.DefaultUni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.Profiles;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.Uni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.BwpGroup;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.DefaultBwpGroup;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.DefaultEvc;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.Evc;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.UniSideInterfaceAssignmentEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.DefaultEvcPerUni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.EvcPerUni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.evcperuni.EvcPerUnic;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.evcperuni.EvcPerUnin;
+import org.slf4j.Logger;
+
+/**
+ * An implementation of the FlowRuleProgrammable behaviour for the EA10000 device.
+ *
+ * This device is not a native Open Flow device. It has only a NETCONF interface for configuration
+ * status retrieval and notifications. It supports only a small subset of OpenFlow rules.<br>
+ *
+ * The device supports only:<br>
+ * 1) Open flow rules that blocks certain IP address ranges, but only those incoming on Port 0
+ * and has a limit of 10 such rules<br>
+ * 2) Open flow rules that PUSH, POP and OVERWRITE VLAN tags on both ports. This can push and overwrite
+ * both C-TAGs (0x8100) and S-TAGs (0x88a8).
+ */
+public class EA1000FlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
+
+ protected final Logger log = getLogger(getClass());
+ public static final String MICROSEMI_DRIVERS = "com.microsemi.drivers";
+ public static final int PRIORITY_DEFAULT = 50000;
+ //To protect the NETCONF session from concurrent access across flow addition and removal
+ static Semaphore sessionMutex = new Semaphore(1);
+
+ /**
+ * Get the flow entries that are present on the EA1000.
+ * Since the EA1000 does not have any 'real' flow entries these are retrieved from 2 configuration
+ * areas on the EA1000 NETCONF model - from SA filtering YANG model and from EVC UNI YANG model.<br>
+ * The flow entries must match exactly the FlowRule entries in the ONOS store. If they are not an
+ * exact match the device will be requested to remove those flows and the FlowRule will stay in a
+ * PENDING_ADD state.
+ * @return A collection of Flow Entries
+ */
+ @Override
+ public Collection<FlowEntry> getFlowEntries() {
+ Collection<FlowEntry> flowEntryCollection = new HashSet<FlowEntry>();
+
+ UniSideInterfaceAssignmentEnum portAssignment = UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST;
+ NetconfController controller = checkNotNull(handler().get(NetconfController.class));
+ NetconfDevice ncDevice = controller.getDevicesMap().get(handler().data().deviceId());
+ if (ncDevice == null) {
+ log.error("Internal ONOS Error. Device has been marked as reachable, " +
+ "but deviceID {} is not in Devices Map. Continuing with empty description",
+ handler().data().deviceId());
+ return flowEntryCollection;
+ }
+ NetconfSession session = ncDevice.getSession();
+ CoreService coreService = checkNotNull(handler().get(CoreService.class));
+ ApplicationId appId = coreService.getAppId(MICROSEMI_DRIVERS);
+ MseaSaFilteringNetconfService mseaSaFilteringService =
+ (MseaSaFilteringNetconfService) checkNotNull(handler().get(MseaSaFilteringNetconfService.class));
+ MseaUniEvcServiceNetconfService mseaUniEvcServiceSvc =
+ (MseaUniEvcServiceNetconfService) checkNotNull(handler().get(MseaUniEvcServiceNetconfService.class));
+ log.debug("getFlowEntries() called on EA1000FlowRuleProgrammable");
+
+ //First get the MseaSaFiltering rules
+ SourceIpaddressFiltering sip =
+ new DefaultSourceIpaddressFiltering();
+
+ MseaSaFilteringOpParam op =
+ new MseaSaFilteringOpParam();
+ op.sourceIpaddressFiltering(sip);
+
+ try {
+ MseaSaFiltering saFilteringCurrent =
+ mseaSaFilteringService.getMseaSaFiltering(op, session);
+ if (saFilteringCurrent != null &&
+ saFilteringCurrent.sourceIpaddressFiltering() != null) {
+ flowEntryCollection.addAll(
+ convertSaFilteringToFlowRules(saFilteringCurrent, appId));
+ }
+ } catch (NetconfException e) {
+ if (e.getCause() instanceof TimeoutException) {
+ log.warn("Timeout exception getting SA Filt Flow Entries from {}",
+ handler().data().deviceId());
+ return flowEntryCollection;
+ } else {
+ log.error("Unexpected error on SA Filt getFlowEntries on {}",
+ handler().data().deviceId(), e);
+ }
+ }
+
+
+ //Then get the EVCs - there will be a flow entry per EVC
+ MefServices mefServices = new DefaultMefServices();
+ mefServices.uni(new DefaultUni());
+
+ MseaUniEvcServiceOpParam mseaUniEvcServiceFilter = new MseaUniEvcServiceOpParam();
+ mseaUniEvcServiceFilter.mefServices(mefServices);
+ try {
+ MseaUniEvcService uniEvcCurrent =
+ mseaUniEvcServiceSvc.getConfigMseaUniEvcService(mseaUniEvcServiceFilter,
+ session, DatastoreId.RUNNING);
+
+ flowEntryCollection.addAll(
+ convertEvcUniToFlowRules(uniEvcCurrent, portAssignment));
+
+ } catch (NetconfException e) {
+ if (e.getCause() instanceof TimeoutException) {
+ log.warn("Timeout exception getting EVC Flow Entries from {}",
+ handler().data().deviceId());
+ return flowEntryCollection;
+ } else {
+ log.error("Unexpected error on EVC getFlowEntries on {}",
+ handler().data().deviceId(), e);
+ }
+ }
+
+ return flowEntryCollection;
+ }
+
+ /**
+ * Apply the flow entries to the EA1000.
+ * Since the EA1000 does not have any 'real' flow entries these are converted 2 configuration
+ * areas on the EA1000 NETCONF model - to SA filtering YANG model and to EVC UNI YANG model.<br>
+ * Only a subset of the possible OpenFlow rules are supported. Any rule that's not handled
+ * will not be in the returned set.
+ *
+ * @param rules A collection of Flow Rules to be applied to the EA1000
+ * @return A collection of the Flow Rules that have been added.
+ */
+ @Override
+ public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
+ Collection<FlowRule> frAdded = new HashSet<FlowRule>();
+ if (rules == null || rules.size() == 0) {
+ return rules;
+ }
+ NetconfController controller = checkNotNull(handler().get(NetconfController.class));
+ NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession();
+ MseaSaFilteringNetconfService mseaSaFilteringService =
+ (MseaSaFilteringNetconfService) checkNotNull(handler().get(MseaSaFilteringNetconfService.class));
+ MseaUniEvcServiceNetconfService mseaUniEvcServiceSvc =
+ (MseaUniEvcServiceNetconfService) checkNotNull(handler().get(MseaUniEvcServiceNetconfService.class));
+ log.debug("applyFlowRules() called on EA1000FlowRuleProgrammable with {} rules.", rules.size());
+ // FIXME: Change this so it's dynamically driven
+ UniSideInterfaceAssignmentEnum portAssignment = UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST;
+
+ List<SourceAddressRange> saRangeList = new ArrayList<SourceAddressRange>();
+ Map<Integer, Evc> evcMap = new HashMap<>();
+
+ //Retrieve the list of actual EVCs and the CeVlanMaps from device
+ List<Evc> activeEvcs = new ArrayList<>();
+ try {
+ sessionMutex.acquire();
+ MseaUniEvcService evcResponse =
+ mseaUniEvcServiceSvc.getmseaUniEvcCeVlanMaps(session, DatastoreId.RUNNING);
+ //There could be zero or more EVCs
+ if (evcResponse != null && evcResponse.mefServices() != null && evcResponse.mefServices().uni() != null) {
+ activeEvcs.addAll(evcResponse.mefServices().uni().evc());
+ }
+ } catch (NetconfException | InterruptedException e1) {
+ log.warn("Unexpected error on applyFlowRules", e1);
+ }
+
+ for (FlowRule fr : rules) {
+
+ // IP SA Filtering can only apply to Port 0 optics
+ if (fr.selector().getCriterion(Type.IPV4_SRC) != null &&
+ fr.selector().getCriterion(Type.IN_PORT) != null &&
+ ((PortCriterion) fr.selector().getCriterion(Type.IN_PORT)).port().toLong() == 0) {
+ parseFrForSaRange(frAdded, saRangeList, fr);
+
+ // EVCs will be defined by Flow Rules relating to VIDs
+ } else if (fr.selector().getCriterion(Type.VLAN_VID) != null &&
+ fr.selector().getCriterion(Type.IN_PORT) != null) {
+ //There could be many Flow Rules for one EVC depending on the ceVlanMap
+ //Cannot build up the EVC until we know the details - the key is the tableID and port
+ parseFrForEvcs(frAdded, evcMap, activeEvcs, portAssignment, fr);
+ } else {
+ log.info("Unexpected Flow Rule type applied: " + fr);
+ }
+ }
+
+ //If there are IPv4 Flow Rules created commit them now through the
+ //MseaSaFiltering service
+ if (saRangeList.size() > 0) {
+ try {
+ mseaSaFilteringService.setMseaSaFiltering(
+ buildSaFilteringObject(saRangeList), session, DatastoreId.RUNNING);
+ } catch (NetconfException e) {
+ log.error("Error applying Flow Rules to SA Filtering - will try again: " + e.getMessage());
+ sessionMutex.release();
+ return frAdded;
+ }
+ }
+ //If there are EVC flow rules then populate the MseaUniEvc part of EA1000
+ if (evcMap.size() > 0) {
+ List<Evc> evcList = evcMap.entrySet().stream()
+ .map(x -> x.getValue())
+ .collect(Collectors.toList());
+ Uni uni = new DefaultUni();
+ URI deviceName = handler().data().deviceId().uri();
+ uni.name(new Identifier45("Uni-on-"
+ + deviceName.getSchemeSpecificPart()));
+ uni.evc(evcList);
+
+ List<BwpGroup> bwpGroupList = new ArrayList<BwpGroup>();
+ BwpGroup bwpGrp = new DefaultBwpGroup();
+ bwpGrp.groupIndex((short) 0);
+ bwpGroupList.add(bwpGrp);
+ Profiles profiles = new DefaultProfiles();
+ profiles.bwpGroup(bwpGroupList);
+
+ MefServices mefServices = new DefaultMefServices();
+ mefServices.uni(uni);
+ mefServices.profiles(profiles);
+
+ MseaUniEvcServiceOpParam mseaUniEvcServiceFilter = new MseaUniEvcServiceOpParam();
+ mseaUniEvcServiceFilter.mefServices(mefServices);
+ try {
+ mseaUniEvcServiceSvc.setMseaUniEvcService(mseaUniEvcServiceFilter, session, DatastoreId.RUNNING);
+ } catch (NetconfException e) {
+ log.error("Error applying Flow Rules to EVC - will try again: " + e.getMessage());
+ sessionMutex.release();
+ return frAdded;
+ }
+ }
+ sessionMutex.release();
+ return frAdded;
+ }
+
+ /**
+ * Remove flow rules from the EA1000.
+ * Since the EA1000 does not have any 'real' flow entries these are converted 2 configuration
+ * areas on the EA1000 NETCONF model - to SA filtering YANG model and to EVC UNI YANG model.
+ *
+ * @param rulesToRemove A collection of Flow Rules to be removed to the EA1000
+ * @return A collection of the Flow Rules that have been removed.
+ */
+ @Override
+ public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rulesToRemove) {
+ NetconfController controller = checkNotNull(handler().get(NetconfController.class));
+ NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession();
+ MseaSaFilteringNetconfService mseaSaFilteringService =
+ (MseaSaFilteringNetconfService) checkNotNull(handler().get(MseaSaFilteringNetconfService.class));
+ MseaUniEvcServiceNetconfService mseaUniEvcServiceSvc =
+ (MseaUniEvcServiceNetconfService) checkNotNull(handler().get(MseaUniEvcServiceNetconfService.class));
+ UniSideInterfaceAssignmentEnum portAssignment = UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST;
+ log.debug("removeFlowRules() called on EA1000FlowRuleProgrammable with {} rules.", rulesToRemove.size());
+
+ if (rulesToRemove.size() == 0) {
+ return rulesToRemove;
+ }
+
+ //Retrieve the list of actual EVCs and the CeVlanMaps from device
+ List<Evc> activeEvcs = new ArrayList<>();
+ List<Short> acvtiveFiltRanges = new ArrayList<>();
+ try {
+ sessionMutex.acquire();
+ MseaUniEvcService evcResponse =
+ mseaUniEvcServiceSvc.getmseaUniEvcCeVlanMaps(session, DatastoreId.RUNNING);
+ //There could be zero or more EVCs
+ if (evcResponse != null && evcResponse.mefServices() != null && evcResponse.mefServices().uni() != null) {
+ activeEvcs.addAll(evcResponse.mefServices().uni().evc());
+ }
+ mseaSaFilteringService.getConfigMseaSaFilterIds(session).forEach(
+ r -> acvtiveFiltRanges.add(r.rangeId()));
+
+ } catch (NetconfException | InterruptedException e1) {
+ log.warn("Error on removeFlowRules.", e1);
+ }
+
+ List<SourceAddressRange> saRangeList = new ArrayList<SourceAddressRange>();
+ Map<Integer, String> ceVlanMapMap = new HashMap<>();
+ Map<Integer, List<Short>> flowIdMap = new HashMap<>();
+
+ Collection<FlowRule> rulesRemoved = new HashSet<FlowRule>();
+ for (FlowRule ruleToRemove : rulesToRemove) {
+ // IP SA Filtering can only apply to Port 0 optics
+ if (ruleToRemove.selector().getCriterion(Type.IPV4_SRC) != null &&
+ ruleToRemove.selector().getCriterion(Type.IN_PORT) != null &&
+ ((PortCriterion) ruleToRemove.selector().getCriterion(Type.IN_PORT)).port().toLong() == 0) {
+ SourceAddressRange sar = new DefaultSourceAddressRange();
+ sar.rangeId((short) ruleToRemove.tableId());
+ acvtiveFiltRanges.remove(Short.valueOf((short) ruleToRemove.tableId()));
+ rulesRemoved.add(ruleToRemove);
+ saRangeList.add(sar);
+
+ } else if (ruleToRemove.selector().getCriterion(Type.VLAN_VID) != null &&
+ ruleToRemove.selector().getCriterion(Type.IN_PORT) != null) {
+ PortNumber portNumber = ((PortCriterion) ruleToRemove.selector().getCriterion(Type.IN_PORT)).port();
+ VlanId vlanId = ((VlanIdCriterion) ruleToRemove.selector().getCriterion(Type.VLAN_VID)).vlanId();
+ int evcId = ruleToRemove.tableId();
+ int evcKey = (evcId << 2) + (int) portNumber.toLong();
+ String activeCeVlanMap = "";
+ //If this is one of many VLANs belonging to an EVC then we should only remove this VLAN
+ // from the ceVlanMap and not the whole EVC
+ if (!ceVlanMapMap.containsKey(evcKey)) {
+ for (Evc activeEvc:activeEvcs) {
+ if (activeEvc.evcIndex() == evcId) {
+ if (Ea1000Port.fromNum(portNumber.toLong()).nOrC(portAssignment) ==
+ UniSide.CUSTOMER) {
+ activeCeVlanMap = activeEvc.evcPerUni().evcPerUnic().ceVlanMap().string();
+ } else if (Ea1000Port.fromNum(portNumber.toLong()).nOrC(portAssignment) ==
+ UniSide.NETWORK) {
+ activeCeVlanMap = activeEvc.evcPerUni().evcPerUnin().ceVlanMap().string();
+ }
+ }
+ }
+ }
+
+ ceVlanMapMap.put(evcKey, CeVlanMapUtils.removeFromCeVlanMap(activeCeVlanMap, vlanId.id()));
+ if (!flowIdMap.containsKey(evcKey)) {
+ flowIdMap.put(evcKey, new ArrayList<>());
+ }
+ flowIdMap.get(evcKey).add(vlanId.id());
+ rulesRemoved.add(ruleToRemove);
+
+ } else {
+ log.info("Unexpected Flow Rule type removal: " + ruleToRemove);
+ }
+ }
+
+ //If there are IPv4 Flow Rules created commit them now through the
+ //MseaSaFiltering service
+ if (saRangeList.size() > 0 && acvtiveFiltRanges.size() == 0) {
+ try {
+ SourceIpaddressFiltering saFilter =
+ new DefaultSourceIpaddressFiltering();
+ MseaSaFilteringOpParam mseaSaFiltering = new MseaSaFilteringOpParam();
+ mseaSaFiltering.sourceIpaddressFiltering(saFilter);
+
+ mseaSaFilteringService.deleteMseaSaFilteringRange(
+ mseaSaFiltering, session, DatastoreId.RUNNING);
+ } catch (NetconfException e) {
+ log.warn("Remove FlowRule on MseaSaFilteringService could not delete all SARules - "
+ + "they may already have been deleted: " + e.getMessage());
+ }
+ } else if (saRangeList.size() > 0) {
+ try {
+ mseaSaFilteringService.deleteMseaSaFilteringRange(
+ buildSaFilteringObject(saRangeList), session, DatastoreId.RUNNING);
+ } catch (NetconfException e) {
+ log.warn("Remove FlowRule on MseaSaFilteringService could not delete SARule - "
+ + "it may already have been deleted: " + e.getMessage());
+ }
+ }
+
+ if (ceVlanMapMap.size() > 0) {
+ try {
+ mseaUniEvcServiceSvc.removeEvcUniFlowEntries(ceVlanMapMap, flowIdMap,
+ session, DatastoreId.RUNNING, portAssignment);
+ } catch (NetconfException e) {
+ log.warn("Remove FlowRule on MseaUniEvcService could not delete EVC - "
+ + "it may already have been deleted: " + e.getMessage());
+ }
+ }
+
+ sessionMutex.release();
+ return rulesRemoved;
+ }
+
+ /**
+ * An internal method for extracting one EVC from a list and returning its ceVlanMap.
+ *
+ * @param evcList - the list of known EVCs
+ * @param evcIndex - the index of the EVC we're looking for
+ * @param side - the side of the UNI
+ * @return - the CEVlanMap we're looking for
+ */
+ private String getCeVlanMapForIdxFromEvcList(List<Evc> evcList, long evcIndex, UniSide side) {
+ if (evcList != null && evcList.size() > 0) {
+ for (Evc evc:evcList) {
+ if (evc.evcIndex() == evcIndex && evc.evcPerUni() != null) {
+ if (side == UniSide.CUSTOMER &&
+ evc.evcPerUni().evcPerUnic() != null &&
+ evc.evcPerUni().evcPerUnic().ceVlanMap() != null) {
+ return evc.evcPerUni().evcPerUnic().ceVlanMap().string();
+ } else if (side == UniSide.NETWORK &&
+ evc.evcPerUni().evcPerUnin() != null &&
+ evc.evcPerUni().evcPerUnin().ceVlanMap() != null) {
+ return evc.evcPerUni().evcPerUnin().ceVlanMap().string();
+ }
+ }
+ }
+ }
+
+ return ""; //The EVC required was not in the list
+ }
+
+ /**
+ * An internal method to convert from a FlowRule to SARange.
+ *
+ * @param frList A collection of flow rules
+ * @param saRangeList A list of SARanges
+ * @param fr A flow rule
+ */
+ private void parseFrForSaRange(Collection<FlowRule> frList, List<SourceAddressRange> saRangeList, FlowRule fr) {
+ String ipAddrStr = fr.selector().getCriterion(Type.IPV4_SRC).toString().substring(9);
+ log.debug("Applying IP address to " + ipAddrStr
+ + " (on Port 0) to IP SA Filtering on EA1000 through NETCONF");
+
+ SourceAddressRange sar =
+ new DefaultSourceAddressRange();
+
+ sar.rangeId((short) fr.tableId());
+ sar.name("Flow:" + fr.id().toString());
+ sar.ipv4AddressPrefix(ipAddrStr);
+
+ frList.add(fr);
+ saRangeList.add(sar);
+ }
+
+ private void parseFrForEvcs(Collection<FlowRule> frList, Map<Integer, Evc> evcMap,
+ List<Evc> activeEvcs, UniSideInterfaceAssignmentEnum portAssignment, FlowRule fr) {
+ //There could be many Flow Rules for one EVC depending on the ceVlanMap
+ //Cannot build up the EVC until we know the details - the key is the tableID and port
+ Ea1000Port port = Ea1000Port.fromNum(
+ ((PortCriterion) fr.selector().getCriterion(Type.IN_PORT)).port().toLong());
+ Integer evcKey = (fr.tableId() << 2) + port.portNum();
+ VlanId sourceVid = ((VlanIdCriterion) fr.selector().getCriterion(Type.VLAN_VID)).vlanId();
+ FlowMapping fm = new DefaultFlowMapping();
+ fm.ceVlanId(VlanIdType.of(sourceVid.id()));
+ fm.flowId(BigInteger.valueOf(fr.id().value()));
+
+ if (evcMap.containsKey(evcKey)) { //Is there an entry already for this EVC and port?
+ //Replace ceVlanMap
+ if (port.nOrC(portAssignment) == UniSide.CUSTOMER) {
+ evcMap.get(evcKey).evcPerUni().evcPerUnic().addToFlowMapping(fm);
+ ServiceListType newCeVlanMap = new ServiceListType(
+ CeVlanMapUtils.addtoCeVlanMap(
+ evcMap.get(evcKey).evcPerUni().evcPerUnic().ceVlanMap().toString(),
+ sourceVid.toShort()));
+ evcMap.get(evcKey).evcPerUni().evcPerUnic().ceVlanMap(newCeVlanMap);
+ } else {
+ evcMap.get(evcKey).evcPerUni().evcPerUnin().addToFlowMapping(fm);
+ ServiceListType newCeVlanMap = new ServiceListType(
+ CeVlanMapUtils.addtoCeVlanMap(
+ evcMap.get(evcKey).evcPerUni().evcPerUnin().ceVlanMap().toString(),
+ sourceVid.toShort()));
+ evcMap.get(evcKey).evcPerUni().evcPerUnin().ceVlanMap(newCeVlanMap);
+ }
+ } else if (evcMap.containsKey((evcKey ^ 1))) { //Is there an entry for this EVC but the opposite port?
+ TagManipulation tm = getTagManipulation(fr);
+ if (port.nOrC(portAssignment) == UniSide.NETWORK) {
+ ServiceListType newCeVlanMap = new ServiceListType(
+ CeVlanMapUtils.addtoCeVlanMap(
+ evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnin().ceVlanMap().toString(),
+ sourceVid.toShort()));
+ evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnin().ceVlanMap(newCeVlanMap);
+ evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnin().tagManipulation(tm);
+ evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnin().addToFlowMapping(fm);
+ evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnin().ingressBwpGroupIndex(getMeterId(fr.treatment()));
+ } else {
+ ServiceListType newCeVlanMap = new ServiceListType(
+ CeVlanMapUtils.addtoCeVlanMap(
+ evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnic().ceVlanMap().toString(),
+ sourceVid.toShort()));
+ evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnic().ceVlanMap(newCeVlanMap);
+ evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnic().tagManipulation(tm);
+ evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnic().addToFlowMapping(fm);
+ evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnic().ingressBwpGroupIndex(getMeterId(fr.treatment()));
+ }
+ } else {
+ Evc evc = new DefaultEvc();
+ EvcPerUnin epun = new CustomEvcPerUnin();
+ EvcPerUnic epuc = new CustomEvcPerUnic();
+ TagManipulation tm = getTagManipulation(fr);
+
+ UniSide side = port.nOrC(portAssignment);
+ String oldCeVlanMap = getCeVlanMapForIdxFromEvcList(activeEvcs, fr.tableId(), side);
+ String newCeVlanMap =
+ CeVlanMapUtils.addtoCeVlanMap(oldCeVlanMap, sourceVid.id());
+ String oppositeCeVlanMap =
+ getCeVlanMapForIdxFromEvcList(activeEvcs, fr.tableId(),
+ port.opposite().nOrC(portAssignment));
+ oppositeCeVlanMap = oppositeCeVlanMap.isEmpty() ? "0" : oppositeCeVlanMap;
+ if (side == UniSide.NETWORK) {
+ epun.ceVlanMap(new ServiceListType(newCeVlanMap));
+ epun.tagManipulation(tm);
+ epun.addToFlowMapping(fm);
+ epun.ingressBwpGroupIndex(getMeterId(fr.treatment()));
+
+ epuc.ceVlanMap(new ServiceListType(oppositeCeVlanMap));
+ epuc.ingressBwpGroupIndex(new Long(0));
+ } else {
+ epuc.ceVlanMap(new ServiceListType(newCeVlanMap));
+ epuc.tagManipulation(tm);
+ epuc.addToFlowMapping(fm);
+ epuc.ingressBwpGroupIndex(getMeterId(fr.treatment()));
+
+ epun.ceVlanMap(new ServiceListType(oppositeCeVlanMap));
+ epun.ingressBwpGroupIndex(new Long(0));
+ }
+
+ evc.evcIndex(fr.tableId());
+ evc.name(new Identifier45("EVC-" + String.valueOf(fr.tableId())));
+
+ DefaultEvcPerUni epu = new DefaultEvcPerUni();
+ epu.evcPerUnin(epun);
+ epu.evcPerUnic(epuc);
+ evc.evcPerUni(epu);
+
+ evcMap.put(evcKey, evc);
+ }
+
+ frList.add(fr);
+ }
+
+
+ private MseaSaFilteringOpParam buildSaFilteringObject(List<SourceAddressRange> saRangeList) {
+ InterfaceEth0 saIf = new DefaultInterfaceEth0();
+ for (SourceAddressRange sa:saRangeList) {
+ saIf.addToSourceAddressRange(sa);
+ }
+ saIf.filterAdminState(FilterAdminStateEnum.BLACKLIST);
+
+ SourceIpaddressFiltering saFilter =
+ new DefaultSourceIpaddressFiltering();
+ saFilter.interfaceEth0(saIf);
+
+ MseaSaFilteringOpParam mseaSaFiltering = new MseaSaFilteringOpParam();
+ mseaSaFiltering.sourceIpaddressFiltering(saFilter);
+
+ return mseaSaFiltering;
+ }
+
+ private Collection<FlowEntry> convertSaFilteringToFlowRules(
+ MseaSaFiltering saFilteringCurrent, ApplicationId appId) {
+ Collection<FlowEntry> flowEntryCollection = new HashSet<FlowEntry>();
+
+ List<SourceAddressRange> saRangelist =
+ saFilteringCurrent.sourceIpaddressFiltering().interfaceEth0().sourceAddressRange();
+ Criterion matchInPort = Criteria.matchInPort(PortNumber.portNumber(0));
+ TrafficSelector.Builder tsBuilder = DefaultTrafficSelector.builder();
+
+ if (saRangelist != null) {
+ for (SourceAddressRange sa : saRangelist) {
+ Criterion matchIpSrc = Criteria.matchIPSrc(IpPrefix.valueOf(sa.ipv4AddressPrefix()));
+
+ TrafficSelector selector = tsBuilder.add(matchIpSrc).add(matchInPort).build();
+
+ TrafficTreatment.Builder trBuilder = DefaultTrafficTreatment.builder();
+ TrafficTreatment treatment = trBuilder.drop().build();
+
+ FlowRule.Builder feBuilder = new DefaultFlowRule.Builder();
+ if (sa.name() != null && sa.name().startsWith("Flow:")) {
+ String[] nameParts = sa.name().split(":");
+ Long cookie = Long.valueOf(nameParts[1], 16);
+ feBuilder = feBuilder.withCookie(cookie);
+ } else {
+ feBuilder = feBuilder.fromApp(appId);
+ }
+
+ FlowRule fr = feBuilder
+ .forDevice(handler().data().deviceId())
+ .withSelector(selector)
+ .withTreatment(treatment)
+ .forTable(sa.rangeId())
+ .makePermanent()
+ .withPriority(PRIORITY_DEFAULT)
+ .build();
+
+ flowEntryCollection.add(
+ new DefaultFlowEntry(fr, FlowEntryState.ADDED, 0, 0, 0));
+ }
+ }
+ return flowEntryCollection;
+ }
+
+
+ private Collection<FlowEntry> convertEvcUniToFlowRules(
+ MseaUniEvcService uniEvcCurrent, UniSideInterfaceAssignmentEnum portAssignment) {
+ Collection<FlowEntry> flowEntryCollection = new HashSet<FlowEntry>();
+
+ if (uniEvcCurrent == null || uniEvcCurrent.mefServices() == null ||
+ uniEvcCurrent.mefServices().uni() == null || uniEvcCurrent.mefServices().uni().evc() == null) {
+ log.info("No EVC's found when getting flow rules");
+ return flowEntryCollection;
+ }
+
+ for (Evc evc:uniEvcCurrent.mefServices().uni().evc()) {
+ FlowRule.Builder frBuilder = new DefaultFlowRule.Builder();
+ TrafficSelector.Builder tsBuilder = DefaultTrafficSelector.builder();
+
+ TrafficTreatment uniNTreatment = treatmentForUniSde(evc.evcPerUni(), true);
+ //Depending on the ceVlanMap there may be multiple VLans and hence multiple flow entries
+ Short[] vlanIdsUniN =
+ CeVlanMapUtils.getVlanSet(ceVlanMapForUniSide(evc.evcPerUni(), true));
+ for (Short vlanId:vlanIdsUniN) {
+ if (vlanId == 0) {
+ continue;
+ }
+ Criterion uniNportCriterion = criterionPortForUniSide(portAssignment, true);
+ TrafficSelector tsUniN = tsBuilder.matchVlanId(VlanId.vlanId(vlanId)).add(uniNportCriterion).build();
+ long flowId = getFlowIdForVlan(evc.evcPerUni().evcPerUnin().flowMapping(), vlanId);
+
+ FlowRule frUniN = frBuilder
+ .forDevice(handler().data().deviceId())
+ .withSelector(tsUniN)
+ .withTreatment(uniNTreatment)
+ .forTable(new Long(evc.evcIndex()).intValue()) //narrowing to int
+ .makePermanent()
+ .withPriority(PRIORITY_DEFAULT)
+ .withCookie(flowId)
+ .build();
+ flowEntryCollection.add(new DefaultFlowEntry(frUniN, FlowEntryState.ADDED, 0, 0, 0));
+ }
+
+ TrafficTreatment uniCTreatment = treatmentForUniSde(evc.evcPerUni(), false);
+ //Depending on the ceVlanMap there may be multiple VLans and hence multiple flow entries
+ Short[] vlanIdsUniC =
+ CeVlanMapUtils.getVlanSet(ceVlanMapForUniSide(evc.evcPerUni(), false));
+ if (vlanIdsUniC != null && vlanIdsUniC.length > 0) {
+ for (Short vlanId:vlanIdsUniC) {
+ if (vlanId == 0) {
+ continue;
+ }
+ Criterion uniCportCriterion = criterionPortForUniSide(portAssignment, false);
+ TrafficSelector tsUniC =
+ tsBuilder.matchVlanId(VlanId.vlanId(vlanId)).add(uniCportCriterion).build();
+ long flowId = getFlowIdForVlan(evc.evcPerUni().evcPerUnic().flowMapping(), vlanId);
+
+ FlowRule frUniC = frBuilder
+ .forDevice(handler().data().deviceId())
+ .withSelector(tsUniC)
+ .withTreatment(uniCTreatment)
+ .forTable(new Long(evc.evcIndex()).intValue()) //narrowing to int
+ .makePermanent()
+ .withPriority(PRIORITY_DEFAULT)
+ .withCookie(flowId)
+ .build();
+ flowEntryCollection.add(new DefaultFlowEntry(frUniC, FlowEntryState.ADDED, 0, 0, 0));
+ }
+ }
+ }
+
+ return flowEntryCollection;
+ }
+
+ private long getFlowIdForVlan(List<FlowMapping> fmList, Short vlanId) {
+ if (fmList == null || vlanId == null) {
+ log.warn("Flow Mapping list is null when reading EVCs");
+ return -1L;
+ }
+ for (FlowMapping fm:fmList) {
+ if (fm.ceVlanId().uint16() == vlanId.intValue()) {
+ return fm.flowId().longValue();
+ }
+ }
+ return 0L;
+ }
+
+ private String ceVlanMapForUniSide(
+ EvcPerUni evcPerUni, boolean portN) {
+ if (portN) {
+ return evcPerUni.evcPerUnin().ceVlanMap().string();
+ } else {
+ return evcPerUni.evcPerUnic().ceVlanMap().string();
+ }
+ }
+
+ private Criterion criterionPortForUniSide(
+ UniSideInterfaceAssignmentEnum portAssignment, boolean portN) {
+ boolean cOnOptics = (portAssignment == UniSideInterfaceAssignmentEnum.UNI_C_ON_OPTICS);
+ int portNum = ((cOnOptics && portN) || (!cOnOptics && !portN)) ? 1 : 0;
+ return Criteria.matchInPort(PortNumber.portNumber(portNum));
+ }
+
+ private TrafficTreatment treatmentForUniSde(
+ EvcPerUni evcPerUni, boolean portN) {
+ TrafficTreatment.Builder trBuilder = DefaultTrafficTreatment.builder();
+
+ TagManipulation tm = null;
+ short meterId = 0;
+ if (portN) {
+ tm = evcPerUni.evcPerUnin().tagManipulation();
+ meterId = (short) evcPerUni.evcPerUnin().ingressBwpGroupIndex();
+ } else {
+ tm = evcPerUni.evcPerUnic().tagManipulation();
+ meterId = (short) evcPerUni.evcPerUnic().ingressBwpGroupIndex();
+ }
+
+ if (meterId > 0L) {
+ trBuilder = trBuilder.meter(MeterId.meterId((long) meterId));
+// trBuilder = trBuilder.meter(MeterId.meterId(meterId)).transition(0);
+ }
+
+ if (tm == null) {
+ return trBuilder.build(); //no tag manipulation found
+ }
+
+ if (tm.getClass().equals(DefaultTagPush.class)) {
+ VlanId pushVlanNum = VlanId.vlanId((short) ((TagPush) tm).tagPush().outerTagVlan().uint16());
+ PushTagTypeEnum pushTagType = ((TagPush) tm).tagPush().pushTagType();
+ //Note - the order of elements below MUST match the order of the Treatment in the stored FlowRule
+ // to be an exactMatch. See DefaultFlowRule.exactMatch()
+ trBuilder = trBuilder
+ .pushVlan(pushTagType.equals(PushTagTypeEnum.PUSHCTAG) ?
+ EtherType.VLAN.ethType() : EtherType.QINQ.ethType())
+ .setVlanId(pushVlanNum).transition(Integer.valueOf(0));
+
+ } else if (tm.getClass().equals(DefaultTagPop.class)) {
+ trBuilder = trBuilder.popVlan();
+
+ } else if (tm.getClass().equals(DefaultTagOverwrite.class)) {
+ TagOverwrite to = (TagOverwrite) tm;
+ VlanId ovrVlanNum = VlanId
+ .vlanId((short) (
+ //There are 2 classes TagOverwrite - the other one is already imported
+ to
+ .tagOverwrite()
+ .outerTagVlan()
+ .uint16()));
+ trBuilder = trBuilder.setVlanId(ovrVlanNum);
+
+ }
+
+ return trBuilder.build();
+ }
+
+ private static TagManipulation getTagManipulation(FlowRule fr) {
+ boolean isPop = false;
+ boolean isPush = false;
+ VlanId vlanId = null;
+ EthType ethType = EtherType.VLAN.ethType(); //Default
+ for (Instruction inst:fr.treatment().allInstructions()) {
+ if (inst.type() == Instruction.Type.L2MODIFICATION) {
+ L2ModificationInstruction l2Mod = (L2ModificationInstruction) inst;
+ if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_POP) {
+ isPop = true;
+ } else if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+ isPush = true;
+ ethType = ((ModVlanHeaderInstruction) l2Mod).ethernetType();
+ } else if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
+ vlanId = ((ModVlanIdInstruction) l2Mod).vlanId();
+ }
+ }
+ }
+
+ if (isPop) {
+ //The should be no vlanId in this case
+ TagPop pop = new DefaultTagPop();
+ org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice
+ .evcperuniextensionattributes.tagmanipulation
+ .tagpop.TagPop popInner =
+ new org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317
+ .mseaunievcservice.evcperuniextensionattributes
+ .tagmanipulation.tagpop.DefaultTagPop();
+ pop.tagPop(popInner);
+ return pop;
+
+ } else if (isPush && vlanId != null) {
+ TagPush push = new DefaultTagPush();
+ org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice
+ .evcperuniextensionattributes.tagmanipulation
+ .tagpush.TagPush pushInner =
+ new org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317
+ .mseaunievcservice.evcperuniextensionattributes
+ .tagmanipulation.tagpush.DefaultTagPush();
+ pushInner.outerTagVlan(new VlanIdType(vlanId.id()));
+ pushInner.pushTagType(ethType.equals(EtherType.VLAN.ethType()) ?
+ PushTagTypeEnum.PUSHCTAG : PushTagTypeEnum.PUSHSTAG);
+ push.tagPush(pushInner);
+ return push;
+
+ } else if (vlanId != null) { //This is overwrite, as it has vlanId, but not push or pop
+ TagOverwrite ovr = new DefaultTagOverwrite();
+ org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice
+ .evcperuniextensionattributes.tagmanipulation
+ .tagoverwrite.TagOverwrite ovrInner =
+ new org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317
+ .mseaunievcservice.evcperuniextensionattributes
+ .tagmanipulation.tagoverwrite.DefaultTagOverwrite();
+ ovrInner.outerTagVlan(new VlanIdType(vlanId.id()));
+ ovr.tagOverwrite(ovrInner);
+ return ovr;
+ }
+
+ return null;
+ }
+
+ private static long getMeterId(TrafficTreatment treatment) {
+ return (treatment.metered() != null && treatment.metered().meterId() != null)
+ ? treatment.metered().meterId().id() : 0L;
+ }
+
+ /**
+ * An enumerated type that characterises the 2 port layout of the EA1000 device.
+ * The device is in an SFP package and has only 2 ports, the HOST port which
+ * plugs in to the chassis (Port 1) and the Optics Port on the rear (Port 0).
+ */
+ public enum Ea1000Port {
+ HOST(1),
+ OPTICS(0);
+
+ private int num = 0;
+ private Ea1000Port(int num) {
+ this.num = num;
+ }
+
+ /**
+ * The numerical assignment of this port.
+ * @return The port number
+ */
+ public int portNum() {
+ return num;
+ }
+
+ /**
+ * Return the enumerated value from a port number.
+ * @param num The port number
+ * @return An enumerated value
+ */
+ public static Ea1000Port fromNum(long num) {
+ for (Ea1000Port a:Ea1000Port.values()) {
+ if (a.num == num) {
+ return a;
+ }
+ }
+ return HOST;
+ }
+
+ /**
+ * Get the port that the UNI-N is present on.
+ * @param side The assignment of UNI-side to port
+ * @return An enumerated value
+ */
+ public static Ea1000Port uniNNum(UniSideInterfaceAssignmentEnum side) {
+ if (side.equals(UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST)) {
+ return OPTICS;
+ } else {
+ return HOST;
+ }
+ }
+
+ /**
+ * Get the port that the UNI-C is present on.
+ * @param side The assignment of UNI-side to port
+ * @return An enumerated value
+ */
+ public static Ea1000Port uniCNum(UniSideInterfaceAssignmentEnum side) {
+ if (side.equals(UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST)) {
+ return HOST;
+ } else {
+ return OPTICS;
+ }
+ }
+
+ /**
+ * Get the port opposite the current port.
+ * @return An enumerated value for the opposite side
+ */
+ public Ea1000Port opposite() {
+ if (this.equals(HOST)) {
+ return OPTICS;
+ } else {
+ return HOST;
+ }
+ }
+
+ /**
+ * Evaluate which side of the UNI on the EA1000 device this port refers to.
+ * @param side The assignment of UNI-side to port
+ * @return An enumerated value representing the UniSide
+ */
+ public UniSide nOrC(UniSideInterfaceAssignmentEnum side) {
+ if ((this == HOST && side == UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST) ||
+ (this == OPTICS && side == UniSideInterfaceAssignmentEnum.UNI_C_ON_OPTICS)) {
+ return UniSide.CUSTOMER;
+ } else {
+ return UniSide.NETWORK;
+ }
+ }
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000MeterProvider.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000MeterProvider.java
new file mode 100644
index 0000000..226ad2f
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000MeterProvider.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.microsemi;
+
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.core.CoreService;
+import org.onosproject.drivers.microsemi.yang.MseaUniEvcServiceNetconfService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.Meter.Unit;
+import org.onosproject.net.meter.MeterOperation;
+import org.onosproject.net.meter.MeterOperations;
+import org.onosproject.net.meter.MeterProvider;
+import org.onosproject.net.meter.MeterProviderRegistry;
+import org.onosproject.net.meter.MeterProviderService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.CosColorType;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.PriorityType;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.coscolortype.CosColorTypeEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcServiceOpParam;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.DefaultMefServices;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.MefServices;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.DefaultProfiles;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.Profiles;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.BwpGroup;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.Cos;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.DefaultBwpGroup;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.DefaultCos;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.bwpgroup.Bwp;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.bwpgroup.DefaultBwp;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.cos.costypechoice.DefaultEvcCosTypeEvcColorId;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.cos.costypechoice.EvcCosTypeEvcColorId;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.cos.costypechoice.evccostypeevccolorid.DefaultEvcCosTypeAll8PrioTo1EvcColor;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.cos.costypechoice.evccostypeevccolorid.EvcCosTypeAll8PrioTo1EvcColor;
+import org.slf4j.Logger;
+
+/**
+ * Provider which uses an NETCONF controller to handle meters.
+ *
+ * TODO: move this to an architecture similar to FlowRuleDriverProvider in order
+ * to use a behavior to discover meters.
+ */
+@Component(immediate = true, enabled = true)
+public class EA1000MeterProvider extends AbstractProvider implements MeterProvider {
+
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetconfController controller;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MeterProviderRegistry providerRegistry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MseaUniEvcServiceNetconfService mseaUniEvcServiceSvc;
+
+ private MeterProviderService providerService;
+
+ private static final int COS_INDEX_1 = 1;
+ private static final short DEFAULT_OUTGOING_PRIO = 3;
+
+ /**
+ * Creates a OpenFlow meter provider.
+ */
+ public EA1000MeterProvider() {
+ super(new ProviderId("netconf", "org.onosproject.provider.meter.microsemi"));
+ }
+
+ @Activate
+ public void activate() {
+ providerService = providerRegistry.register(this);
+
+ }
+
+ @Deactivate
+ public void deactivate() {
+ providerRegistry.unregister(this);
+
+ providerService = null;
+ }
+
+ @Override
+ public void performMeterOperation(DeviceId deviceId, MeterOperations meterOps) {
+ log.debug("Adding meterOps to Microsemi Meter Store");
+ }
+
+ @Override
+ public void performMeterOperation(DeviceId deviceId, MeterOperation meterOp) {
+ if (meterOp == null || deviceId == null) {
+ log.warn("Missing argument for performMeterOperation()");
+ return;
+ }
+ log.debug("{} meterOp {} to Microsemi Meter Store", meterOp.type(), meterOp);
+
+ long meterId = meterOp.meter().id().id();
+ String deviceName = deviceId.uri().getSchemeSpecificPart();
+ Unit unit = meterOp.meter().unit();
+
+ Profiles profiles = new DefaultProfiles();
+ if (meterOp.type() == MeterOperation.Type.ADD || meterOp.type() == MeterOperation.Type.MODIFY) {
+ Bwp bwp = new DefaultBwp();
+ bwp.cosIndex(COS_INDEX_1);
+ bwp.name("BWP-" + String.valueOf(meterId) + "-" + deviceName);
+
+ long cirRateKbps = 0L;
+ long cbsRateKbps = 0L;
+ long eirRateKbps = 0L;
+ long ebsRateKbps = 0L;
+ for (Band band:meterOp.meter().bands()) {
+ if (band.type() == Band.Type.REMARK) {
+ //This relates to CIR/CBS
+ cirRateKbps = toBitsPerSec(band.rate(), unit);
+ cbsRateKbps = band.burst(); //Already in kbps
+ } else if (band.type() == Band.Type.DROP) {
+ //This relates to EIR/EBS
+ eirRateKbps = toBitsPerSec(band.rate(), unit);
+ ebsRateKbps = band.burst(); //Already in kbps
+ }
+ }
+ bwp.committedInformationRate(cirRateKbps);
+ bwp.excessInformationRate(eirRateKbps - cirRateKbps);
+ if (meterOp.meter().isBurst()) {
+ bwp.committedBurstSize(cbsRateKbps);
+ bwp.excessBurstSize(ebsRateKbps - cbsRateKbps);
+ }
+
+ BwpGroup bwpg = new DefaultBwpGroup();
+ bwpg.groupIndex((short) meterId);
+ bwpg.addToBwp(bwp);
+
+ //Create cos-1 as referenced above - we only support 1 at the moment
+ Cos cos = new DefaultCos();
+ cos.cosIndex(COS_INDEX_1);
+ cos.name("COS-1");
+ cos.outgoingCosValue(PriorityType.of(DEFAULT_OUTGOING_PRIO));
+ cos.colorAware(true);
+ cos.colorForward(true);
+
+ EvcCosTypeAll8PrioTo1EvcColor ect =
+ new DefaultEvcCosTypeAll8PrioTo1EvcColor();
+ ect.evcAll8ColorTo(CosColorType.of(CosColorTypeEnum.GREEN));
+ profiles.addToBwpGroup(bwpg);
+
+ EvcCosTypeEvcColorId cid = new DefaultEvcCosTypeEvcColorId();
+ cid.evcCosTypeAll8PrioTo1EvcColor(ect);
+ cos.cosTypeChoice(cid);
+ profiles.addToCos(cos);
+ } else if (meterOp.type() == MeterOperation.Type.REMOVE) {
+ BwpGroup bwpg = new DefaultBwpGroup();
+ bwpg.groupIndex((short) meterId);
+
+ profiles.addToBwpGroup(bwpg);
+ }
+
+ MefServices mefServices = new DefaultMefServices();
+ mefServices.profiles(profiles);
+
+ MseaUniEvcServiceOpParam mseaUniEvcServiceFilter = new MseaUniEvcServiceOpParam();
+ mseaUniEvcServiceFilter.mefServices(mefServices);
+
+ NetconfSession session = controller.getDevicesMap().get(deviceId).getSession();
+ try {
+ if (meterOp.type() == MeterOperation.Type.REMOVE) {
+ mseaUniEvcServiceSvc.deleteMseaUniEvcService(mseaUniEvcServiceFilter,
+ session, DatastoreId.RUNNING);
+ } else {
+ mseaUniEvcServiceSvc.setMseaUniEvcService(mseaUniEvcServiceFilter,
+ session, DatastoreId.RUNNING);
+ }
+ } catch (NetconfException e) {
+ //This can fail if the BWP Group is deleted before the EVC that is dependent on it
+ //The delete of the EVC will be called on a separate thread to that should proceed
+ //within a few seconds after which we should try again
+ AtomicInteger retry = new AtomicInteger(4);
+ if (meterOp.type() == MeterOperation.Type.REMOVE &&
+ e.getMessage().startsWith("Failed to run edit-config through NETCONF")) {
+ while (retry.getAndDecrement() > 0) {
+ try {
+ Thread.sleep(1000L);
+ log.debug("Retrying deletion of Bandwith Profile Group {}",
+ String.valueOf(meterId));
+ mseaUniEvcServiceSvc.setMseaUniEvcService(mseaUniEvcServiceFilter,
+ session, DatastoreId.RUNNING);
+ return; //If it did not throw an exception
+ } catch (InterruptedException e1) {
+ log.debug("Error when deleting BWP profile on EA1000" +
+ " - trying again in 1 sec", e1);
+ } catch (NetconfException e1) {
+ log.debug("NETCONF failed to delete profile - trying again in 1 sec", e1);
+ }
+ }
+ log.error("Error deleting BWPGroup {} from {} after 4 tries: {}",
+ meterId, deviceId, e.getMessage());
+ } else {
+ log.error("Error adding BWPGroup {} from {}: {}",
+ meterId, deviceId, e.getMessage());
+ throw new UnsupportedOperationException(e);
+ }
+ }
+ }
+
+ private static long toBitsPerSec(long rate, Unit unit) {
+ if (unit == Unit.KB_PER_SEC) {
+ return rate * 8;
+ } else {
+ return -1;
+ }
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000Pipeliner.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000Pipeliner.java
new file mode 100644
index 0000000..308bdff
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000Pipeliner.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.drivers.microsemi.EA1000FlowRuleProgrammable.Ea1000Port;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.NextGroup;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.behaviour.PipelinerContext;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.Criterion.Type;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.slf4j.Logger;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.RemovalCause;
+import com.google.common.cache.RemovalNotification;
+
+/**
+ * Support for FlowObjectives in the EA1000.
+ *
+ * Used with the CarrierEthernet App
+ *
+ */
+public class EA1000Pipeliner extends AbstractHandlerBehaviour implements Pipeliner {
+
+ protected final Logger log = getLogger(getClass());
+ protected ServiceDirectory serviceDirectory;
+ protected FlowRuleService flowRuleService;
+ protected DeviceId deviceId;
+ protected Cache<Integer, NextObjective> pendingNext;
+ protected Integer evcIdBase = 1;
+
+ @Override
+ public void init(DeviceId deviceId, PipelinerContext context) {
+ this.serviceDirectory = context.directory();
+ this.deviceId = deviceId;
+
+ flowRuleService = serviceDirectory.get(FlowRuleService.class);
+
+ pendingNext = CacheBuilder.newBuilder()
+ .expireAfterWrite(20, TimeUnit.SECONDS)
+ .removalListener((RemovalNotification<Integer, NextObjective> notification) -> {
+ if (notification.getCause() == RemovalCause.EXPIRED) {
+ notification.getValue().context()
+ .ifPresent(c -> c.onError(notification.getValue(),
+ ObjectiveError.FLOWINSTALLATIONFAILED));
+ }
+ }).build();
+
+ log.debug("Loaded handler behaviour EA1000Pipeliner for " + handler().data().deviceId().uri());
+ }
+
+ @Override
+ public void filter(FilteringObjective filterObjective) {
+ TrafficTreatment.Builder actions;
+ boolean oppositePort = false;
+ int evcId = -1;
+ switch (filterObjective.type()) {
+ case PERMIT:
+ if (filterObjective.meta() == null) {
+ actions = DefaultTrafficTreatment.builder().add(Instructions.popVlan());
+ } else {
+ oppositePort = true; //Experimental - push happens on the opposite port
+ actions = DefaultTrafficTreatment.builder(filterObjective.meta());
+ if (filterObjective.meta().metered() != null) {
+ actions.meter(filterObjective.meta().metered().meterId());
+ }
+ actions.transition(0);
+ boolean isPush = false;
+ int vid = 0;
+ for (Instruction inst:filterObjective.meta().immediate()) {
+ if (inst.type() == Instruction.Type.L2MODIFICATION) {
+ L2ModificationInstruction l2mod = (L2ModificationInstruction) inst;
+ if (l2mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+ isPush = true;
+ } else if (l2mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
+ vid = ((ModVlanIdInstruction) l2mod).vlanId().id();
+ }
+ }
+ }
+ if (isPush && vid > 0) {
+ evcId = vid;
+ }
+ }
+ break;
+ case DENY:
+ actions = (filterObjective.meta() == null) ?
+ DefaultTrafficTreatment.builder() :
+ DefaultTrafficTreatment.builder(filterObjective.meta());
+ actions.drop();
+ break;
+ default:
+ log.warn("Unknown filter type: {}", filterObjective.type());
+ actions = DefaultTrafficTreatment.builder().drop();
+ }
+
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+ for (Criterion c:filterObjective.conditions()) {
+ if (c.type() == Type.VLAN_VID && evcId == -1) {
+ evcId = ((VlanIdCriterion) c).vlanId().id();
+ }
+ selector.add(c);
+ }
+
+ if (filterObjective.key() != null) {
+ if (oppositePort) {
+ //Experimental
+ Ea1000Port port = Ea1000Port.fromNum(((PortCriterion) filterObjective.key()).port().toLong());
+ selector.matchInPort(PortNumber.portNumber(port.opposite().portNum()));
+ } else {
+ selector.add(filterObjective.key());
+ }
+ }
+
+ FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(selector.build())
+ .withTreatment(actions.build())
+ .fromApp(filterObjective.appId())
+ .forTable(evcId)
+ .withPriority(filterObjective.priority());
+
+ if (filterObjective.permanent()) {
+ ruleBuilder.makePermanent();
+ } else {
+ ruleBuilder.makeTemporary(filterObjective.timeout());
+ }
+
+ installObjective(ruleBuilder, filterObjective);
+
+ log.debug("filter() of EA1000Pipeliner called for "
+ + handler().data().deviceId().uri()
+ + ". Objective: " + filterObjective);
+ }
+
+ @Override
+ public void forward(ForwardingObjective forwardObjective) {
+ TrafficSelector selector = forwardObjective.selector();
+
+ if (forwardObjective.treatment() != null) {
+ List<Instruction> instructions = forwardObjective.treatment().immediate();
+ if (instructions != null && instructions.size() == 1
+ && instructions.get(0).type() == Instruction.Type.OUTPUT
+ && ((OutputInstruction) instructions.get(0)).port() == PortNumber.CONTROLLER) {
+ Set<Criterion> criteria = forwardObjective.selector().criteria();
+ log.info("EA1000 does not yet implement forwarding to CONTROLLER for flow objective for: "
+ + handler().data().deviceId().uri()
+ + ". "
+ + forwardObjective);
+ return;
+ } else {
+ FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(selector)
+ .fromApp(forwardObjective.appId())
+ .withPriority(forwardObjective.priority())
+ .withTreatment(forwardObjective.treatment());
+
+ if (forwardObjective.permanent()) {
+ ruleBuilder.makePermanent();
+ } else {
+ ruleBuilder.makeTemporary(forwardObjective.timeout());
+ }
+ installObjective(ruleBuilder, forwardObjective);
+ }
+ } else {
+ NextObjective nextObjective = pendingNext.getIfPresent(forwardObjective.nextId());
+ if (nextObjective != null) {
+ pendingNext.invalidate(forwardObjective.nextId());
+ nextObjective.next().forEach(treat -> {
+ FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(selector)
+ .fromApp(forwardObjective.appId())
+ .withPriority(forwardObjective.priority())
+ .withTreatment(treat);
+
+ if (forwardObjective.permanent()) {
+ ruleBuilder.makePermanent();
+ } else {
+ ruleBuilder.makeTemporary(forwardObjective.timeout());
+ }
+ installObjective(ruleBuilder, forwardObjective);
+ });
+ } else {
+ forwardObjective.context().ifPresent(c -> c.onError(forwardObjective,
+ ObjectiveError.GROUPMISSING));
+ }
+ }
+ log.debug("EA1000: Unhandled Forwarding Objective for: "
+ + handler().data().deviceId().uri()
+ + ". "
+ + forwardObjective);
+ }
+
+ @Override
+ public void next(NextObjective nextObjective) {
+ pendingNext.put(nextObjective.id(), nextObjective);
+ nextObjective.context().ifPresent(context -> context.onSuccess(nextObjective));
+
+ log.debug("next() of EA1000Pipeliner called for "
+ + handler().data().deviceId().uri()
+ + ". Objective: " + nextObjective);
+ }
+
+ @Override
+ public List<String> getNextMappings(NextGroup nextGroup) {
+ log.debug("getNextMappings() of EA1000Pipeliner called for "
+ + handler().data().deviceId().uri()
+ + ". Objective: " + nextGroup);
+ return new ArrayList<String>();
+ }
+
+ protected void installObjective(FlowRule.Builder ruleBuilder, Objective objective) {
+ FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
+ switch (objective.op()) {
+
+ case ADD:
+ flowBuilder.add(ruleBuilder.build());
+ break;
+ case REMOVE:
+ flowBuilder.remove(ruleBuilder.build());
+ break;
+ default:
+ log.warn("Unknown operation {}", objective.op());
+ }
+
+ flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
+ @Override
+ public void onSuccess(FlowRuleOperations ops) {
+ objective.context().ifPresent(context -> context.onSuccess(objective));
+ }
+
+ @Override
+ public void onError(FlowRuleOperations ops) {
+ objective.context()
+ .ifPresent(context -> context.onError(objective, ObjectiveError.FLOWINSTALLATIONFAILED));
+ }
+ }));
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/Ea1000DeviceDescription.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/Ea1000DeviceDescription.java
new file mode 100644
index 0000000..dfb8480
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/Ea1000DeviceDescription.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onlab.packet.ChassisId;
+import org.onosproject.drivers.microsemi.yang.IetfSystemNetconfService;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DefaultPortDescription;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfDevice;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.system.AugmentedSysSystem;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.system.DefaultAugmentedSysSystem;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.systemstate.platform.AugmentedSysPlatform;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.IetfSystem;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.systemstate.platform.DefaultAugmentedSysPlatform;
+import org.onosproject.yang.gen.v1.ietfyangtypes.rev20130715.ietfyangtypes.DateAndTime;
+import org.slf4j.Logger;
+
+public class Ea1000DeviceDescription extends AbstractHandlerBehaviour implements DeviceDescriptionDiscovery {
+
+ private String serialNumber = "unavailable";
+ private String swVersion = "unavailable";
+ private String longitudeStr = null;
+ private String latitudeStr = null;
+ private final Logger log = getLogger(getClass());
+
+ public Ea1000DeviceDescription() {
+ log.info("Loaded handler behaviour Ea1000DeviceDescription.");
+ }
+
+ @Override
+ public DeviceDescription discoverDeviceDetails() {
+ log.info("Adding description for EA1000 device");
+
+ NetconfController controller = checkNotNull(handler().get(NetconfController.class));
+ NetconfDevice ncDevice = controller.getDevicesMap().get(handler().data().deviceId());
+ if (ncDevice == null) {
+ log.error("Internal ONOS Error. Device has been marked as reachable, " +
+ "but deviceID {} is not in Devices Map. Continuing with empty description",
+ handler().data().deviceId());
+ return null;
+ }
+ NetconfSession session = ncDevice.getSession();
+ IetfSystemNetconfService ietfSystemService =
+ (IetfSystemNetconfService) checkNotNull(handler().get(IetfSystemNetconfService.class));
+
+ try {
+ IetfSystem system = ietfSystemService.getIetfSystemInit(session);
+ if (system != null && system.systemState() != null) {
+ swVersion = system.systemState().platform().osRelease();
+ AugmentedSysPlatform augmentedSysPlatform =
+ (AugmentedSysPlatform) system.systemState()
+ .platform().augmentation(DefaultAugmentedSysPlatform.class);
+ serialNumber = augmentedSysPlatform.deviceIdentification().serialNumber();
+ DateAndTime deviceDateAndTime = system.systemState().clock().currentDatetime();
+ OffsetDateTime odt =
+ OffsetDateTime.parse(deviceDateAndTime.string(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+ if (odt.getYear() < OffsetDateTime.now(ZoneId.of("UTC")).getYear()) {
+ OffsetDateTime nowUtc = OffsetDateTime.now(ZoneId.of("UTC"));
+ log.warn("Date on device is in the past: {}. Setting it to {}", odt.toString(), nowUtc);
+ ietfSystemService.setCurrentDatetime(nowUtc, session);
+ }
+ }
+
+ if (system != null && system.system() != null) {
+ AugmentedSysSystem augmentedSystem =
+ (AugmentedSysSystem) system.system().augmentation(DefaultAugmentedSysSystem.class);
+ longitudeStr = augmentedSystem.longitude().toPlainString();
+ latitudeStr = augmentedSystem.latitude().toPlainString();
+ }
+ } catch (NetconfException e) {
+ log.error("Unable to retrieve init data from device: " + handler().data().deviceId().toString()
+ + " Error: " + e.getMessage());
+ e.printStackTrace();
+ }
+
+ DeviceService deviceService = checkNotNull(handler().get(DeviceService.class));
+ DeviceId deviceId = handler().data().deviceId();
+ Device device = deviceService.getDevice(deviceId);
+ DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder();
+ if (longitudeStr != null && latitudeStr != null) {
+ annotationsBuilder.set(AnnotationKeys.LONGITUDE, longitudeStr)
+ .set(AnnotationKeys.LATITUDE, latitudeStr).build();
+ } else {
+ log.warn("Longitude and latitude could not be retrieved from device " + deviceId);
+ }
+
+ return new DefaultDeviceDescription(device.id().uri(), Device.Type.OTHER, "Microsemi", "EA1000", swVersion,
+ serialNumber, new ChassisId(), annotationsBuilder.build());
+ }
+
+ @Override
+ public List<PortDescription> discoverPortDetails() {
+
+ List<PortDescription> ports = new ArrayList<PortDescription>();
+
+ DefaultAnnotations annotationOptics = DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "Optics")
+ .build();
+ PortDescription optics = new DefaultPortDescription(PortNumber.portNumber(0), true, Port.Type.FIBER, 1000,
+ annotationOptics);
+ ports.add(optics);
+
+ DefaultAnnotations annotationHost = DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "Host").build();
+ PortDescription host = new DefaultPortDescription(PortNumber.portNumber(1), true, Port.Type.COPPER, 1000,
+ annotationHost);
+ ports.add(host);
+
+ return ports;
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/FullMetersAvailable.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/FullMetersAvailable.java
new file mode 100644
index 0000000..724792e
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/FullMetersAvailable.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import org.onosproject.net.behaviour.MeterQuery;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+
+/**
+ * Driver which always responds that all Meters are available for the Device.
+ */
+public class FullMetersAvailable extends AbstractHandlerBehaviour implements MeterQuery {
+
+ private static final long MAX_METER = 0x00000FFF;
+
+ @Override
+ public long getMaxMeters() {
+ return MAX_METER;
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/MicrosemiDriversLoader.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/MicrosemiDriversLoader.java
new file mode 100644
index 0000000..b7f0e68
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/MicrosemiDriversLoader.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import org.apache.felix.scr.annotations.Component;
+import org.onosproject.net.driver.AbstractDriverLoader;
+
+/**
+ * Loader for Microsemi device drivers.
+ */
+@Component(immediate = true)
+public class MicrosemiDriversLoader extends AbstractDriverLoader {
+
+ public MicrosemiDriversLoader() {
+ super("/microsemi-drivers.xml");
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/NetconfConfigGetter.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/NetconfConfigGetter.java
new file mode 100644
index 0000000..53151bb
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/NetconfConfigGetter.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.microsemi;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.io.IOException;
+
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.ConfigGetter;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.netconf.NetconfController;
+import org.slf4j.Logger;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Used with the onos:device-configuration CLI command.
+ *
+ * This allows the full configuration to be retrieved from the device
+ */
+public class NetconfConfigGetter extends AbstractHandlerBehaviour implements ConfigGetter {
+
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PacketService packetService;
+
+ private PacketProcessor testProcessor;
+
+ // FIXME the error string should be universal for all implementations of
+ // ConfigGetter
+ public static final String UNABLE_TO_READ_CONFIG = "config retrieval error";
+
+ @Override
+ public String getConfiguration(String type) {
+ DriverHandler handler = handler();
+ NetconfController controller = handler.get(NetconfController.class);
+
+ DeviceId ofDeviceId = handler.data().deviceId();
+ Preconditions.checkNotNull(controller, "Netconf controller is null");
+ if (type == null ||
+ (!type.equalsIgnoreCase("running")
+ && !type.equalsIgnoreCase("candidate")
+ && !type.equalsIgnoreCase("startup"))) {
+ log.error("Configuration type must be either 'running', 'startup' or 'candidate'. '{}' is invalid", type);
+ return UNABLE_TO_READ_CONFIG;
+ }
+ try {
+ return controller.getDevicesMap().get(ofDeviceId).getSession().getConfig(type.replace("cfgType=", ""));
+ } catch (IOException e) {
+ log.error("Configuration could not be retrieved {}", e.getMessage());
+ }
+ return UNABLE_TO_READ_CONFIG;
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/RpcResultParser.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/RpcResultParser.java
new file mode 100644
index 0000000..7589ea7
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/RpcResultParser.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+public final class RpcResultParser {
+
+ private RpcResultParser() {
+ //Not called
+ }
+
+ public static String parseXml(final String deviceDescriptionResponse, final String keyWord) {
+
+ int end = deviceDescriptionResponse.lastIndexOf(keyWord);
+ end = deviceDescriptionResponse.lastIndexOf('<', end);
+ int start = deviceDescriptionResponse.lastIndexOf('>', end);
+ if (start > 1 && end > start) {
+ return deviceDescriptionResponse.substring(start + 1, end);
+ } else {
+ return null;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/package-info.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/package-info.java
new file mode 100644
index 0000000..de883d1
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package for Microsemi device drivers.
+ */
+package org.onosproject.drivers.microsemi;
\ No newline at end of file
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/IetfSystemNetconfService.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/IetfSystemNetconfService.java
new file mode 100644
index 0000000..44c62f6
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/IetfSystemNetconfService.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import java.time.OffsetDateTime;
+
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.doupgradeandreboot.DoUpgradeAndRebootInput;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.doupgradeandreboot.DoUpgradeAndRebootOutput;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.pullupdatetarfromtftp.PullUpdateTarFromTftpInput;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.readfromsyslog.ReadFromSyslogInput;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.readfromsyslog.ReadFromSyslogOutput;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.IetfSystem;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.IetfSystemOpParam;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.ietfsystem.systemrestart.SystemRestartInput;
+
+/**
+ * Extension of ietfSystemService to include NETCONF sessions.
+ *
+ * This is manually extended and should be revised if the ietf-system.yang file changes
+ */
+public interface IetfSystemNetconfService {
+ /**
+ * Returns the attribute ietfSystem.
+ *
+ * @param ietfSystem value of ietfSystem
+ * @param session An active NETCONF session
+ * @return ietfSystem
+ * @throws NetconfException if the session has any error
+ */
+ IetfSystem getIetfSystem(IetfSystemOpParam ietfSystem, NetconfSession session) throws NetconfException;
+
+ /**
+ * Returns the result of the init query.
+ *
+ * @param session An active NETCONF session
+ * @return ietfSystem
+ * @throws NetconfException if the session has any error
+ */
+ IetfSystem getIetfSystemInit(NetconfSession session) throws NetconfException;
+
+ /**
+ * Sets the value to attribute ietfSystem.
+ *
+ * @param ietfSystem value of ietfSystem
+ * @param session An active NETCONF session
+ * @param ncDs datastore type running, startup or candidate
+ * @return Boolean to indicate success or failure
+ * @throws NetconfException if the session has any error
+ */
+ boolean setIetfSystem(IetfSystemOpParam ietfSystem, NetconfSession session,
+ DatastoreId ncDs) throws NetconfException;
+
+ /**
+ * Service interface of setCurrentDatetime.
+ *
+ * @param date input of service interface setCurrentDatetime
+ * @param session An active NETCONF session
+ * @throws NetconfException if the session has any error
+ */
+ void setCurrentDatetime(OffsetDateTime date, NetconfSession session) throws NetconfException;
+
+ /**
+ * Service interface of systemRestart.
+ *
+ * @param inputVar input of service interface systemRestart
+ * @param session An active NETCONF session
+ * @throws NetconfException if the session has any error
+ */
+ void systemRestart(SystemRestartInput inputVar, NetconfSession session) throws NetconfException;
+
+ /**
+ * Service interface of systemShutdown.
+ *
+ * @param session An active NETCONF session
+ * @throws NetconfException if the session has any error
+ */
+ void systemShutdown(NetconfSession session) throws NetconfException;
+
+ /**
+ * Service interface of doUpgradeAndReboot.
+ *
+ * @param inputVar input of service interface doUpgradeAndReboot
+ * @param session An active NETCONF session
+ * @return doUpgradeAndRebootOutput output of service interface doUpgradeAndReboot
+ * @throws NetconfException if the session has any error
+ */
+ DoUpgradeAndRebootOutput doUpgradeAndReboot(DoUpgradeAndRebootInput inputVar, NetconfSession session)
+ throws NetconfException;
+
+ /**
+ * Service interface of pullUpdateTarFromTftp.
+ *
+ * @param inputVar input of service interface pullUpdateTarFromTftp
+ * @param session An active NETCONF session
+ * @throws NetconfException if the session has any error
+ */
+ void pullUpdateTarFromTftp(PullUpdateTarFromTftpInput inputVar, NetconfSession session)
+ throws NetconfException;
+
+ /**
+ * Service interface of readFromSyslog.
+ *
+ * @param inputVar input of service interface readFromSyslog
+ * @param session An active NETCONF session
+ * @return readFromSyslogOutput output of service interface readFromSyslog
+ * @throws NetconfException if the session has any error
+ */
+ ReadFromSyslogOutput readFromSyslog(ReadFromSyslogInput inputVar, NetconfSession session)
+ throws NetconfException;
+
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MicrosemiModelRegistrator.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MicrosemiModelRegistrator.java
new file mode 100644
index 0000000..6cf8031
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MicrosemiModelRegistrator.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.felix.scr.annotations.Component;
+import org.onosproject.yang.AbstractYangModelRegistrator;
+import org.onosproject.yang.gen.v1.entitystatetcmib.rev20051122.EntityStateTcMib;
+import org.onosproject.yang.gen.v1.fpgainternal.rev20151130.FpgaInternal;
+import org.onosproject.yang.gen.v1.ianacrypthash.rev20140806.IanaCryptHash;
+import org.onosproject.yang.gen.v1.ianaiftype.rev20140508.IanaIfType;
+import org.onosproject.yang.gen.v1.ieeetypes.rev20080522.IeeeTypes;
+import org.onosproject.yang.gen.v1.ietfinettypes.rev20130715.IetfInetTypes;
+import org.onosproject.yang.gen.v1.ietfinterfaces.rev20140508.IetfInterfaces;
+import org.onosproject.yang.gen.v1.ietfnetconf.rev20110601.IetfNetconf;
+import org.onosproject.yang.gen.v1.ietfnetconfacm.rev20120222.IetfNetconfAcm;
+import org.onosproject.yang.gen.v1.ietfnetconfmonitoring.rev20101004.IetfNetconfMonitoring;
+import org.onosproject.yang.gen.v1.ietfnetconfnotifications.rev20120206.IetfNetconfNotifications;
+import org.onosproject.yang.gen.v1.ietfnetconfwithdefaults.rev20100609.IetfNetconfWithDefaults;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.IetfSystem;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.IetfSystemMicrosemi;
+import org.onosproject.yang.gen.v1.ietfsystemtlsauth.rev20140524.IetfSystemTlsAuth;
+import org.onosproject.yang.gen.v1.ietfx509certtoname.rev20130326.IetfX509CertToName;
+import org.onosproject.yang.gen.v1.ietfyangtypes.rev20130715.IetfYangTypes;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfm;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFiltering;
+import org.onosproject.yang.gen.v1.mseasoamfm.rev20160229.MseaSoamFm;
+import org.onosproject.yang.gen.v1.mseasoampm.rev20160229.MseaSoamPm;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.MseaTypes;
+import org.onosproject.yang.gen.v1.mseaunievcinterface.rev20160317.MseaUniEvcInterface;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcService;
+import org.onosproject.yang.gen.v1.ncnotifications.rev20080714.NcNotifications;
+import org.onosproject.yang.gen.v1.netopeercfgnetopeer.rev20130214.NetopeerCfgnetopeer;
+import org.onosproject.yang.gen.v1.notifications.rev20080714.Notifications;
+import org.onosproject.yang.gen.v1.rfc2544.rev20151020.Rfc2544;
+import org.onosproject.yang.gen.v1.svcactivationtypes.rev20151027.SvcActivationTypes;
+import org.onosproject.yang.gen.v1.y1564.rev20151029.Y1564;
+import org.onosproject.yang.model.DefaultYangModuleId;
+import org.onosproject.yang.model.YangModuleId;
+import org.onosproject.yang.runtime.AppModuleInfo;
+import org.onosproject.yang.runtime.DefaultAppModuleInfo;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Representation of Microsemi model registrator which registers Microsemi device
+ * models.
+ */
+@Component(immediate = true)
+public class MicrosemiModelRegistrator extends AbstractYangModelRegistrator {
+
+ public MicrosemiModelRegistrator() {
+ super(IetfSystem.class, getAppInfo());
+ }
+
+ private static Map<YangModuleId, AppModuleInfo> getAppInfo() {
+ Map<YangModuleId, AppModuleInfo> appInfo = new HashMap<>();
+
+ appInfo.put(new DefaultYangModuleId("fpga-internal", "2015-11-30"),
+ new DefaultAppModuleInfo(FpgaInternal.class, null));
+ appInfo.put(new DefaultYangModuleId("iana-if-type", "2014-05-08"),
+ new DefaultAppModuleInfo(IanaIfType.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-yang-types", "2013-07-15"),
+ new DefaultAppModuleInfo(IetfYangTypes.class, null));
+ appInfo.put(new DefaultYangModuleId("msea-sa-filtering", "2016-04-12"),
+ new DefaultAppModuleInfo(MseaSaFiltering.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-x509-cert-to-name", "2013-03-26"),
+ new DefaultAppModuleInfo(IetfX509CertToName.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-system", "2014-08-06"),
+ new DefaultAppModuleInfo(IetfSystem.class, null));
+ appInfo.put(new DefaultYangModuleId("msea-types", "2016-02-29"),
+ new DefaultAppModuleInfo(MseaTypes.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-inet-types", "2013-07-15"),
+ new DefaultAppModuleInfo(IetfInetTypes.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-netconf-with-defaults", "2010-06-09"),
+ new DefaultAppModuleInfo(IetfNetconfWithDefaults.class, null));
+ appInfo.put(new DefaultYangModuleId("msea-uni-evc-service", "2016-03-17"),
+ new DefaultAppModuleInfo(MseaUniEvcService.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-netconf-monitoring", "2010-10-04"),
+ new DefaultAppModuleInfo(IetfNetconfMonitoring.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-netconf-acm", "2012-02-22"),
+ new DefaultAppModuleInfo(IetfNetconfAcm.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-system-tls-auth", "2014-05-24"),
+ new DefaultAppModuleInfo(IetfSystemTlsAuth.class, null));
+ appInfo.put(new DefaultYangModuleId("rfc-2544", "2015-10-20"),
+ new DefaultAppModuleInfo(Rfc2544.class, null));
+ appInfo.put(new DefaultYangModuleId("msea-cfm", "2016-02-29"),
+ new DefaultAppModuleInfo(MseaCfm.class, null));
+ appInfo.put(new DefaultYangModuleId("netopeer-cfgnetopeer", "2013-02-14"),
+ new DefaultAppModuleInfo(NetopeerCfgnetopeer.class, null));
+ appInfo.put(new DefaultYangModuleId("ENTITY-STATE-TC-MIB", "2005-11-22"),
+ new DefaultAppModuleInfo(EntityStateTcMib.class, null));
+ appInfo.put(new DefaultYangModuleId("msea-soam-fm", "2016-02-29"),
+ new DefaultAppModuleInfo(MseaSoamFm.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-netconf-notifications", "2012-02-06"),
+ new DefaultAppModuleInfo(IetfNetconfNotifications.class, null));
+ appInfo.put(new DefaultYangModuleId("nc-notifications", "2008-07-14"),
+ new DefaultAppModuleInfo(NcNotifications.class, null));
+ appInfo.put(new DefaultYangModuleId("iana-crypt-hash", "2014-08-06"),
+ new DefaultAppModuleInfo(IanaCryptHash.class, null));
+ appInfo.put(new DefaultYangModuleId("msea-uni-evc-interface", "2016-03-17"),
+ new DefaultAppModuleInfo(MseaUniEvcInterface.class, null));
+ appInfo.put(new DefaultYangModuleId("msea-soam-pm", "2016-02-29"),
+ new DefaultAppModuleInfo(MseaSoamPm.class, null));
+ appInfo.put(new DefaultYangModuleId("ieee-types", "2008-05-22"),
+ new DefaultAppModuleInfo(IeeeTypes.class, null));
+ appInfo.put(new DefaultYangModuleId("svc-activation-types", "2015-10-27"),
+ new DefaultAppModuleInfo(SvcActivationTypes.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-netconf", "2011-06-01"),
+ new DefaultAppModuleInfo(IetfNetconf.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-system-microsemi", "2016-05-05"),
+ new DefaultAppModuleInfo(IetfSystemMicrosemi.class, null));
+ appInfo.put(new DefaultYangModuleId("notifications", "2008-07-14"),
+ new DefaultAppModuleInfo(Notifications.class, null));
+ appInfo.put(new DefaultYangModuleId("y-1564", "2015-10-29"),
+ new DefaultAppModuleInfo(Y1564.class, null));
+ appInfo.put(new DefaultYangModuleId("ietf-interfaces", "2014-05-08"),
+ new DefaultAppModuleInfo(IetfInterfaces.class, null));
+ return ImmutableMap.copyOf(appInfo);
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MseaCfmNetconfService.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MseaCfmNetconfService.java
new file mode 100644
index 0000000..cdd3700
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MseaCfmNetconfService.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfm;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfmOpParam;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.abortloopback.AbortLoopbackInput;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitlinktrace.TransmitLinktraceInput;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitlinktrace.TransmitLinktraceOutput;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.TransmitLoopbackInput;
+
+/**
+ * Extension of mseaCfmService to include NETCONF sessions.
+ *
+ * This is manually extended and should be revised if the msea-cfm.yang,
+ * msea-soam-pm.yang or msea-soam-fm.yang files change
+ */
+public interface MseaCfmNetconfService {
+
+ /**
+ * Returns attributes of MEP.
+ *
+ * @param mdName The name of the MD
+ * @param maName The name of the MA
+ * @param mepId The ID of the MEP
+ * @param session An active NETCONF session
+ * @return mseaCfm
+ * @throws NetconfException if the session has any error
+ */
+ MseaCfm getMepEssentials(String mdName, String maName, int mepId,
+ NetconfSession session) throws NetconfException;
+
+
+ /**
+ * Returns attributes of DM.
+ *
+ * @param mdName The name of the MD
+ * @param maName The name of the MA
+ * @param mepId The ID of the MEP
+ * @param dmId The Id of the Delay Measurement
+ * @param session An active NETCONF session
+ * @return mseaCfm
+ * @throws NetconfException if the session has any error
+ */
+ MseaCfm getSoamDm(String mdName, String maName, int mepId,
+ int dmId, NetconfSession session) throws NetconfException;
+
+ /**
+ * Sets the value to attribute mseaCfm.
+ *
+ * @param mseaCfm value of mseaCfm
+ * @param session An active NETCONF session
+ * @param targetDs one of running, candidate or startup
+ * @return Boolean to indicate success or failure
+ * @throws NetconfException if the session has any error
+ */
+ boolean setMseaCfm(MseaCfmOpParam mseaCfm, NetconfSession session,
+ DatastoreId targetDs) throws NetconfException;
+
+ /**
+ * Service interface of transmitLoopback.
+ *
+ * @param inputVar input of service interface transmitLoopback
+ * @param session An active NETCONF session
+ * @throws NetconfException if the session has any error
+ */
+ void transmitLoopback(TransmitLoopbackInput inputVar,
+ NetconfSession session) throws NetconfException;
+
+ /**
+ * Service interface of abortLoopback.
+ *
+ * @param inputVar input of service interface abortLoopback
+ * @param session An active NETCONF session
+ * @throws NetconfException if the session has any error
+ */
+ void abortLoopback(AbortLoopbackInput inputVar,
+ NetconfSession session) throws NetconfException;
+
+ /**
+ * Service interface of transmitLinktrace.
+ *
+ * @param inputVar input of service interface transmitLinktrace
+ * @param session An active NETCONF session
+ * @return transmitLinktraceOutput output of service interface transmitLinktrace
+ * @throws NetconfException if the session has any error
+ */
+ TransmitLinktraceOutput transmitLinktrace(TransmitLinktraceInput inputVar,
+ NetconfSession session) throws NetconfException;
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MseaSaFilteringNetconfService.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MseaSaFilteringNetconfService.java
new file mode 100644
index 0000000..f9788f3
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MseaSaFilteringNetconfService.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.microsemi.yang;
+
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFilteringOpParam;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.interfaceeth0.SourceAddressRange;
+
+import java.util.List;
+
+/**
+ * Extension of mseaSaFilteringService to include NETCONF sessions.
+ *
+ * This is manually extended and should be revised if the msea-sa-filtering.yang file changes
+ */
+public interface MseaSaFilteringNetconfService {
+ /**
+ * Returns the attribute mseaSaFiltering.
+ *
+ * @param mseaSaFiltering value of mseaSaFiltering
+ * @param session An active NETCONF session
+ * @return mseaSaFiltering
+ * @throws NetconfException if the session has any error
+ */
+ MseaSaFiltering getMseaSaFiltering(
+ MseaSaFilteringOpParam mseaSaFiltering, final NetconfSession session)
+ throws NetconfException;
+
+ /**
+ * Get a filtered subset of the config model.
+ *
+ * @param session An active NETCONF session
+ * @return mseaSaFiltering
+ * @throws NetconfException if the session has any error
+ */
+ public List<SourceAddressRange> getConfigMseaSaFilterIds(NetconfSession session)
+ throws NetconfException;
+
+ /**
+ * Sets the value to attribute mseaSaFiltering.
+ *
+ * @param mseaSaFiltering value of mseaSaFiltering
+ * @param session An active NETCONF session
+ * @param targetDs The NETCONF datastore to edit
+ * @return Boolean to indicate success or failure
+ * @throws NetconfException if the session has any error
+ */
+ boolean setMseaSaFiltering(MseaSaFilteringOpParam mseaSaFiltering,
+ NetconfSession session, DatastoreId targetDs) throws NetconfException;
+
+ /**
+ * Deletes the value to attribute mseaSaFiltering.
+ *
+ * @param mseaSaFiltering value of mseaSaFiltering
+ * @param session An active NETCONF session
+ * @param targetDs The NETCONF datastore to edit
+ * @return Boolean to indicate success or failure
+ * @throws NetconfException if the session has any error
+ */
+ boolean deleteMseaSaFilteringRange(MseaSaFilteringOpParam mseaSaFiltering,
+ NetconfSession session, DatastoreId targetDs) throws NetconfException;
+
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MseaUniEvcServiceNetconfService.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MseaUniEvcServiceNetconfService.java
new file mode 100644
index 0000000..a7f85bf
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/MseaUniEvcServiceNetconfService.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.microsemi.yang;
+
+import java.util.List;
+import java.util.Map;
+
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcService;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcServiceOpParam;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.UniSideInterfaceAssignmentEnum;
+
+/**
+ * Extension of mseaUniEvcServiceService to include NETCONF sessions.
+ *
+ * This is manually extended and should be revised if the msea-uni-evc-service.yang
+ * file changes
+ */
+public interface MseaUniEvcServiceNetconfService {
+ /**
+ * Returns the configuration and state attributes of the running mseaUniEvcService.
+ *
+ * @param mseaUniEvcService value of mseaUniEvcService
+ * @param session The NETCONF session
+ * @return mseaUniEvcService
+ * @throws NetconfException if the session has any error
+ */
+ MseaUniEvcService getMseaUniEvcService(
+ MseaUniEvcServiceOpParam mseaUniEvcService, NetconfSession session)
+ throws NetconfException;
+
+ /**
+ * Returns the configuration only attributes of mseaUniEvcService.
+ *
+ * @param mseaUniEvcService value of mseaUniEvcService
+ * @param session The NETCONF session
+ * @param targetDs one of running, candidate or startup
+ * @return mseaUniEvcService
+ * @throws NetconfException if the session has any error
+ */
+ MseaUniEvcService getConfigMseaUniEvcService(
+ MseaUniEvcServiceOpParam mseaUniEvcService, NetconfSession session,
+ DatastoreId targetDs) throws NetconfException;
+
+ /**
+ * Sets the value to attribute mseaUniEvcService.
+ *
+ * @param mseaUniEvcService value of mseaUniEvcService
+ * @param session The NETCONF session
+ * @param targetDs one of running, candidate or startup
+ * @return Boolean to indicate success or failure
+ * @throws NetconfException if the session has any error
+ */
+ boolean setMseaUniEvcService(MseaUniEvcServiceOpParam mseaUniEvcService,
+ NetconfSession session, DatastoreId targetDs)
+ throws NetconfException;
+
+ /**
+ * Deletes the objects in mseaUniEvcService.
+ *
+ * @param mseaUniEvcService value of mseaUniEvcService
+ * @param session The NETCONF session
+ * @param targetDs one of running, candidate or startup
+ * @return Boolean to indicate success or failure
+ * @throws NetconfException if the session has any error
+ */
+ boolean deleteMseaUniEvcService(MseaUniEvcServiceOpParam mseaUniEvcService,
+ NetconfSession session, DatastoreId targetDs) throws NetconfException;
+
+ /**
+ * Returns a list of the CeVlanMaps on both sides of the EVC.
+ *
+ * @param session A NETCONF Session
+ * @param ncDs The datastore to affect - running, candidate or startup
+ * @return The Object Model with the VLans
+ * @throws NetconfException if the session has any error
+ */
+ MseaUniEvcService getmseaUniEvcCeVlanMaps(
+ NetconfSession session, DatastoreId ncDs)
+ throws NetconfException;
+
+ /**
+ * Replace ceVlans or delete EVCs from a device.
+ *
+ * It is necessary to have a custom command for this as the YCH cannot
+ * handle the intricacies of putting a replace operation on the
+ * ceVlanMap leaf at present
+ *
+ * @param ceVlanUpdates A Map of CeVlanMap entries to change, as flows are deleted
+ * @param flowVlanIds The IDs of flows that are being removed
+ * @param session A NETCONF Session
+ * @param targetDs The datastore to affect - running, candidate or startup
+ * @param portAssign The port assignment of the device
+ * @throws NetconfException if the session has any error
+ */
+ void removeEvcUniFlowEntries(
+ Map<Integer, String> ceVlanUpdates,
+ Map<Integer, List<Short>> flowVlanIds,
+ NetconfSession session,
+ DatastoreId targetDs,
+ UniSideInterfaceAssignmentEnum portAssign)
+ throws NetconfException;
+
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/UniSide.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/UniSide.java
new file mode 100644
index 0000000..8ced81c
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/UniSide.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+/**
+ * An enumeration to describe the side of a UNI - Customer or Network.
+ * For reference see MEF 6.2
+ */
+public enum UniSide {
+ CUSTOMER,
+ NETWORK
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/custom/CustomEvcPerUnic.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/custom/CustomEvcPerUnic.java
new file mode 100644
index 0000000..fbf89be
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/custom/CustomEvcPerUnic.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang.custom;
+
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.ServiceListType;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.EvcPerUniServiceTypeEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.FlowMapping;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.TagManipulation;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.evcperuni.DefaultEvcPerUnic;
+
+import java.util.List;
+
+/**
+ * Extend the DefaultEvcPerUnic so that the ceVlanMap can always be initialized at 0.
+ */
+public class CustomEvcPerUnic extends DefaultEvcPerUnic {
+ @Override
+ public ServiceListType ceVlanMap() {
+ if (ceVlanMap == null) {
+ return new ServiceListType("0");
+ }
+ return ceVlanMap;
+ }
+ @Override
+ public Object ingressBwpGroupIndex() {
+ return ingressBwpGroupIndex;
+ }
+
+ @Override
+ public EvcPerUniServiceTypeEnum evcPerUniServiceType() {
+ return evcPerUniServiceType;
+ }
+
+ @Override
+ public TagManipulation tagManipulation() {
+ return tagManipulation;
+ }
+
+ @Override
+ public List<FlowMapping> flowMapping() {
+ return flowMapping;
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/custom/CustomEvcPerUnin.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/custom/CustomEvcPerUnin.java
new file mode 100644
index 0000000..d8712dc
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/custom/CustomEvcPerUnin.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang.custom;
+
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.ServiceListType;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.EvcPerUniServiceTypeEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.FlowMapping;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.TagManipulation;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.evcperuni.DefaultEvcPerUnin;
+
+import java.util.List;
+
+/**
+ * Extend the DefaultEvcPerUnin so that the ceVlanMap can always be initialized at 0.
+ */
+public class CustomEvcPerUnin extends DefaultEvcPerUnin {
+ @Override
+ public ServiceListType ceVlanMap() {
+ if (ceVlanMap == null) {
+ return new ServiceListType("0");
+ }
+ return ceVlanMap;
+ }
+ @Override
+ public Object ingressBwpGroupIndex() {
+ return ingressBwpGroupIndex;
+ }
+
+ @Override
+ public EvcPerUniServiceTypeEnum evcPerUniServiceType() {
+ return evcPerUniServiceType;
+ }
+
+ @Override
+ public TagManipulation tagManipulation() {
+ return tagManipulation;
+ }
+
+ @Override
+ public List<FlowMapping> flowMapping() {
+ return flowMapping;
+ }
+
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/custom/package-info.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/custom/package-info.java
new file mode 100644
index 0000000..1a7a471
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/custom/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package for Microsemi device drivers support for NETCONF for EA1000.
+ */
+package org.onosproject.drivers.microsemi.yang.custom;
\ No newline at end of file
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/AbstractYangServiceImpl.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/AbstractYangServiceImpl.java
new file mode 100644
index 0000000..3867a2f
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/AbstractYangServiceImpl.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.ByteSource;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.model.ModelConverter;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.model.SchemaContext;
+import org.onosproject.yang.model.SchemaContextProvider;
+import org.onosproject.yang.runtime.AnnotatedNodeInfo;
+import org.onosproject.yang.runtime.CompositeData;
+import org.onosproject.yang.runtime.CompositeStream;
+import org.onosproject.yang.runtime.DefaultCompositeData;
+import org.onosproject.yang.runtime.DefaultCompositeStream;
+import org.onosproject.yang.runtime.DefaultYangSerializerContext;
+import org.onosproject.yang.runtime.YangModelRegistry;
+import org.onosproject.yang.runtime.YangSerializer;
+import org.onosproject.yang.runtime.YangSerializerContext;
+import org.onosproject.yang.runtime.YangSerializerRegistry;
+import org.onosproject.yang.serializers.xml.XmlSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract class that implements some of the core functions of a YANG model service.
+ *
+ */
+@Component(immediate = true)
+@Service
+public abstract class AbstractYangServiceImpl {
+ public static final String NC_OPERATION = "nc:operation";
+ public static final String OP_DELETE = "delete";
+
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+ protected boolean alreadyLoaded = false;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected YangModelRegistry yangModelRegistry;
+
+// @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+// protected SchemaContextProvider schemaContextProvider;
+
+ protected ApplicationId appId;
+
+ // xSer is not a service and is a class variable. Can be lost on deactivate.
+ // Must be recreated on activate
+ protected XmlSerializer xSer;
+ protected YangSerializerContext yCtx;
+
+ protected static final Pattern REGEX_XML_HEADER =
+ Pattern.compile("(<\\?xml).*(\\?>)", Pattern.DOTALL);
+ protected static final Pattern REGEX_RPC_REPLY =
+ Pattern.compile("(<rpc-reply)[ ]*" +
+ "(xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\")[ ]*" +
+ "(message-id=\")[0-9]*(\">)", Pattern.DOTALL);
+ protected static final Pattern REGEX_RPC_REPLY_DATA_NS =
+ Pattern.compile("(<data)[ ]*(xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)");
+ protected static final Pattern REGEX_RPC_REPLY_DATA =
+ Pattern.compile("(<data>)");
+ protected static final Pattern REGEX_RPC_REPLY_DATA_CLOSE =
+ Pattern.compile("(</data>)");
+ protected static final Pattern REGEX_RPC_REPLY_DATA_EMPTY =
+ Pattern.compile("(<data/>)");
+ protected static final Pattern REGEX_RPC_REPLY_CLOSE =
+ Pattern.compile("(</rpc-reply>)");
+
+ @Activate
+ public void activate() {
+ Set<YangSerializer> yangSer = ((YangSerializerRegistry) yangModelRegistry).getSerializers();
+ yangSer.forEach(ser -> {
+ if (ser instanceof XmlSerializer) {
+ xSer = (XmlSerializer) ser;
+ }
+ });
+ SchemaContext context = ((SchemaContextProvider) yangModelRegistry)
+ .getSchemaContext(ResourceId.builder().addBranchPointSchema("/", null).build());
+
+ yCtx = new DefaultYangSerializerContext(context, null);
+ };
+
+ @Deactivate
+ public void deactivate() {
+ alreadyLoaded = false;
+ }
+
+ /**
+ * Internal method to generically make a NETCONF get query from YANG objects.
+ * @param moFilter A YANG object model
+ * @param session A NETCONF session
+ * @return YangObjectModel
+ * @throws NetconfException if the session has any error
+ */
+ protected final ModelObjectData getNetconfObject(
+ ModelObjectData moFilter, NetconfSession session)
+ throws NetconfException {
+
+ return getConfigNetconfObject(moFilter, session, null);
+ }
+
+ /**
+ * Internal method to generically make a NETCONF get-config query from YANG objects.
+ *
+ * @param moFilter A YANG object model
+ * @param session A NETCONF session
+ * @param targetDs - running,candidate or startup
+ * @return YangObjectModel
+ * @throws NetconfException if the session has any error
+ */
+ protected final ModelObjectData getConfigNetconfObject(
+ ModelObjectData moFilter, NetconfSession session, DatastoreId targetDs)
+ throws NetconfException {
+ if (session == null) {
+ throw new NetconfException("Session is null when calling getConfigNetconfObject()");
+ }
+
+ if (moFilter == null) {
+ throw new NetconfException("Query object cannot be null");
+ }
+
+ String xmlQueryStr = encodeMoToXmlStr(moFilter, null);
+
+ log.debug("Sending <get-(config)> query on NETCONF session " + session.getSessionId() +
+ ":\n" + xmlQueryStr);
+ String xmlResult;
+ if (targetDs == null) {
+ xmlResult = session.get(xmlQueryStr, null);
+ } else {
+ xmlResult = session.getConfig(targetDs, xmlQueryStr);
+ }
+ xmlResult = removeRpcReplyData(xmlResult);
+
+ DefaultCompositeStream resultDcs = new DefaultCompositeStream(
+ null, new ByteArrayInputStream(xmlResult.getBytes()));
+ CompositeData compositeData = xSer.decode(resultDcs, yCtx);
+
+ return ((ModelConverter) yangModelRegistry).createModel(compositeData.resourceData());
+ }
+
+ /**
+ * Internal method to generically make a NETCONF edit-config call from a set of YANG objects.
+ *
+ * @param moConfig A YANG object model
+ * @param session A NETCONF session
+ * @param targetDs - running,candidate or startup
+ * @param annotations A list of AnnotatedNodeInfos to be added to the DataNodes
+ * @return Boolean value indicating success or failure of command
+ * @throws NetconfException if the session has any error
+ */
+ protected final boolean setNetconfObject(
+ ModelObjectData moConfig, NetconfSession session, DatastoreId targetDs,
+ List<AnnotatedNodeInfo> annotations) throws NetconfException {
+ if (moConfig == null) {
+ throw new NetconfException("Query object cannot be null");
+ } else if (session == null) {
+ throw new NetconfException("Session is null when calling getMseaSaFiltering()");
+ } else if (targetDs == null) {
+ throw new NetconfException("TargetDs is null when calling getMseaSaFiltering()");
+ }
+
+ String xmlQueryStr = encodeMoToXmlStr(moConfig, annotations);
+ log.debug("Sending <edit-config> query on NETCONF session " + session.getSessionId() +
+ ":\n" + xmlQueryStr);
+
+ return session.editConfig(targetDs, null, xmlQueryStr);
+ }
+
+ protected final String encodeMoToXmlStr(ModelObjectData yangObjectOpParamFilter,
+ List<AnnotatedNodeInfo> annotations)
+ throws NetconfException {
+ //Convert the param to XML to use as a filter
+ ResourceData rd = ((ModelConverter) yangModelRegistry).createDataNode(yangObjectOpParamFilter);
+
+ DefaultCompositeData.Builder cdBuilder =
+ DefaultCompositeData.builder().resourceData(rd);
+ if (annotations != null) {
+ for (AnnotatedNodeInfo ani : annotations) {
+ cdBuilder.addAnnotatedNodeInfo(ani);
+ }
+ }
+ CompositeStream cs = xSer.encode(cdBuilder.build(), yCtx);
+ //Convert the param to XML to use as a filter
+
+ try {
+ ByteSource byteSource = new ByteSource() {
+ @Override
+ public InputStream openStream() throws IOException {
+ return cs.resourceData();
+ }
+ };
+
+ return byteSource.asCharSource(Charsets.UTF_8).read();
+ } catch (IOException e) {
+ throw new NetconfException("Error decoding CompositeStream to String", e);
+ }
+ }
+
+ protected static final String removeRpcReplyData(String rpcReplyXml) {
+ rpcReplyXml = REGEX_XML_HEADER.matcher(rpcReplyXml).replaceFirst("");
+ rpcReplyXml = REGEX_RPC_REPLY.matcher(rpcReplyXml).replaceFirst("");
+ rpcReplyXml = REGEX_RPC_REPLY_DATA_NS.matcher(rpcReplyXml).replaceFirst("");
+ rpcReplyXml = REGEX_RPC_REPLY_DATA.matcher(rpcReplyXml).replaceFirst("");
+ rpcReplyXml = REGEX_RPC_REPLY_DATA_CLOSE.matcher(rpcReplyXml).replaceFirst("");
+ rpcReplyXml = REGEX_RPC_REPLY_DATA_EMPTY.matcher(rpcReplyXml).replaceFirst("");
+ rpcReplyXml = REGEX_RPC_REPLY_CLOSE.matcher(rpcReplyXml).replaceFirst("");
+ rpcReplyXml = rpcReplyXml.replace("\t", "");
+ return rpcReplyXml;
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/IetfSystemManager.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/IetfSystemManager.java
new file mode 100644
index 0000000..3673594
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/IetfSystemManager.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang.impl;
+
+import java.io.ByteArrayInputStream;
+import java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.drivers.microsemi.yang.IetfSystemNetconfService;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.ietfsystem.DefaultSystem;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.ietfsystem.DefaultSystemState;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.doupgradeandreboot.DoUpgradeAndRebootInput;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.doupgradeandreboot.DoUpgradeAndRebootOutput;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.pullupdatetarfromtftp.PullUpdateTarFromTftpInput;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.readfromsyslog.ReadFromSyslogInput;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.readfromsyslog.ReadFromSyslogOutput;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.IetfSystem;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.IetfSystemOpParam;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.ietfsystem.systemrestart.SystemRestartInput;
+import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.ModelConverter;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.runtime.CompositeData;
+import org.onosproject.yang.runtime.DefaultCompositeStream;
+
+/**
+ * Implementation of the IetfService YANG model service.
+ */
+@Component(immediate = true, inherit = true)
+@Service
+public class IetfSystemManager extends AbstractYangServiceImpl
+ implements IetfSystemNetconfService {
+
+ protected static final String IETF_SYSTEM = "org.onosproject.drivers.microsemi.yang.ietfsystem";
+
+ @Activate
+ public void activate() {
+ super.activate();
+ appId = coreService.registerApplication(IETF_SYSTEM);
+ log.info("IetfSystemManager Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ super.deactivate();
+ log.info("IetfSystemManager Stopped");
+ }
+
+ /**
+ * Get a filtered subset of the model.
+ * This is meant to filter the current live model
+ * against the attribute(s) given in the argument
+ * and return the filtered model.
+ * @throws NetconfException if the session has any error
+ */
+ @Override
+ public IetfSystem getIetfSystem(IetfSystemOpParam ietfSystemFilter, NetconfSession session)
+ throws NetconfException {
+
+ ModelObjectData moQuery = DefaultModelObjectData.builder()
+ .addModelObject((ModelObject) ietfSystemFilter.system())
+ .build();
+
+ ModelObjectData moReply = getNetconfObject(moQuery, session);
+
+ IetfSystemOpParam ietfSystem = new IetfSystemOpParam();
+ for (ModelObject mo:moReply.modelObjects()) {
+ if (mo instanceof DefaultSystem) {
+ ietfSystem.system((DefaultSystem) mo);
+ } else if (mo instanceof DefaultSystemState) {
+ ietfSystem.systemState((DefaultSystemState) mo);
+ }
+ }
+
+ return ietfSystem;
+ }
+
+ @Override
+ public IetfSystem getIetfSystemInit(NetconfSession session) throws NetconfException {
+ if (session == null) {
+ throw new NetconfException("Session is null when calling getIetfSystemInit()");
+ }
+
+ String xmlResult = session.get(getInitRequestBuilder(), null);
+
+ xmlResult = removeRpcReplyData(xmlResult);
+ DefaultCompositeStream resultDcs = new DefaultCompositeStream(
+ null, new ByteArrayInputStream(xmlResult.getBytes()));
+ CompositeData compositeData = xSer.decode(resultDcs, yCtx);
+
+ ModelObjectData mod = ((ModelConverter) yangModelRegistry).createModel(compositeData.resourceData());
+
+ IetfSystemOpParam ietfSystem = new IetfSystemOpParam();
+ for (ModelObject mo:mod.modelObjects()) {
+ if (mo instanceof DefaultSystem) {
+ ietfSystem.system((DefaultSystem) mo);
+ } else if (mo instanceof DefaultSystemState) {
+ ietfSystem.systemState((DefaultSystemState) mo);
+ }
+ }
+
+ return ietfSystem;
+ }
+
+ /**
+ * Call NETCONF edit-config with a configuration.
+ */
+ @Override
+ public boolean setIetfSystem(IetfSystemOpParam ietfSystem, NetconfSession session,
+ DatastoreId ncDs) throws NetconfException {
+ ModelObjectData mo = DefaultModelObjectData.builder()
+ .addModelObject(ietfSystem).build();
+ return setNetconfObject(mo, session, ncDs, null);
+ }
+
+ @Override
+ public void setCurrentDatetime(OffsetDateTime date, NetconfSession session)
+ throws NetconfException {
+ String xmlQueryStr = getSetCurrentDatetimeBuilder(date);
+ log.info("Sending <get> query on NETCONF session " + session.getSessionId() +
+ ":\n" + xmlQueryStr);
+
+ String xmlResult = session.doWrappedRpc(xmlQueryStr);
+ log.info("Result from NETCONF RPC <set-current-datetime>: {}", xmlResult);
+ }
+
+ @Override
+ public void systemRestart(SystemRestartInput inputVar, NetconfSession session) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ @Override
+ public void systemShutdown(NetconfSession session) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ @Override
+ public DoUpgradeAndRebootOutput doUpgradeAndReboot(DoUpgradeAndRebootInput inputVar, NetconfSession session)
+ throws NetconfException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ @Override
+ public void pullUpdateTarFromTftp(PullUpdateTarFromTftpInput inputVar, NetconfSession session)
+ throws NetconfException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ @Override
+ public ReadFromSyslogOutput readFromSyslog(ReadFromSyslogInput inputVar, NetconfSession session)
+ throws NetconfException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+
+ /**
+ * Builds a request crafted to get the configuration required to create
+ * details descriptions for the device.
+ *
+ * @return The request string.
+ */
+ private static String getInitRequestBuilder() {
+ StringBuilder rpc = new StringBuilder();
+ rpc.append("<system-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-system\" ");
+ rpc.append("xmlns:sysms=\"http://www.microsemi.com/microsemi-edge-assure/msea-system\">");
+ rpc.append("<platform>");
+ rpc.append("<os-release/>");
+ rpc.append("<sysms:device-identification>");
+ rpc.append("<sysms:serial-number/>");
+ rpc.append("</sysms:device-identification>");
+ rpc.append("</platform>");
+ rpc.append("<clock>");
+ rpc.append("<current-datetime/>");
+ rpc.append("</clock>");
+ rpc.append("</system-state>");
+ rpc.append("<system xmlns=\"urn:ietf:params:xml:ns:yang:ietf-system\" ");
+ rpc.append("xmlns:sysms=\"http://www.microsemi.com/microsemi-edge-assure/msea-system\">");
+ rpc.append("<sysms:longitude/>");
+ rpc.append("<sysms:latitude/>");
+ rpc.append("</system>");
+ return rpc.toString();
+ }
+
+ private static String getSetCurrentDatetimeBuilder(OffsetDateTime date) {
+ StringBuilder rpc = new StringBuilder();
+ rpc.append("<set-current-datetime xmlns=\"urn:ietf:params:xml:ns:yang:ietf-system\">");
+ rpc.append("<current-datetime>");
+ rpc.append(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx")));
+ rpc.append("</current-datetime>");
+ rpc.append("</set-current-datetime>");
+
+ return rpc.toString();
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/MseaCfmManager.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/MseaCfmManager.java
new file mode 100644
index 0000000..36f48c4
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/MseaCfmManager.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang.impl;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.drivers.microsemi.yang.MseaCfmNetconfService;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfm;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfmOpParam;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.DefaultMefCfm;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.abortloopback.AbortLoopbackInput;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitlinktrace.TransmitLinktraceInput;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitlinktrace.TransmitLinktraceOutput;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.TransmitLoopbackInput;
+import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.ModelConverter;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.runtime.CompositeData;
+import org.onosproject.yang.runtime.DefaultCompositeStream;
+
+import java.io.ByteArrayInputStream;
+
+/**
+ * Implementation of the MseaCfmServiceNetconf YANG model service.
+ */
+@Component(immediate = true, inherit = true)
+@Service
+public class MseaCfmManager extends AbstractYangServiceImpl
+ implements MseaCfmNetconfService {
+
+ public static final String MSEA_CFM = "org.onosproject.drivers.microsemi.yang.mseacfmservice";
+
+ @Activate
+ public void activate() {
+ super.activate();
+ appId = coreService.registerApplication(MSEA_CFM);
+ log.info("MseaCfmService Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ super.deactivate();
+ log.info("MseaCfmService Stopped");
+ }
+
+ @Override
+ public MseaCfm getMepEssentials(String mdName, String maName, int mepId,
+ NetconfSession session) throws NetconfException {
+ if (session == null) {
+ throw new NetconfException("Session is null when calling getMepEssentials()");
+ }
+
+ String xmlQueryStr = buildMepQueryString(mdName, maName, mepId);
+ log.debug("Sending <get> for " +
+ " query on NETCONF session " + session.getSessionId() +
+ ":\n" + xmlQueryStr);
+
+ String xmlResult = session.get(xmlQueryStr, null);
+
+ xmlResult = removeRpcReplyData(xmlResult);
+ DefaultCompositeStream resultDcs = new DefaultCompositeStream(
+ null, new ByteArrayInputStream(xmlResult.getBytes()));
+ CompositeData compositeData = xSer.decode(resultDcs, yCtx);
+
+ ModelObjectData mod = ((ModelConverter) yangModelRegistry).createModel(compositeData.resourceData());
+
+ MseaCfmOpParam mseaCfm = new MseaCfmOpParam();
+ for (ModelObject mo:mod.modelObjects()) {
+ if (mo instanceof DefaultMefCfm) {
+ mseaCfm.mefCfm((DefaultMefCfm) mo);
+ }
+ }
+
+ return mseaCfm;
+ }
+
+ @Override
+ public MseaCfm getSoamDm(String mdName, String maName, int mepId,
+ int dmId, NetconfSession session) throws NetconfException {
+ String xmlQueryStr = buildDmQueryString(mdName, maName, mepId, dmId);
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ @Override
+ public boolean setMseaCfm(MseaCfmOpParam mseaCfm, NetconfSession session,
+ DatastoreId targetDs) throws NetconfException {
+ ModelObjectData moEdit = DefaultModelObjectData.builder()
+ .addModelObject(mseaCfm).build();
+
+ return setNetconfObject(moEdit, session, targetDs, null);
+ }
+
+ /**
+ * Call RPCs on the device through NETCONF.
+ */
+ @Override
+ public void transmitLoopback(TransmitLoopbackInput inputVar, NetconfSession session) throws NetconfException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ @Override
+ public void abortLoopback(AbortLoopbackInput inputVar, NetconfSession session) throws NetconfException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ @Override
+ public TransmitLinktraceOutput transmitLinktrace(TransmitLinktraceInput inputVar, NetconfSession session)
+ throws NetconfException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ private String buildMepQueryString(String mdName, String maName, int mepId) {
+ StringBuilder rpc = new StringBuilder();
+
+ rpc.append("<mef-cfm xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-cfm\" ");
+ rpc.append(" xmlns:msea-soam-fm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-fm\" ");
+ rpc.append("xmlns:msea-soam-pm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-pm\">\n");
+ rpc.append("<maintenance-domain>\n");
+ rpc.append("<id/>\n");
+ rpc.append("<name>" + mdName + "</name>\n");
+ rpc.append("<md-level/>\n");
+ rpc.append("<maintenance-association>\n");
+ rpc.append("<id/>\n");
+ rpc.append("<name>" + maName + "</name>\n");
+ rpc.append("<ccm-interval>10ms</ccm-interval>\n");
+ rpc.append("<remote-meps/>\n");
+ rpc.append("<component-list/>\n");
+ rpc.append("<maintenance-association-end-point>\n");
+ rpc.append("<mep-identifier>" + mepId + "</mep-identifier>\n");
+ rpc.append("<interface/>\n");
+ rpc.append("<primary-vid/>\n");
+ rpc.append("<administrative-state/>\n");
+ rpc.append("<ccm-ltm-priority/>\n");
+ rpc.append("<continuity-check/>\n");
+ rpc.append("<mac-address/>\n");
+ rpc.append("<msea-soam-fm:port-status/>\n");
+ rpc.append("<msea-soam-fm:interface-status/>\n");
+ rpc.append("<msea-soam-fm:last-defect-sent/>\n");
+ rpc.append("<msea-soam-fm:rdi-transmit-status/>\n");
+ rpc.append("<loopback/>\n");
+ rpc.append("<remote-mep-database/>\n");
+ rpc.append("<linktrace/>\n");
+ rpc.append("</maintenance-association-end-point>\n");
+ rpc.append("</maintenance-association>\n");
+ rpc.append("</maintenance-domain>\n");
+ rpc.append("</mef-cfm>");
+
+ return rpc.toString();
+ }
+
+
+ private String buildDmQueryString(String mdName, String maName, int mepId, int dmId) {
+ StringBuilder rpc = new StringBuilder();
+
+ rpc.append("<mef-cfm xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-cfm\" ");
+ rpc.append(" xmlns:msea-soam-fm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-fm\" ");
+ rpc.append("xmlns:msea-soam-pm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-pm\">\n");
+ rpc.append("<maintenance-domain>\n");
+ rpc.append("<id/>\n");
+ rpc.append("<name>" + mdName + "</name>\n");
+ rpc.append("<md-level/>\n");
+ rpc.append("<maintenance-association>\n");
+ rpc.append("<id/>\n");
+ rpc.append("<name>" + maName + "</name>\n");
+ rpc.append("<ccm-interval>10ms</ccm-interval>\n");
+ rpc.append("<maintenance-association-end-point>\n");
+ rpc.append("<mep-identifier>" + mepId + "</mep-identifier>\n");
+ rpc.append("<msea-soam-pm:delay-measurements>");
+ rpc.append("<msea-soam-pm:delay-measurement>");
+ rpc.append("<msea-soam-pm:dm-id>" + dmId + "</msea-soam-pm:dm-id>");
+ rpc.append("</msea-soam-pm:delay-measurement>");
+ rpc.append("</msea-soam-pm:delay-measurements>");
+ rpc.append("</maintenance-association-end-point>\n");
+ rpc.append("</maintenance-association>\n");
+ rpc.append("</maintenance-domain>\n");
+ rpc.append("</mef-cfm>");
+
+ return rpc.toString();
+ }
+
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/MseaSaFilteringManager.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/MseaSaFilteringManager.java
new file mode 100644
index 0000000..01af138
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/MseaSaFilteringManager.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang.impl;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.drivers.microsemi.yang.MseaSaFilteringNetconfService;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFilteringOpParam;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.SourceIpaddressFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.interfaceeth0.SourceAddressRange;
+import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.ModelConverter;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.AnnotatedNodeInfo;
+import org.onosproject.yang.runtime.CompositeData;
+import org.onosproject.yang.runtime.DefaultAnnotatedNodeInfo;
+import org.onosproject.yang.runtime.DefaultAnnotation;
+import org.onosproject.yang.runtime.DefaultCompositeStream;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of the MseaSaFiltering YANG model service.
+ */
+@Component(immediate = true, inherit = true)
+@Service
+public class MseaSaFilteringManager extends AbstractYangServiceImpl
+ implements MseaSaFilteringNetconfService {
+ public static final String MSEA_SA_FILTERING =
+ "org.onosproject.drivers.microsemi.yang.mseasafiltering";
+ public static final String MSEA_SA_FILTERING_NS =
+ "http://www.microsemi.com/microsemi-edge-assure/msea-sa-filtering";
+
+ @Activate
+ public void activate() {
+ super.activate();
+ appId = coreService.registerApplication(MSEA_SA_FILTERING);
+ log.info("MseaSaFilteringManager Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ super.deactivate();
+ log.info("MseaSaFilteringManager Stopped");
+ }
+
+ /**
+ * Get a filtered subset of the model.
+ * This is meant to filter the current live model
+ * against the attribute(s) given in the argument
+ * and return the filtered model.
+ */
+ @Override
+ public MseaSaFiltering getMseaSaFiltering(
+ MseaSaFilteringOpParam mseaSaFilteringFilter, NetconfSession session)
+ throws NetconfException {
+ ModelObjectData moQuery = DefaultModelObjectData.builder()
+ .addModelObject((ModelObject) mseaSaFilteringFilter
+ .sourceIpaddressFiltering())
+ .build();
+
+
+ ModelObjectData moReply = getNetconfObject(moQuery, session);
+
+ MseaSaFiltering reply = new MseaSaFilteringOpParam();
+ for (ModelObject mo:moReply.modelObjects()) {
+ if (mo instanceof SourceIpaddressFiltering) {
+ reply.sourceIpaddressFiltering((SourceIpaddressFiltering) mo);
+ }
+ }
+ return reply;
+ }
+
+ /**
+ * Get a filtered subset of the config model (from running)
+ * This is meant to filter the current live model
+ * against the attribute(s) given in the argument
+ * and return the filtered model.
+ */
+ @Override
+ public List<SourceAddressRange> getConfigMseaSaFilterIds(NetconfSession session)
+ throws NetconfException {
+
+ String xmlResult = session.getConfig(DatastoreId.RUNNING, saFilterQuery());
+ xmlResult = removeRpcReplyData(xmlResult);
+
+ DefaultCompositeStream resultDcs = new DefaultCompositeStream(
+ null, new ByteArrayInputStream(xmlResult.getBytes()));
+ CompositeData compositeData = xSer.decode(resultDcs, yCtx);
+
+ ModelObjectData moReply = ((ModelConverter) yangModelRegistry).createModel(compositeData.resourceData());
+
+ MseaSaFiltering reply = new MseaSaFilteringOpParam();
+ for (ModelObject mo:moReply.modelObjects()) {
+ if (mo instanceof SourceIpaddressFiltering) {
+ reply.sourceIpaddressFiltering((SourceIpaddressFiltering) mo);
+ }
+ }
+ if (reply != null && reply.sourceIpaddressFiltering() != null &&
+ reply.sourceIpaddressFiltering().interfaceEth0() != null) {
+ return reply.sourceIpaddressFiltering().interfaceEth0().sourceAddressRange();
+ } else {
+ return new ArrayList<SourceAddressRange>();
+ }
+ }
+
+ /**
+ * Call NETCONF edit-config with a configuration.
+ */
+ @Override
+ public boolean setMseaSaFiltering(MseaSaFilteringOpParam mseaSaFiltering,
+ NetconfSession session, DatastoreId ncDs) throws NetconfException {
+
+ ModelObjectData moQuery = DefaultModelObjectData.builder()
+ .addModelObject((ModelObject) mseaSaFiltering
+ .sourceIpaddressFiltering()).build();
+
+ return setNetconfObject(moQuery, session, ncDs, null);
+ }
+
+ @Override
+ public boolean deleteMseaSaFilteringRange(MseaSaFilteringOpParam mseaSaFiltering,
+ NetconfSession session, DatastoreId ncDs) throws NetconfException {
+
+ ModelObjectData moQuery = DefaultModelObjectData.builder()
+ .addModelObject((ModelObject) mseaSaFiltering
+ .sourceIpaddressFiltering()).build();
+
+ ArrayList anis = new ArrayList<AnnotatedNodeInfo>();
+ if (mseaSaFiltering.sourceIpaddressFiltering().interfaceEth0() != null &&
+ mseaSaFiltering.sourceIpaddressFiltering().interfaceEth0().sourceAddressRange() != null) {
+
+ for (SourceAddressRange sar:mseaSaFiltering.sourceIpaddressFiltering()
+ .interfaceEth0().sourceAddressRange()) {
+ String sarRangeIdStr = String.valueOf(sar.rangeId());
+
+ ResourceId.Builder ridBuilder = ResourceId.builder()
+ .addBranchPointSchema("/", null)
+ .addBranchPointSchema("source-ipaddress-filtering", MSEA_SA_FILTERING_NS)
+ .addBranchPointSchema("interface-eth0", MSEA_SA_FILTERING_NS)
+ .addBranchPointSchema("source-address-range", MSEA_SA_FILTERING_NS)
+ .addKeyLeaf("range-id", MSEA_SA_FILTERING_NS, sarRangeIdStr);
+
+ AnnotatedNodeInfo ani = DefaultAnnotatedNodeInfo.builder()
+ .resourceId(ridBuilder.build())
+ .addAnnotation(new DefaultAnnotation(NC_OPERATION, OP_DELETE))
+ .build();
+
+ anis.add(ani);
+ }
+ } else {
+ //Delete all
+ ResourceId.Builder ridBuilder = ResourceId.builder()
+ .addBranchPointSchema("/", null)
+ .addBranchPointSchema("source-ipaddress-filtering", MSEA_SA_FILTERING_NS);
+ AnnotatedNodeInfo ani = DefaultAnnotatedNodeInfo.builder()
+ .resourceId(ridBuilder.build())
+ .addAnnotation(new DefaultAnnotation(NC_OPERATION, OP_DELETE))
+ .build();
+ anis.add(ani);
+ }
+
+ return setNetconfObject(moQuery, session, ncDs, anis);
+ }
+
+
+ private static String saFilterQuery() {
+ StringBuilder sb = new StringBuilder("<source-ipaddress-filtering " +
+ "xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-sa-filtering\">");
+ sb.append("<interface-eth0>");
+ sb.append("<filter-admin-state>blacklist</filter-admin-state>");
+ sb.append("<source-address-range>");
+ sb.append("<range-id/>");
+ sb.append("</source-address-range>");
+ sb.append("</interface-eth0>");
+ sb.append("</source-ipaddress-filtering>");
+ return sb.toString();
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/MseaUniEvcServiceManager.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/MseaUniEvcServiceManager.java
new file mode 100644
index 0000000..f965541
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/MseaUniEvcServiceManager.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang.impl;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.drivers.microsemi.yang.MseaUniEvcServiceNetconfService;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcService;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcServiceOpParam;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.MefServices;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.BwpGroup;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.UniSideInterfaceAssignmentEnum;
+import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.ModelConverter;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.AnnotatedNodeInfo;
+import org.onosproject.yang.runtime.CompositeData;
+import org.onosproject.yang.runtime.DefaultAnnotatedNodeInfo;
+import org.onosproject.yang.runtime.DefaultAnnotation;
+import org.onosproject.yang.runtime.DefaultCompositeStream;
+
+/**
+ * Implementation of the MseaUniEvcServiceService YANG model service.
+ */
+@Component(immediate = true, inherit = true)
+@Service
+public class MseaUniEvcServiceManager extends AbstractYangServiceImpl
+ implements MseaUniEvcServiceNetconfService {
+ public static final String MSEA_UNI_EVC_SVC =
+ "org.onosproject.drivers.microsemi.yang.mseaunievcservice";
+ public static final String MSEA_UNI_EVC_SVC_NS =
+ "http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service";
+
+ @Activate
+ public void activate() {
+ super.activate();
+ appId = coreService.registerApplication(MSEA_UNI_EVC_SVC);
+ log.info("MseaUniEvcServiceManager Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ super.deactivate();
+ log.info("MseaUniEvcServiceManager Stopped");
+ }
+
+ @Override
+ public MseaUniEvcService getMseaUniEvcService(
+ MseaUniEvcServiceOpParam mseaUniEvcService, NetconfSession session)
+ throws NetconfException {
+
+ return getConfigMseaUniEvcService(mseaUniEvcService, session, null);
+ }
+
+ @Override
+ public MseaUniEvcService getConfigMseaUniEvcService(
+ MseaUniEvcServiceOpParam mseaUniEvcService, NetconfSession session,
+ DatastoreId targetDs) throws NetconfException {
+
+ ModelObjectData moFilter = DefaultModelObjectData.builder()
+ .addModelObject((ModelObject) mseaUniEvcService.mefServices()).build();
+
+ ModelObjectData moReply = getConfigNetconfObject(moFilter, session, targetDs);
+
+ MseaUniEvcService reply = new MseaUniEvcServiceOpParam();
+ for (ModelObject mo:moReply.modelObjects()) {
+ if (mo instanceof MefServices) {
+ reply.mefServices((MefServices) mo);
+ }
+ }
+ return reply;
+ }
+
+ /**
+ * Modify the configuration.
+ */
+ @Override
+ public boolean setMseaUniEvcService(MseaUniEvcServiceOpParam mseaUniEvcService,
+ NetconfSession session, DatastoreId ncDs) throws NetconfException {
+ ModelObjectData moEdit = DefaultModelObjectData.builder()
+ .addModelObject((ModelObject) mseaUniEvcService.mefServices()).build();
+
+ return setNetconfObject(moEdit, session, ncDs, null);
+ }
+
+ /**
+ * Delete the configuration.
+ */
+ @Override
+ public boolean deleteMseaUniEvcService(MseaUniEvcServiceOpParam mseaUniEvcService,
+ NetconfSession session, DatastoreId ncDs) throws NetconfException {
+ ModelObjectData moEdit = DefaultModelObjectData.builder()
+ .addModelObject((ModelObject) mseaUniEvcService.mefServices()).build();
+
+ ArrayList anis = new ArrayList<AnnotatedNodeInfo>();
+ for (BwpGroup bwpGrp:mseaUniEvcService.mefServices().profiles().bwpGroup()) {
+ String bwpGroupIndex = String.valueOf(bwpGrp.groupIndex());
+
+ ResourceId.Builder ridBuilder = ResourceId.builder()
+ .addBranchPointSchema("/", null)
+ .addBranchPointSchema("mef-services", MSEA_UNI_EVC_SVC_NS)
+ .addBranchPointSchema("profiles", MSEA_UNI_EVC_SVC_NS)
+ .addBranchPointSchema("bwp-group", MSEA_UNI_EVC_SVC_NS)
+ .addKeyLeaf("group-index", MSEA_UNI_EVC_SVC_NS, bwpGroupIndex);
+
+ AnnotatedNodeInfo ani = DefaultAnnotatedNodeInfo.builder()
+ .resourceId(ridBuilder.build())
+ .addAnnotation(new DefaultAnnotation(NC_OPERATION, OP_DELETE))
+ .build();
+
+ anis.add(ani);
+ }
+
+
+ return setNetconfObject(moEdit, session, ncDs, anis);
+ }
+
+
+ @Override
+ public MseaUniEvcService getmseaUniEvcCeVlanMaps(
+ NetconfSession session, DatastoreId ncDs)
+ throws NetconfException {
+ if (session == null) {
+ throw new NetconfException("Session is null when calling getMseaSaFiltering()");
+ }
+
+ String xmlResult = session.getConfig(ncDs, evcFilterQuery());
+ xmlResult = removeRpcReplyData(xmlResult);
+
+ DefaultCompositeStream resultDcs = new DefaultCompositeStream(
+ null, new ByteArrayInputStream(xmlResult.getBytes()));
+ CompositeData compositeData = xSer.decode(resultDcs, yCtx);
+
+ ModelObjectData moReply = ((ModelConverter) yangModelRegistry).createModel(compositeData.resourceData());
+
+ MseaUniEvcService reply = new MseaUniEvcServiceOpParam();
+ for (ModelObject mo:moReply.modelObjects()) {
+ if (mo instanceof MefServices) {
+ reply.mefServices((MefServices) mo);
+ }
+ }
+ return reply;
+ }
+
+ @Override
+ public void removeEvcUniFlowEntries(
+ Map<Integer, String> ceVlanUpdates,
+ Map<Integer, List<Short>> flowVlanIds,
+ NetconfSession session, DatastoreId targetDs,
+ UniSideInterfaceAssignmentEnum portAssign) throws NetconfException {
+
+ List<Integer> evcAlreadyHandled = new ArrayList<>();
+ StringBuilder xmlEvcUpdate = new StringBuilder(evcUniOpener());
+ for (Integer evcKey:ceVlanUpdates.keySet()) {
+ int evcId = (evcKey & ((1 << 8) - 100)) >> 2;
+ if (evcAlreadyHandled.contains(new Integer(evcId))) {
+ continue;
+ }
+ evcAlreadyHandled.add(evcId);
+ int port = (evcKey & 3);
+ String ceVlanMapThis = ceVlanUpdates.get(evcKey);
+ String ceVlanMapOpposite = ceVlanUpdates.get(evcKey ^ 1);
+
+ if ((ceVlanMapThis == null || ceVlanMapThis.isEmpty()) &&
+ (ceVlanMapOpposite == null || ceVlanMapOpposite.isEmpty())) {
+ xmlEvcUpdate.append("<evc nc:operation=\"delete\">\n<evc-index>");
+ xmlEvcUpdate.append(Integer.toString(evcId));
+ xmlEvcUpdate.append("</evc-index>\n</evc>\n");
+ } else {
+ xmlEvcUpdate.append("<evc>\n<evc-index>");
+ xmlEvcUpdate.append(Integer.toString(evcId));
+ xmlEvcUpdate.append("</evc-index>\n<evc-per-uni>\n");
+ if (port == 0 && portAssign == UniSideInterfaceAssignmentEnum.UNI_C_ON_OPTICS ||
+ port == 1 && portAssign == UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST) {
+ if (ceVlanMapThis != null) {
+ xmlEvcUpdate.append("<evc-per-uni-c>\n<ce-vlan-map nc:operation=\"replace\">");
+ xmlEvcUpdate.append(ceVlanMapThis);
+ xmlEvcUpdate.append("</ce-vlan-map>\n");
+ xmlEvcUpdate.append(deleteFlowMapping(flowVlanIds.get(evcKey)));
+ xmlEvcUpdate.append("</evc-per-uni-c>\n");
+ }
+ if (ceVlanMapOpposite != null) {
+ xmlEvcUpdate.append("<evc-per-uni-n>\n<ce-vlan-map nc:operation=\"replace\">");
+ xmlEvcUpdate.append(ceVlanMapOpposite);
+ xmlEvcUpdate.append("</ce-vlan-map>\n");
+ xmlEvcUpdate.append(deleteFlowMapping(flowVlanIds.get(evcKey ^ 1)));
+ xmlEvcUpdate.append("</evc-per-uni-n>\n");
+ }
+ } else {
+ if (ceVlanMapThis != null) {
+ xmlEvcUpdate.append("<evc-per-uni-n>\n<ce-vlan-map nc:operation=\"replace\">");
+ xmlEvcUpdate.append(ceVlanMapThis);
+ xmlEvcUpdate.append("</ce-vlan-map>\n");
+ xmlEvcUpdate.append(deleteFlowMapping(flowVlanIds.get(evcKey)));
+ xmlEvcUpdate.append("</evc-per-uni-n>\n");
+ }
+ if (ceVlanMapOpposite != null) {
+ xmlEvcUpdate.append("<evc-per-uni-c>\n<ce-vlan-map nc:operation=\"replace\">");
+ xmlEvcUpdate.append(ceVlanMapOpposite);
+ xmlEvcUpdate.append("</ce-vlan-map>\n");
+ xmlEvcUpdate.append(deleteFlowMapping(flowVlanIds.get(evcKey ^ 1)));
+ xmlEvcUpdate.append("</evc-per-uni-c>\n");
+ }
+ }
+
+ xmlEvcUpdate.append("</evc-per-uni>\n</evc>\n");
+ }
+ }
+ xmlEvcUpdate.append("</uni>\n</mef-services>");
+
+ log.info("Sending XML <edit-config> on NETCONF session " + session.getSessionId() +
+ ":\n" + xmlEvcUpdate.toString());
+
+
+ session.editConfig(targetDs, null, xmlEvcUpdate.toString());
+ }
+
+
+ private static String deleteFlowMapping(List<Short> vlanIds) {
+ if (vlanIds == null || vlanIds.size() == 0) {
+ return "";
+ }
+ StringBuilder fmXmlBuilder = new StringBuilder();
+ for (long vlanId:vlanIds) {
+ fmXmlBuilder.append("<flow-mapping nc:operation=\"delete\">\n");
+ fmXmlBuilder.append("<ce-vlan-id>");
+ fmXmlBuilder.append(String.valueOf(vlanId));
+ fmXmlBuilder.append("</ce-vlan-id>\n");
+ fmXmlBuilder.append("</flow-mapping>\n");
+ }
+
+ return fmXmlBuilder.toString();
+ }
+
+ private String evcFilterQuery() {
+ StringBuilder sb = new StringBuilder("<mef-services "
+ + "xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\">");
+ sb.append("<uni>");
+ sb.append("<evc>");
+ sb.append("<evc-index/>");
+ sb.append("<evc-per-uni>");
+ sb.append("<evc-per-uni-c>");
+ sb.append("<ce-vlan-map/>");
+ sb.append("<flow-mapping/>");
+ sb.append("<ingress-bwp-group-index/>");
+ sb.append("</evc-per-uni-c>");
+ sb.append("<evc-per-uni-n>");
+ sb.append("<ce-vlan-map/>");
+ sb.append("<flow-mapping/>");
+ sb.append("<ingress-bwp-group-index/>");
+ sb.append("</evc-per-uni-n>");
+ sb.append("</evc-per-uni>");
+ sb.append("</evc>");
+ sb.append("</uni>");
+ sb.append("</mef-services>");
+
+ return sb.toString();
+ }
+
+ private String evcUniOpener() {
+ StringBuilder sb = new StringBuilder("<mef-services ");
+ sb.append("xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\">\n");
+ sb.append("<uni>\n");
+
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/package-info.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/package-info.java
new file mode 100644
index 0000000..ccf0dd2
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package for Microsemi device drivers support for NETCONF for EA1000.
+ */
+package org.onosproject.drivers.microsemi.yang.impl;
\ No newline at end of file
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/package-info.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/package-info.java
new file mode 100644
index 0000000..d886c69
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package for Microsemi device drivers support for NETCONF for EA1000.
+ */
+package org.onosproject.drivers.microsemi.yang;
\ No newline at end of file
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/utils/CeVlanMapUtils.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/utils/CeVlanMapUtils.java
new file mode 100644
index 0000000..52ede6d
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/utils/CeVlanMapUtils.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang.utils;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.lang.ArrayUtils;
+
+/**
+ * A set of static utilities that allow a ce-vlan-map to be decomposed.
+ *
+ * This is an implementation specific to Microsemi that encodes ce-vlan-map
+ * in a similar way to Section 7.9 in the MEF 10.2 specification. That specification
+ * suggests comma delimited lists of VIDs - this implementation adds on colons to
+ * specify a contiguous range of IDs
+ */
+public final class CeVlanMapUtils {
+
+ private CeVlanMapUtils() {
+ //Do not allow this utility class to be instantiated
+ }
+
+ /**
+ * Calculate the ceVlanMap in to a Set of values.
+ *
+ * From Yang description
+ * "This object indicates the CE-VLANs associated with the specific
+ * EVC on a UNI. CE-VLAN IDs have value of 0 to 4095. The CE-VLAN ID
+ * list can be a single value or multiple values separated by a delimiter.
+ * Some valid values are: '100', '1:10', '10,20,30', '1:4095'. In the
+ * first example only CE-VLAN ID 100 is associated with the VLAN map.
+ * In the second example the CE-VLAN map includes CE-VLAN IDs 1 through
+ * 10 (range of values). The third example indicates three separate values
+ * that make up the CE-VLAN map. The last example indicates all CE-VLAN IDs
+ * are included in the map (range of values). ";
+ * reference
+ * "[MEF 6.1] 6.1; [MEF 7.2] 6.2.1.3";
+ * @param ceVlanMap A list of vlan id's in the format described above
+ * @return A set of vlan ids
+ */
+ public static Short[] getVlanSet(String ceVlanMap) {
+ if (ceVlanMap == null || ceVlanMap.isEmpty()) {
+ return new Short[0];
+ }
+ Set<Short> ceVlanSet = new TreeSet<Short>();
+
+ String[] ceVlanMapCommas = ceVlanMap.split(",");
+ for (String ceVlanMapComma:ceVlanMapCommas) {
+ String[] ceVlanMapColon = ceVlanMapComma.split(":");
+ if (ceVlanMapColon.length == 1) {
+ ceVlanSet.add(Short.decode(ceVlanMapColon[0]));
+ } else {
+ short start = Short.decode(ceVlanMapColon[0]);
+ short end = Short.decode(ceVlanMapColon[1]);
+ if ((start < 0 || end > 4095)) {
+ return null;
+ } else {
+ for (short i = start; i <= end; i++) {
+ ceVlanSet.add(i);
+ }
+ }
+ }
+ }
+
+ return ceVlanSet.toArray(new Short[ceVlanSet.size()]);
+ }
+
+ /**
+ * Convert an array of vlan ids in to a string representation.
+ * @param vlanArray An array of vlan ids
+ * @return A string representation delimited by commas and colons
+ */
+ public static String vlanListAsString(Short[] vlanArray) {
+ boolean colonPending = false;
+ StringBuilder ceVlanMapBuilder = new StringBuilder();
+ if (vlanArray.length == 0) {
+ return "";
+ } else if (vlanArray.length == 1 && vlanArray[0] == 0) {
+ return "0";
+ }
+
+ //To ensure that there are no repeated or out-of-order elements we must convert to TreeSet
+ TreeSet<Short> vlanSet = new TreeSet<>(Arrays.asList(vlanArray));
+
+ if (vlanSet.first() == 0) {
+ vlanSet.remove(vlanSet.first());
+ }
+ short prev = vlanSet.first();
+ for (short s:vlanSet) {
+ if (s == prev) {
+ ceVlanMapBuilder.append(Short.valueOf(s));
+ continue;
+ } else if (prev == (s - 1)) {
+ colonPending = true;
+ } else {
+ if (colonPending) {
+ ceVlanMapBuilder.append(":" + Short.valueOf(prev));
+ colonPending = false;
+ }
+ ceVlanMapBuilder.append("," + Short.valueOf(s));
+ }
+ prev = s;
+ }
+ if (colonPending) {
+ ceVlanMapBuilder.append(":" + Short.valueOf(prev));
+ }
+
+ return ceVlanMapBuilder.toString();
+ }
+
+ /**
+ * Add an additional vlan id to an existing string representation.
+ * @param existingMap An array of vlan ids
+ * @param newVlan The new vlan ID to add
+ * @return A string representation delimited by commas and colons
+ */
+ public static String addtoCeVlanMap(String existingMap, Short newVlan) {
+ Short[] vlanArray = getVlanSet(existingMap);
+ TreeSet<Short> vlanSet = new TreeSet<>();
+ for (Short vlan:vlanArray) {
+ vlanSet.add(vlan);
+ }
+
+ vlanSet.add(newVlan);
+
+ return vlanListAsString(vlanSet.toArray(new Short[vlanSet.size()]));
+ }
+
+ /**
+ * If a string representation contains a '0' then remove it.
+ *
+ * Zero is an invalid VLAN id, and is used here as a place holder for null. Null can't
+ * be used in the EA1000 device. Once any other vlan ids are added then the zero should
+ * be removed. It is safe to call this method even if no zero is present - the method will
+ * make no change in that case.
+ *
+ * @param existingMap An string representation of vlan ids, possibly containing a zero
+ * @return A string representation delimited by commas and colons without zero
+ */
+ public static String removeZeroIfPossible(String existingMap) {
+ if (existingMap == null || existingMap.isEmpty()) {
+ return "0";
+ } else if (existingMap == "0") {
+ return existingMap;
+ }
+ return removeFromCeVlanMap(existingMap, (short) 0);
+ }
+
+ /**
+ * Remove a vlan id from an existing string representation.
+ * @param existingMap An array of vlan ids
+ * @param vlanRemove The vlan ID to remove
+ * @return A string representation delimited by commas and colons
+ */
+ public static String removeFromCeVlanMap(String existingMap, Short vlanRemove) {
+ Short[] vlanArray = getVlanSet(existingMap);
+ TreeSet<Short> vlanSet = new TreeSet<>();
+ for (Short vlan:vlanArray) {
+ if (vlan.shortValue() != vlanRemove.shortValue()) {
+ vlanSet.add(vlan);
+ }
+ }
+
+ return vlanListAsString(vlanSet.toArray(new Short[vlanSet.size()]));
+ }
+
+ /**
+ * Combine vlan ids from two existing string representations.
+ *
+ * If there are overlapping elements and ranges, these are consolidated in to one.
+ *
+ * @param set1 A string containing a set of vlan ids
+ * @param set2 A string containing a set of vlan ids
+ * @return A string representation delimited by commas and colons
+ */
+ public static String combineVlanSets(String set1, String set2) {
+ Short[] set1Array = getVlanSet(set1);
+ Short[] set2Array = getVlanSet(set2);
+ return vlanListAsString((Short[]) ArrayUtils.addAll(set1Array, set2Array));
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/utils/IetfYangTypesUtils.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/utils/IetfYangTypesUtils.java
new file mode 100644
index 0000000..275dc25
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/utils/IetfYangTypesUtils.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang.utils;
+
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+import org.onosproject.yang.gen.v1.ietfyangtypes.rev20130715.ietfyangtypes.DateAndTime;
+
+/**
+ * A utility class to change various YANG types to general purpose classes.
+ */
+public final class IetfYangTypesUtils {
+ private IetfYangTypesUtils() {
+ //Hiding the public constructor for this utility class
+ }
+
+ /**
+ * Convert from Date and Time in a ietf-yang-types format to the Java Time API.
+ * @param dateAndTime A date and time from a YANG object
+ * @return A Date and Time with a Time Zone offset
+ */
+ public static OffsetDateTime fromYangDateTime(DateAndTime dateAndTime) {
+ return OffsetDateTime.parse(dateAndTime.toString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+ }
+
+ /**
+ * Convert a from Date and Time in a ietf-yang-types format to the Java Time API and rezone to a given Time Zone.
+ * @param dateAndTime A date and time from a YANG object
+ * @param zoneId The time zone to rezone the time and date to
+ * @return The rezoned time and date
+ */
+ public static ZonedDateTime fromYangDateTimeZoned(DateAndTime dateAndTime, ZoneId zoneId) {
+ return OffsetDateTime.parse(dateAndTime.toString(),
+ DateTimeFormatter.ISO_OFFSET_DATE_TIME).atZoneSameInstant(zoneId);
+ }
+
+ /**
+ * Convert a from Date and Time in a ietf-yang-types format to the Java Time API rezoned to the local Time Zone.
+ * @param dateAndTime A date and time from a YANG object
+ * @return The date and time in the zone of this local machine
+ */
+ public static LocalDateTime fromYangDateTimeToLocal(DateAndTime dateAndTime) {
+ OffsetDateTime odt = OffsetDateTime.parse(dateAndTime.toString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+
+ return LocalDateTime.ofInstant(odt.toInstant(), ZoneId.systemDefault());
+ }
+}
diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/utils/package-info.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/utils/package-info.java
new file mode 100644
index 0000000..0c03c46
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/yang/utils/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package for general utilities and helpers.
+ */
+package org.onosproject.drivers.microsemi.yang.utils;
\ No newline at end of file
diff --git a/drivers/microsemi/src/main/resources/microsemi-drivers.xml b/drivers/microsemi/src/main/resources/microsemi-drivers.xml
new file mode 100644
index 0000000..988ac9a
--- /dev/null
+++ b/drivers/microsemi/src/main/resources/microsemi-drivers.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2017-present Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<drivers>
+ <driver name="microsemi-netconf" extends="netconf" manufacturer="Microsemi"
+ hwVersion="EA1000">
+ <behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
+ impl="org.onosproject.drivers.microsemi.Ea1000DeviceDescription" />
+ <behaviour api="org.onosproject.net.behaviour.ConfigGetter"
+ impl="org.onosproject.drivers.microsemi.NetconfConfigGetter" />
+ <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+ impl="org.onosproject.drivers.microsemi.EA1000Pipeliner" />
+ <behaviour api="org.onosproject.net.flow.FlowRuleProgrammable"
+ impl="org.onosproject.drivers.microsemi.EA1000FlowRuleProgrammable" />
+ <behaviour api="org.onosproject.net.behaviour.MeterQuery"
+ impl="org.onosproject.drivers.microsemi.FullMetersAvailable" />
+<!-- <behaviour api="org.onosproject.incubator.net.l2monitoring.cfm.CfmMepProgrammable" -->
+<!-- impl="org.onosproject.drivers.microsemi.EA1000CfmMepProgrammable"/> -->
+<!-- <behaviour api="org.onosproject.incubator.net.l2monitoring.soam.SoamDmProgrammable" -->
+<!-- impl="org.onosproject.drivers.microsemi.EA1000SoamDmProgrammable"/> -->
+ </driver>
+</drivers>
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/EA1000FlowRuleProgrammableTest.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/EA1000FlowRuleProgrammableTest.java
new file mode 100644
index 0000000..24aad06
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/EA1000FlowRuleProgrammableTest.java
@@ -0,0 +1,363 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.EthType.EtherType;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowEntry.FlowEntryState;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.Criterion.Type;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+public class EA1000FlowRuleProgrammableTest {
+ EA1000FlowRuleProgrammable frProgramable;
+
+ @Before
+ public void setUp() throws Exception {
+ frProgramable = new EA1000FlowRuleProgrammable();
+ frProgramable.setHandler(new MockEa1000DriverHandler());
+ assertNotNull(frProgramable.handler().data().deviceId());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testGetFlowEntries() {
+ //From MockNetconfSession sample of MseaSaFiltering
+ Collection<FlowEntry> flowEntries = frProgramable.getFlowEntries();
+
+ assertNotNull(flowEntries);
+ //There will be 12 flow entries
+ // 2 for IP Src Address filtering
+ // 2 for EVC 7 - one each port
+ // 8 for EVC 8 - one for host port, 7 on optics port because of ceVlanMap 12:14,20:22,25
+ assertEquals(12, flowEntries.size());
+
+ //Test the first Flow Entry
+ Iterator<FlowEntry> feIter = flowEntries.iterator();
+ while (feIter.hasNext()) {
+ FlowEntry fe = feIter.next();
+ assertTrue(fe.isPermanent());
+ assertEquals(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT, fe.priority());
+
+ Set<Criterion> criteria = fe.selector().criteria();
+ IPCriterion ipCr = null;
+ PortNumber port = null;
+ for (Criterion cr:criteria.toArray(new Criterion[criteria.size()])) {
+ if (cr.type() == Criterion.Type.IPV4_SRC) {
+ ipCr = (IPCriterion) cr;
+ } else if (cr.type() == Criterion.Type.IN_PORT) {
+ port = ((PortCriterion) cr).port();
+ } else if (cr.type() == Criterion.Type.VLAN_VID) {
+ VlanId vid = ((VlanIdCriterion) cr).vlanId();
+ } else {
+ fail("Unexpected Criterion type: " + cr.type().toString());
+ }
+ }
+ if (ipCr != null && (port == null || port.toLong() != 0L)) {
+ fail("Port number not equal 0 when IP Src Address filter is present");
+ }
+
+ List<Instruction> instructions = fe.treatment().allInstructions();
+
+ if (fe.tableId() == 1) {
+ //Note that in MockNetconf session 10.10.10.10/16 was entered
+ //but it has been corrected to the following by the OF implementation
+ assertEquals("10.10.0.0/16", ipCr.ip().toString());
+ assertEquals(FlowEntryState.ADDED, fe.state());
+ } else if (fe.tableId() == 2) {
+ //Likewise 20.30.40.50 has been truncated because of the 18 bit mask
+ assertEquals("20.30.0.0/18", ipCr.ip().toString());
+ assertEquals(FlowEntryState.ADDED, fe.state());
+ } else if (fe.tableId() == 7 || fe.tableId() == 8) {
+ // 7 and 8 are EVC entries - 2 elements - IN_PORT and VLAN_ID
+ assertEquals(2, fe.selector().criteria().size());
+ //In MockNetconfSession we're rigged it so that the last two chars of the
+ //flow id is the same as the VlanId
+ short vlanId = ((VlanIdCriterion) fe.selector().getCriterion(Type.VLAN_VID)).vlanId().toShort();
+ long flowId = fe.id().id();
+ String flowIdStr = String.valueOf(flowId).substring(String.valueOf(flowId).length() - 2);
+ assertEquals(flowIdStr, String.valueOf(vlanId));
+ if (((PortCriterion) fe.selector().getCriterion(Type.IN_PORT)).port().toLong() == 1L) {
+ assertEquals(Instruction.Type.L2MODIFICATION, instructions.get(0).type());
+ }
+ } else {
+ fail("Unexpected Flow Entry Rule " + fe.tableId());
+ }
+ }
+ }
+
+ @Test
+ public void testSetFlowEntries() {
+ Criterion matchInPort = Criteria.matchInPort(PortNumber.portNumber(0));
+
+ TrafficTreatment treatmentDrop = DefaultTrafficTreatment.builder().drop().build();
+
+ Collection<FlowRule> frAddedList = new HashSet<FlowRule>();
+
+ FlowRule fr4 = new DefaultFlowRule.Builder()
+ .forDevice(frProgramable.handler().data().deviceId())
+ .forTable(4)
+ .withSelector(DefaultTrafficSelector.builder()
+ .matchIPSrc(IpPrefix.valueOf("192.168.60.0/22"))
+ .add(matchInPort).build())
+ .withTreatment(treatmentDrop)
+ .fromApp(new DefaultApplicationId(4, "Filter4"))
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
+ .build();
+ frAddedList.add(fr4);
+
+ FlowRule fr5 = new DefaultFlowRule.Builder()
+ .forDevice(frProgramable.handler().data().deviceId())
+ .forTable(5)
+ .withSelector(DefaultTrafficSelector.builder()
+ .matchIPSrc(IpPrefix.valueOf("192.168.50.0/23"))
+ .add(matchInPort).build())
+ .withTreatment(treatmentDrop)
+ .withCookie(Long.valueOf("5e0000abaa2772", 16))
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
+ .build();
+ frAddedList.add(fr5);
+
+ //Add in some EVCs - especially with complex ceVlanMaps
+ FlowRule frEvc1Vid19P0 = new DefaultFlowRule.Builder()
+ .forDevice(frProgramable.handler().data().deviceId())
+ .forTable(1)
+ .withSelector(DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(0L))
+ .matchVlanId(VlanId.vlanId((short) 19))
+ .build())
+ .withTreatment(DefaultTrafficTreatment.builder()
+ .popVlan()
+ .build())
+ .withCookie(Long.valueOf("1e0000abaa0019", 16))
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
+ .build();
+ frAddedList.add(frEvc1Vid19P0);
+
+ FlowRule frEvc1Vid20P0 = new DefaultFlowRule.Builder()
+ .forDevice(frProgramable.handler().data().deviceId())
+ .forTable(1)
+ .withSelector(DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(0L))
+ .matchVlanId(VlanId.vlanId((short) 20))
+ .build())
+ .withTreatment(DefaultTrafficTreatment.builder()
+ .popVlan()
+ .build())
+ .withCookie(Long.valueOf("1e0000abaa0020", 16))
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
+ .build();
+ frAddedList.add(frEvc1Vid20P0);
+
+ FlowRule frEvc1Vid21P1 = new DefaultFlowRule.Builder()
+ .forDevice(frProgramable.handler().data().deviceId())
+ .forTable(1)
+ .withSelector(DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(1L))
+ .matchVlanId(VlanId.vlanId((short) 21))
+ .build())
+ .withTreatment(DefaultTrafficTreatment.builder()
+ .setVlanId(VlanId.vlanId((short) 250))
+ .pushVlan(EtherType.QINQ.ethType())
+ .build())
+ .withCookie(Long.valueOf("1e0000abaa0121", 16))
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
+ .build();
+ frAddedList.add(frEvc1Vid21P1);
+
+ FlowRule frEvc1Vid22P1 = new DefaultFlowRule.Builder()
+ .forDevice(frProgramable.handler().data().deviceId())
+ .forTable(1)
+ .withSelector(DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(1L))
+ .matchVlanId(VlanId.vlanId((short) 22))
+ .build())
+ .withTreatment(DefaultTrafficTreatment.builder()
+ .setVlanId(VlanId.vlanId((short) 250))
+ .pushVlan(EtherType.QINQ.ethType())
+ .build())
+ .withCookie(Long.valueOf("1e0000abaa0122", 16))
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
+ .build();
+ frAddedList.add(frEvc1Vid22P1);
+
+ Collection<FlowRule> returnedFrList = frProgramable.applyFlowRules(frAddedList);
+
+ assertNotNull(returnedFrList);
+ assertEquals(6, returnedFrList.size());
+
+ //Test the scenario like in FlowRuleManager$InternalFlowRuleProviderService.pushFlowMetricsInternal()
+ Map<FlowEntry, FlowEntry> storedRules = Maps.newHashMap();
+ frAddedList.forEach(f -> storedRules.put(new DefaultFlowEntry(f), new DefaultFlowEntry(f)));
+ List<FlowEntry> feList = Lists.newArrayList();
+ returnedFrList.forEach(f -> feList.add(new DefaultFlowEntry(f)));
+
+ for (FlowEntry rule : feList) {
+ FlowEntry fer = storedRules.remove(rule);
+ assertNotNull(fer);
+ assertTrue(fer.exactMatch(rule));
+ }
+
+ for (FlowRule fr:returnedFrList.toArray(new FlowRule[2])) {
+ if (fr.tableId() == 4) {
+ assertEquals("IPV4_SRC:192.168.60.0/22",
+ ((IPCriterion) fr.selector().getCriterion(Type.IPV4_SRC)).toString());
+ } else if (fr.tableId() == 5) {
+ assertEquals("IPV4_SRC:192.168.50.0/23",
+ ((IPCriterion) fr.selector().getCriterion(Type.IPV4_SRC)).toString());
+ assertEquals(Long.valueOf("5e0000abaa2772", 16), fr.id().id());
+ } else if (fr.tableId() == 1) {
+ //TODO add in tests
+ } else {
+ fail("Unexpected flow rule " + fr.tableId() + " in test");
+ }
+ }
+ }
+
+ @Test
+ public void testRemoveFlowEntries() {
+ TrafficSelector.Builder tsBuilder = DefaultTrafficSelector.builder();
+ Criterion matchInPort0 = Criteria.matchInPort(PortNumber.portNumber(0));
+ Criterion matchInPort1 = Criteria.matchInPort(PortNumber.portNumber(1));
+
+ TrafficTreatment.Builder trDropBuilder = DefaultTrafficTreatment.builder();
+ TrafficTreatment treatmentDrop = trDropBuilder.drop().build();
+
+ Collection<FlowRule> frRemoveList = new HashSet<FlowRule>();
+ ApplicationId app = new DefaultApplicationId(1, "org.onosproject.rest");
+
+ Criterion matchIpSrc1 = Criteria.matchIPSrc(IpPrefix.valueOf("10.10.10.10/16"));
+ TrafficSelector selector1 = tsBuilder.add(matchIpSrc1).add(matchInPort0).build();
+ FlowRule.Builder frBuilder1 = new DefaultFlowRule.Builder();
+ frBuilder1.forDevice(frProgramable.handler().data().deviceId())
+ .withSelector(selector1)
+ .withTreatment(treatmentDrop)
+ .forTable(2)
+ .fromApp(app)
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT);
+ frRemoveList.add(frBuilder1.build());
+
+ Criterion matchIpSrc2 = Criteria.matchIPSrc(IpPrefix.valueOf("10.30.10.10/16"));
+ TrafficSelector selector2 = tsBuilder.add(matchIpSrc2).add(matchInPort0).build();
+ FlowRule.Builder frBuilder2 = new DefaultFlowRule.Builder();
+ frBuilder2.forDevice(frProgramable.handler().data().deviceId())
+ .withSelector(selector2)
+ .withTreatment(treatmentDrop)
+ .forTable(3)
+ .fromApp(app)
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
+ .build();
+ frRemoveList.add(frBuilder2.build());
+
+
+ TrafficTreatment.Builder trVlanPopBuilder = DefaultTrafficTreatment.builder();
+ TrafficTreatment treatmentVlanPop = trVlanPopBuilder.popVlan().build();
+
+
+ Criterion matchVlan710 = Criteria.matchVlanId(VlanId.vlanId((short) 710));
+ TrafficSelector selector3 = DefaultTrafficSelector.builder().add(matchVlan710).add(matchInPort1).build();
+ FlowRule.Builder frBuilder3 = new DefaultFlowRule.Builder();
+ frBuilder3.forDevice(frProgramable.handler().data().deviceId())
+ .withSelector(selector3)
+ .withTreatment(treatmentVlanPop)
+ .forTable(7)
+ .fromApp(app)
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
+ .build();
+ frRemoveList.add(frBuilder3.build());
+
+
+ Criterion matchVlan101 = Criteria.matchVlanId(VlanId.vlanId((short) 101));
+ TrafficSelector selector4 = DefaultTrafficSelector.builder().add(matchVlan101).add(matchInPort1).build();
+ FlowRule.Builder frBuilder4 = new DefaultFlowRule.Builder();
+ frBuilder4.forDevice(frProgramable.handler().data().deviceId())
+ .withSelector(selector4)
+ .withTreatment(treatmentVlanPop)
+ .forTable(1)
+ .fromApp(app)
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
+ .build();
+ frRemoveList.add(frBuilder4.build());
+
+ Criterion matchVlan102 = Criteria.matchVlanId(VlanId.vlanId((short) 102));
+ TrafficSelector selector5 = DefaultTrafficSelector.builder().add(matchVlan102).add(matchInPort0).build();
+ FlowRule.Builder frBuilder5 = new DefaultFlowRule.Builder();
+ frBuilder5.forDevice(frProgramable.handler().data().deviceId())
+ .withSelector(selector5)
+ .withTreatment(treatmentVlanPop)
+ .forTable(1)
+ .fromApp(app)
+ .makePermanent()
+ .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
+ .build();
+ frRemoveList.add(frBuilder5.build());
+
+ Collection<FlowRule> removedFrList = frProgramable.removeFlowRules(frRemoveList);
+ assertNotNull(removedFrList);
+ assertEquals(5, removedFrList.size());
+
+ for (FlowRule frRemoved:removedFrList) {
+ assertNotNull(frRemoved);
+ }
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/EA1000MeterProviderTest.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/EA1000MeterProviderTest.java
new file mode 100644
index 0000000..b00b321
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/EA1000MeterProviderTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import java.util.HashSet;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.drivers.microsemi.yang.MockMseaUniEvcServiceManager;
+import org.onosproject.drivers.microsemi.yang.MockNetconfSessionEa1000;
+import org.onosproject.drivers.netconf.MockNetconfController;
+import org.onosproject.drivers.netconf.MockNetconfDevice;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+import org.onosproject.net.meter.DefaultMeter;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.Meter.Unit;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterOperation;
+import org.onosproject.net.meter.MeterOperation.Type;
+import org.onosproject.netconf.NetconfController;
+
+public class EA1000MeterProviderTest {
+
+ private EA1000MeterProvider meterProvider;
+ private NetconfController controller;
+ private DeviceId mockDeviceId;
+ private MockMseaUniEvcServiceManager mseaUniEvcServiceSvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mockDeviceId = DeviceId.deviceId("netconf:1.2.3.4:830");
+ controller = new MockNetconfController();
+ MockNetconfDevice device = (MockNetconfDevice) controller.connectDevice(mockDeviceId);
+ device.setNcSessionImpl(MockNetconfSessionEa1000.class);
+ mseaUniEvcServiceSvc = new MockMseaUniEvcServiceManager();
+ mseaUniEvcServiceSvc.activate();
+ meterProvider = new TestEA1000MeterProvider(controller, mseaUniEvcServiceSvc);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testPerformMeterOperationDeviceIdMeterAdd() {
+ DeviceId mockDeviceId = DeviceId.deviceId("netconf:1.2.3.4:830");
+
+ Band cbsBand = DefaultBand.builder()
+ .ofType(Band.Type.REMARK) //Committed - CIR & CBS
+ .withRate(37500L)
+ .burstSize(2000)
+ .dropPrecedence((short) 0)
+ .build();
+
+ Band ebsBand = DefaultBand.builder()
+ .ofType(Band.Type.DROP) //Excess - EIR & EBS
+ .withRate(50000L) //The rate at which we drop - for EA 1000 subtract CIR to get EIR
+ .burstSize(3000) //The burst rate to drop at
+ .build();
+
+ Meter.Builder mBuilder = DefaultMeter.builder()
+ .forDevice(mockDeviceId)
+ .withId(MeterId.meterId(1))
+ .fromApp(new DefaultApplicationId(101, "unit.test"))
+ .burst()
+ .withUnit(Unit.KB_PER_SEC)
+ .withBands(new HashSet<Band>() { { add(cbsBand); add(ebsBand); } });
+
+ MeterOperation meterOp = new MeterOperation(mBuilder.build(), Type.ADD);
+
+ meterProvider.performMeterOperation(mockDeviceId, meterOp);
+ //The NETCONF XML generated by this matches the pattern
+ // sampleXmlRegexEditConfigBwpGroup1
+ // in MockNetconfSession
+ }
+
+ @Test
+ public void testPerformMeterOperationDeviceIdMeterRemove() {
+ DeviceId mockDeviceId = DeviceId.deviceId("netconf:1.2.3.4:830");
+
+ Band cbsBand = DefaultBand.builder()
+ .ofType(Band.Type.REMARK) //Committed - CIR & CBS
+ .withRate(37500L)
+ .burstSize(2000)
+ .dropPrecedence((short) 0)
+ .build();
+
+ Meter.Builder mBuilder = DefaultMeter.builder()
+ .forDevice(mockDeviceId)
+ .withId(MeterId.meterId(1))
+ .fromApp(new DefaultApplicationId(101, "unit.test"))
+ .burst()
+ .withBands(new HashSet<Band>() { { add(cbsBand); } });
+
+ MeterOperation meterOp = new MeterOperation(mBuilder.build(), Type.REMOVE);
+
+ meterProvider.performMeterOperation(mockDeviceId, meterOp);
+ //The NETCONF XML generated by this matches the pattern
+ // sampleXmlRegexEditConfigBwpGroup1
+ // in MockNetconfSession
+ }
+
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/MicrosemiDriversLoaderTest.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/MicrosemiDriversLoaderTest.java
new file mode 100644
index 0000000..a53c6e3
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/MicrosemiDriversLoaderTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import org.junit.Before;
+import org.onosproject.net.driver.AbstractDriverLoaderTest;
+
+
+/**
+ * Microsemi drivers loader test.
+ */
+public class MicrosemiDriversLoaderTest extends AbstractDriverLoaderTest {
+
+ @Before
+ public void setUp() {
+ loader = new MicrosemiDriversLoader();
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/MockEa1000DriverHandler.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/MockEa1000DriverHandler.java
new file mode 100644
index 0000000..78a9d32
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/MockEa1000DriverHandler.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onosproject.core.CoreService;
+import org.onosproject.drivers.microsemi.yang.MockMseaSaFilteringManager;
+import org.onosproject.drivers.microsemi.yang.MockMseaUniEvcServiceManager;
+import org.onosproject.drivers.microsemi.yang.MockNetconfSessionEa1000;
+import org.onosproject.drivers.microsemi.yang.MseaSaFilteringNetconfService;
+import org.onosproject.drivers.microsemi.yang.MseaUniEvcServiceNetconfService;
+import org.onosproject.drivers.netconf.MockCoreService;
+import org.onosproject.drivers.netconf.MockNetconfController;
+import org.onosproject.drivers.netconf.MockNetconfDevice;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.DefaultDriver;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.flow.FlowRuleProgrammable;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfException;
+
+/**
+ * A Mock implementation of the DriverHandler to facilitate unit tests.
+ *
+ * This brings in the implementations of MockMseaSaFilteringManager, MockMseaUniEvcServiceManager,
+ * MockCoreService, MockNetconfDevice and MockNetconfSessionEa1000
+ */
+public class MockEa1000DriverHandler implements DriverHandler {
+
+ private static final String MICROSEMI_DRIVERS = "com.microsemi.drivers";
+
+ private DriverData mockDriverData;
+
+ private NetconfController ncc;
+ private MockMseaSaFilteringManager mseaSaFilteringService;
+ private MockMseaUniEvcServiceManager mseaUniEvcService;
+ private CoreService coreService;
+
+ public MockEa1000DriverHandler() throws NetconfException {
+ Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours =
+ new HashMap<Class<? extends Behaviour>, Class<? extends Behaviour>>();
+ behaviours.put(FlowRuleProgrammable.class, FlowRuleProgrammable.class);
+
+ Map<String, String> properties = new HashMap<String, String>();
+
+ Driver mockDriver =
+ new DefaultDriver("mockDriver", null, "ONOSProject", "1.0.0", "1.0.0", behaviours, properties);
+ DeviceId mockDeviceId = DeviceId.deviceId("netconf:1.2.3.4:830");
+ mockDriverData = new DefaultDriverData(mockDriver, mockDeviceId);
+
+
+ ncc = new MockNetconfController();
+ MockNetconfDevice device = (MockNetconfDevice) ncc.connectDevice(mockDeviceId);
+ device.setNcSessionImpl(MockNetconfSessionEa1000.class);
+
+ mseaSaFilteringService = new MockMseaSaFilteringManager();
+ mseaSaFilteringService.activate();
+
+ mseaUniEvcService = new MockMseaUniEvcServiceManager();
+ mseaUniEvcService.activate();
+
+ coreService = new MockCoreService();
+ coreService.registerApplication(MICROSEMI_DRIVERS);
+ }
+
+ @Override
+ public Driver driver() {
+ return mockDriverData.driver();
+ }
+
+ @Override
+ public DriverData data() {
+ return mockDriverData;
+ }
+
+ @Override
+ public <T extends Behaviour> T behaviour(Class<T> behaviourClass) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public <T> T get(Class<T> serviceClass) {
+ if (serviceClass.equals(NetconfController.class)) {
+ return (T) ncc;
+
+ } else if (serviceClass.equals(MseaSaFilteringNetconfService.class)) {
+ return (T) mseaSaFilteringService;
+
+ } else if (serviceClass.equals(MseaUniEvcServiceNetconfService.class)) {
+ return (T) mseaUniEvcService;
+
+ } else if (serviceClass.equals(CoreService.class)) {
+ return (T) coreService;
+
+ }
+
+ return null;
+ }
+
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/RpcResultParserTest.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/RpcResultParserTest.java
new file mode 100644
index 0000000..64dd80e
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/RpcResultParserTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import static org.junit.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.junit.Test;
+
+public class RpcResultParserTest {
+
+ private static final String SAMPLE1_XML = "/systemReply-Sample1.xml";
+ private static final String SAMPLE2_XML = "/systemReply-Sample2.xml";
+
+ @Test
+ public void testSerialNumber1() {
+ String serialNumberReply = loadXml(SAMPLE1_XML);
+ String serialNumber = RpcResultParser.parseXml(serialNumberReply, "serial-number");
+ assertEquals("Eagle Simulator.", serialNumber);
+ }
+
+ @Test
+ public void testSerialNumber2() {
+ String serialNumberReply = loadXml(SAMPLE2_XML);
+ String serialNumber = RpcResultParser.parseXml(serialNumberReply, "serial-number");
+ assertEquals(null, serialNumber);
+ }
+
+ @Test
+ public void testOsRelease1() {
+ String osReleaseReply = loadXml(SAMPLE1_XML);
+ String osRelease = RpcResultParser.parseXml(osReleaseReply, "os-release");
+ assertEquals("2.6.33-arm1-MSEA1000--00326-g643be76.x.0.0.212", osRelease);
+ }
+
+ @Test
+ public void testOsRelease2() {
+ String osReleaseReply = loadXml(SAMPLE2_XML);
+ String osRelease = RpcResultParser.parseXml(osReleaseReply, "os-release");
+ assertEquals(null, osRelease);
+ }
+
+ @Test
+ public void testLongitude() {
+ String longitudeReply = loadXml(SAMPLE1_XML);
+ String longitudeStr = RpcResultParser.parseXml(longitudeReply, "longitude");
+ assertEquals("-8.4683990", longitudeStr);
+ }
+
+ @Test
+ public void testLatitude() {
+ String latitudeReply = loadXml(SAMPLE1_XML);
+ String latitudeStr = RpcResultParser.parseXml(latitudeReply, "latitude");
+ assertEquals("51.9036140", latitudeStr);
+ }
+
+
+ private static String loadXml(final String fileName) {
+
+ InputStream inputStream = RpcResultParserTest.class.getResourceAsStream(fileName);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+ StringBuilder result = new StringBuilder();
+ try {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ result.append(line);
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return result.toString();
+ }
+}
\ No newline at end of file
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/TestEA1000MeterProvider.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/TestEA1000MeterProvider.java
new file mode 100644
index 0000000..e56e121
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/TestEA1000MeterProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi;
+
+import org.onosproject.drivers.microsemi.yang.MseaUniEvcServiceNetconfService;
+import org.onosproject.netconf.NetconfController;
+
+public class TestEA1000MeterProvider extends EA1000MeterProvider {
+
+ public TestEA1000MeterProvider(NetconfController controller,
+ MseaUniEvcServiceNetconfService mseaUniEvcServiceSvc) {
+ this.controller = controller;
+ this.mseaUniEvcServiceSvc = mseaUniEvcServiceSvc;
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/CeVlanMapUtilsTest.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/CeVlanMapUtilsTest.java
new file mode 100644
index 0000000..c7b3e72
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/CeVlanMapUtilsTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.onosproject.drivers.microsemi.yang.utils.CeVlanMapUtils;
+
+public class CeVlanMapUtilsTest {
+
+ @Test
+ public void testGetVlanSet() {
+ Short[] vlanArray = CeVlanMapUtils.getVlanSet("101:102");
+ assertEquals(2, vlanArray.length);
+
+ vlanArray = CeVlanMapUtils.getVlanSet("101:103,107,110:115");
+ assertEquals(10, vlanArray.length);
+
+ vlanArray = CeVlanMapUtils.getVlanSet("1:4095");
+ assertEquals(4095, vlanArray.length);
+ }
+
+ @Test
+ public void testVlanListAsString() {
+ String ceVlanMap = CeVlanMapUtils.vlanListAsString(new Short[]{101, 102, 103});
+ assertEquals("101:103", ceVlanMap);
+
+ ceVlanMap = CeVlanMapUtils.vlanListAsString(new Short[]{0, 101, 104, 108});
+ assertEquals("101,104,108", ceVlanMap);
+ }
+
+ @Test
+ public void testAddtoCeVlanMap() {
+ String ceVlanMap = CeVlanMapUtils.addtoCeVlanMap("101:102", (short) 103);
+ assertEquals("101:103", ceVlanMap);
+
+ ceVlanMap = CeVlanMapUtils.addtoCeVlanMap("101:102", (short) 0);
+ assertEquals("101:102", ceVlanMap);
+
+ ceVlanMap = CeVlanMapUtils.addtoCeVlanMap("101:102", (short) 104);
+ assertEquals("101:102,104", ceVlanMap);
+ }
+
+ @Test
+ public void testRemoveZeroIfPossible() {
+ String ceVlanMap = CeVlanMapUtils.removeZeroIfPossible("101:102");
+ assertEquals("101:102", ceVlanMap);
+
+ ceVlanMap = CeVlanMapUtils.removeZeroIfPossible("0,101:102");
+ assertEquals("101:102", ceVlanMap);
+
+ ceVlanMap = CeVlanMapUtils.removeZeroIfPossible("0");
+ assertEquals("0", ceVlanMap);
+ }
+
+ @Test
+ public void testRemoveFromCeVlanMap() {
+ String ceVlanMap = CeVlanMapUtils.removeFromCeVlanMap("101:102", (short) 102);
+ assertEquals("101", ceVlanMap);
+
+ ceVlanMap = CeVlanMapUtils.removeFromCeVlanMap("101:103", (short) 102);
+ assertEquals("101,103", ceVlanMap);
+ }
+
+ @Test
+ public void testCombineVlanSets() {
+ assertEquals("101:104", CeVlanMapUtils.combineVlanSets("101:102", "103:104"));
+
+ assertEquals("101:103", CeVlanMapUtils.combineVlanSets("101:102", "103"));
+
+ assertEquals("101:102,104", CeVlanMapUtils.combineVlanSets("101:102", "104"));
+
+ assertEquals("99,101:102", CeVlanMapUtils.combineVlanSets("101:102", "99"));
+
+ assertEquals("101:102", CeVlanMapUtils.combineVlanSets("101:102", "0"));
+
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/IetfSystemManagerTest.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/IetfSystemManagerTest.java
new file mode 100644
index 0000000..098ecdd
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/IetfSystemManagerTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.UncheckedIOException;
+import java.text.ParseException;
+import java.time.OffsetDateTime;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.drivers.microsemi.yang.impl.IetfSystemManager;
+import org.onosproject.netconf.NetconfDeviceInfo;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.system.AugmentedSysSystem;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.system.DefaultAugmentedSysSystem;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.systemstate.platform.AugmentedSysPlatform;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.IetfSystem;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.IetfSystemOpParam;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.ietfsystem.DefaultSystem;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.ietfsystem.System;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.ietfsystem.system.DefaultClock;
+import org.onosproject.yang.gen.v1.ietfsystem.rev20140806.ietfsystem.system.clock.timezone.DefaultTimezoneName;
+import org.onosproject.yang.gen.v1.ietfsystemmicrosemi.rev20160505.ietfsystemmicrosemi.systemstate.platform.DefaultAugmentedSysPlatform;
+
+public class IetfSystemManagerTest {
+
+ IetfSystemManager sysSvc = null;
+ NetconfSession session;
+
+ @Before
+ public void setUp() throws Exception {
+ try {
+ sysSvc = new MockIetfSystemManager();
+ sysSvc.activate();
+ } catch (UncheckedIOException e) {
+ fail(e.getMessage());
+ }
+ NetconfDeviceInfo deviceInfo = new NetconfDeviceInfo("netconf", "netconf", Ip4Address.valueOf("1.2.3.4"), 830);
+ session = new MockNetconfSessionEa1000(deviceInfo);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ sysSvc.deactivate();
+ }
+
+ @Test
+ public void testGetIetfSystemSession() throws NetconfException {
+ System system = new DefaultSystem();
+ system.clock(new DefaultClock());
+
+ IetfSystemOpParam sampleSystem = new IetfSystemOpParam();
+ sampleSystem.system(system);
+
+ IetfSystem sys = sysSvc.getIetfSystem(sampleSystem, session);
+ assertNotNull(sys);
+
+ assertEquals(sys.system().clock().timezone().getClass(), DefaultTimezoneName.class);
+ DefaultTimezoneName tzName = (DefaultTimezoneName) sys.system().clock().timezone();
+ assertEquals("Etc/UTC", tzName.timezoneName().string());
+ }
+
+ @Test
+ public void testGetIetfSystemInit() throws NetconfException {
+
+ IetfSystem sys = sysSvc.getIetfSystemInit(session);
+ assertNotNull(sys);
+ assertNotNull(sys.system());
+
+ AugmentedSysSystem sysSystem = (AugmentedSysSystem) sys.system().augmentation(DefaultAugmentedSysSystem.class);
+
+ assertEquals("-8.4683990", sysSystem.longitude().toPlainString());
+ assertEquals("51.9036140", sysSystem.latitude().toPlainString());
+ assertEquals("4.4.0-53-generic", sys.systemState().platform().osRelease());
+
+ AugmentedSysPlatform sysSystemState =
+ (AugmentedSysPlatform) sys.systemState().platform().augmentation(DefaultAugmentedSysPlatform.class);
+
+ assertEquals("Eagle Simulator.", sysSystemState.deviceIdentification().serialNumber());
+ }
+
+ @Test
+ public void testSetCurrentDatetime() throws NetconfException, ParseException {
+ sysSvc.setCurrentDatetime(OffsetDateTime.now(), session);
+ //Look at MockNetconfSessionEa1000::sampleXmlRegexSetCurrentDatetime() for catching an error
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockIetfSystemManager.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockIetfSystemManager.java
new file mode 100644
index 0000000..f035c70
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockIetfSystemManager.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+
+import org.onosproject.drivers.microsemi.yang.impl.IetfSystemManager;
+import org.onosproject.yang.MockYangRuntimeManager;
+import org.onosproject.yang.runtime.impl.DefaultYangModelRegistry;
+import org.onosproject.yang.serializers.xml.MockYangSerializerContext;
+import org.onosproject.yang.serializers.xml.XmlSerializer;
+
+public class MockIetfSystemManager extends IetfSystemManager {
+
+ @Override
+ public void activate() {
+ yCtx = new MockYangSerializerContext();
+ xSer = new XmlSerializer();
+ yangModelRegistry = new MockYangRuntimeManager();
+ ((MockYangRuntimeManager) yangModelRegistry).setModelRegistry(
+ (DefaultYangModelRegistry) yCtx.getContext());
+ ((MockYangRuntimeManager) yangModelRegistry).activate();
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockMseaCfmManager.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockMseaCfmManager.java
new file mode 100644
index 0000000..fb20697
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockMseaCfmManager.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import org.onosproject.drivers.microsemi.yang.impl.MseaCfmManager;
+import org.onosproject.yang.MockYangRuntimeManager;
+import org.onosproject.yang.runtime.impl.DefaultYangModelRegistry;
+import org.onosproject.yang.serializers.xml.MockYangSerializerContext;
+import org.onosproject.yang.serializers.xml.XmlSerializer;
+
+public class MockMseaCfmManager extends MseaCfmManager {
+
+ @Override
+ public void activate() {
+ yCtx = new MockYangSerializerContext();
+ xSer = new XmlSerializer();
+ yangModelRegistry = new MockYangRuntimeManager();
+ ((MockYangRuntimeManager) yangModelRegistry).setModelRegistry(
+ (DefaultYangModelRegistry) yCtx.getContext());
+ ((MockYangRuntimeManager) yangModelRegistry).activate();
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockMseaSaFilteringManager.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockMseaSaFilteringManager.java
new file mode 100644
index 0000000..a2de180
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockMseaSaFilteringManager.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import org.onosproject.drivers.microsemi.yang.impl.MseaSaFilteringManager;
+import org.onosproject.yang.MockYangRuntimeManager;
+import org.onosproject.yang.runtime.impl.DefaultYangModelRegistry;
+import org.onosproject.yang.serializers.xml.MockYangSerializerContext;
+import org.onosproject.yang.serializers.xml.XmlSerializer;
+
+public class MockMseaSaFilteringManager extends MseaSaFilteringManager {
+
+ @Override
+ public void activate() {
+ yCtx = new MockYangSerializerContext();
+ xSer = new XmlSerializer();
+ yangModelRegistry = new MockYangRuntimeManager();
+ ((MockYangRuntimeManager) yangModelRegistry).setModelRegistry(
+ (DefaultYangModelRegistry) yCtx.getContext());
+ ((MockYangRuntimeManager) yangModelRegistry).activate();
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockMseaUniEvcServiceManager.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockMseaUniEvcServiceManager.java
new file mode 100644
index 0000000..e7921c2
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockMseaUniEvcServiceManager.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import org.onosproject.drivers.microsemi.yang.impl.MseaUniEvcServiceManager;
+import org.onosproject.yang.MockYangRuntimeManager;
+import org.onosproject.yang.runtime.impl.DefaultYangModelRegistry;
+import org.onosproject.yang.serializers.xml.MockYangSerializerContext;
+import org.onosproject.yang.serializers.xml.XmlSerializer;
+
+public class MockMseaUniEvcServiceManager extends MseaUniEvcServiceManager {
+ @Override
+ public void activate() {
+ yCtx = new MockYangSerializerContext();
+ xSer = new XmlSerializer();
+ yangModelRegistry = new MockYangRuntimeManager();
+ ((MockYangRuntimeManager) yangModelRegistry).setModelRegistry(
+ (DefaultYangModelRegistry) yCtx.getContext());
+ ((MockYangRuntimeManager) yangModelRegistry).activate();
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockNetconfSessionEa1000.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockNetconfSessionEa1000.java
new file mode 100644
index 0000000..fc6da58
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MockNetconfSessionEa1000.java
@@ -0,0 +1,1034 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Pattern;
+
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfDeviceInfo;
+import org.onosproject.netconf.NetconfDeviceOutputEventListener;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.netconf.TargetConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MockNetconfSessionEa1000 implements NetconfSession {
+ private static final Logger log = LoggerFactory
+ .getLogger(MockNetconfSessionEa1000.class);
+
+ private static final String MESSAGE_ID_STRING = "message-id";
+ private static final String EQUAL = "=";
+ private static final String RPC_OPEN = "<rpc ";
+ private static final String RPC_CLOSE = "</rpc>";
+ private static final String GET_OPEN = "<get>";
+ private static final String GET_CLOSE = "</get>";
+ private static final String NEW_LINE = "\n";
+ private static final String SUBTREE_FILTER_OPEN = "<filter type=\"subtree\">";
+ private static final String SUBTREE_FILTER_CLOSE = "</filter>";
+ private static final String WITH_DEFAULT_OPEN = "<with-defaults ";
+ private static final String WITH_DEFAULT_CLOSE = "</with-defaults>";
+ private static final String EDIT_CONFIG_OPEN = "<edit-config>";
+ private static final String EDIT_CONFIG_CLOSE = "</edit-config>";
+ private static final String TARGET_OPEN = "<target>";
+ private static final String TARGET_CLOSE = "</target>";
+ private static final String DEFAULT_OPERATION_OPEN = "<default-operation>";
+ private static final String DEFAULT_OPERATION_CLOSE = "</default-operation>";
+ private static final String CONFIG_OPEN = "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
+ private static final String CONFIG_CLOSE = "</config>";
+
+ private static final String ENDPATTERN = "]]>]]>";
+ private static final String XML_HEADER =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ private static final String NETCONF_BASE_NAMESPACE =
+ "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"";
+ private static final String NETCONF_WITH_DEFAULTS_NAMESPACE =
+ "xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\"";
+
+
+ private Pattern sampleXmlRegex1 =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<get>).*(<filter).*"
+ + "(<system).*(<clock/>).*(</system>).*(</filter>)*.(</get>).*(</rpc).*(]]>){2}",
+ Pattern.DOTALL);
+
+ private Pattern sampleXmlRegex2 =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<get>).*(<filter).*(<system-state).*(</system-state>).*"
+ + "(<system).*(</system>).*(</filter>).*(</get>).*(</rpc).*(]]>){2}",
+ Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexSaFiltering =
+ Pattern.compile("(<\\?xml).*"
+ + "(<rpc).*(<get>).*"
+ + "(<filter type=\"subtree\">).*(<source-ipaddress-filtering).*"
+ + "(</filter>).*(</get>).*(</rpc>).*"
+ + "(]]>){2}", Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexEditConfigSaFilt =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<edit-config>).*"
+ + "(<target><running/></target>).*(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">).*"
+ + "(<source-ipaddress-filtering).*(<interface-eth0>).*"
+ + "(<source-address-range>).*(<range-id>).*(</range-id>).*"
+ + "(<name>).*(</name>).*(<ipv4-address-prefix>).*(</ipv4-address-prefix>).*"
+ + "(</source-address-range>).*(</interface-eth0>)*(</source-ipaddress-filtering>).*"
+ + "(</config>).*(</edit-config>).*(</rpc>).*(]]>){2}", Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexEditDeleteSaFilt =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<edit-config>)\\R?"
+ + "(<target><running/></target>)\\R?"
+ + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+ + "(<source-ipaddress-filtering "
+ + "xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-sa-filtering\">)\\R?"
+ + "(<interface-eth0>)\\R?"
+ + "((<source-address-range nc:operation=\"delete\">)\\R?"
+ + "(<range-id>)[0-9]*(</range-id>)\\R?"
+ + "((<name>)[a-zA-Z0-9]*(</name>))?\\R?"
+ + "((<ipv4-address-prefix>)[0-9\\\\./]*(</ipv4-address-prefix>))?\\R?"
+ + "(</source-address-range>))++\\R?"
+ + "(</interface-eth0>)\\R?"
+ + "(</source-ipaddress-filtering>)\\R?"
+ + "(</config>)\\R?"
+ + "(</edit-config>)\\R?(</rpc>).*(]]>){2}", Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexUniEvc =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<get-config>)\\R?"
+ + "(<source>)\\R?(<running/>)\\R?(</source>)\\R?"
+ + "(<filter type=\"subtree\">)\\R?"
+ + "(<mef-services "
+ + "xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\"/>)\\R?"
+ + "(</filter>)\\R?(</get-config>)\\R?(</rpc>)\\R?(]]>){2}", Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexUniEvcUni =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<get-config>)\\R?"
+ + "(<source>)\\R?(<running/>)\\R?(</source>)\\R?"
+ + "(<filter type=\"subtree\">)\\R?"
+ + "(<mef-services "
+ + "xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\">)\\R?"
+ + "(<uni/>)\\R?"
+ + "(</mef-services>)\\R?"
+ + "(</filter>)\\R?(</get-config>)\\R?(</rpc>)\\R?(]]>){2}", Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexEditConfigUni1Evc =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<edit-config>)\\R?"
+ + "(<target><running/></target>)\\R?"
+ + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+ + "(<mef-services).*(<uni>)\\R?(<name>).*(</name>)\\R?"
+ + "(<evc>)\\R?(<evc-index>).*(</evc-index>)\\R?(<name>).*(</name>)\\R?"
+ + "(<evc-per-uni>)\\R?"
+ + "(<evc-per-uni-c>)\\R?"
+ + "(<ce-vlan-map>)[0-9]*(</ce-vlan-map>)\\R?"
+ + "(<ingress-bwp-group-index>)[0-9]*(</ingress-bwp-group-index>)\\R?"
+ + "(<tag-push>)\\R?(<push-tag-type>)pushStag(</push-tag-type>)\\R?"
+ + "(<outer-tag-vlan>)[0-9]*(</outer-tag-vlan>)\\R?(</tag-push>)\\R?"
+ + "((<flow-mapping>)\\R?"
+ + "(<ce-vlan-id>)[0-9]*(</ce-vlan-id>)\\R?"
+ + "(<flow-id>)[0-9]*(</flow-id>)\\R?"
+ + "(</flow-mapping>)\\R?)*"
+ + "(</evc-per-uni-c>)\\R?"
+ + "(<evc-per-uni-n>)\\R?"
+ + "(<ce-vlan-map>)[0-9\\:\\,]*(</ce-vlan-map>)\\R?"
+ + "(<ingress-bwp-group-index>)[0-9]*(</ingress-bwp-group-index>)\\R?"
+ + "(<tag-pop).*"
+ + "((<flow-mapping>)\\R?"
+ + "(<ce-vlan-id>)[0-9]*(</ce-vlan-id>)\\R?"
+ + "(<flow-id>)[0-9]*(</flow-id>)\\R?"
+ + "(</flow-mapping>)\\R?)*"
+ + "(</evc-per-uni-n>)\\R?"
+ + "(</evc-per-uni>)\\R?"
+ + "(</evc>)\\R?"
+ + "(</uni>)\\R?"
+ + "(</mef-services>)\\R?"
+ + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?(]]>){2}", Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexEditConfigUni2Evc =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<edit-config>)\\R?"
+ + "(<target><running/></target>)\\R?"
+ + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+ + "(<mef-services).*(<uni>)\\R?(<name>)[0-9a-zA-Z\\-\\:]*(</name>)\\R?"
+ + "(<evc>)\\R?(<evc-index>)[0-9]*(</evc-index>)\\R?(<name>)[0-9a-zA-Z\\-\\:]*(</name>)\\R?"
+ + "(<evc-per-uni>)\\R?"
+ + "(<evc-per-uni-c>)\\R?"
+ + "(<ce-vlan-map>)[0-9\\:\\,]*(</ce-vlan-map>)\\R?"
+ + "(<ingress-bwp-group-index>)[0-9]*(</ingress-bwp-group-index>)\\R?"
+ + "(</evc-per-uni-c>)\\R?"
+ + "(<evc-per-uni-n>)\\R?"
+ + "(<ce-vlan-map>)[0-9\\:\\,]*(</ce-vlan-map>)\\R?"
+ + "(<ingress-bwp-group-index>)[0-9]*(</ingress-bwp-group-index>)\\R?"
+ + "(<evc-per-uni-service-type>).*(</evc-per-uni-service-type>)\\R?"
+ + "(<tag-push>)\\R?(<push-tag-type>)pushStag(</push-tag-type>)\\R?(<outer-tag-vlan>).*"
+ + "(</outer-tag-vlan>)\\R?(</tag-push>)\\R?"
+ + "(</evc-per-uni-n>)\\R?"
+ + "(</evc-per-uni>)\\R?"
+ + "(</evc>)\\R?"
+ + "(<evc>)\\R?(<evc-index>)[0-9]*(</evc-index>)\\R?(<name>)[0-9a-zA-Z\\-\\:]*(</name>)\\R?"
+ + "(<evc-per-uni>)\\R?"
+ + "(<evc-per-uni-c>)\\R?"
+ + "(<ce-vlan-map>)[0-9\\:\\,]*(</ce-vlan-map>)\\R?"
+ + "(<ingress-bwp-group-index>)[0-9]*(</ingress-bwp-group-index>)\\R?"
+ + "(</evc-per-uni-c>)\\R?"
+ + "(<evc-per-uni-n>)\\R?"
+ + "(<ce-vlan-map>)[0-9\\:\\,]*(</ce-vlan-map>)\\R?"
+ + "(<ingress-bwp-group-index>)[0-9]*(</ingress-bwp-group-index>)\\R?"
+ + "(</evc-per-uni-n>)\\R?"
+ + "(</evc-per-uni>)\\R?"
+ + "(</evc>)\\R?(</uni>).*"
+ + "(</mef-services>)\\R?"
+ + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?(]]>){2}", Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexEditConfigUniProfiles =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<edit-config>).*"
+ + "(<target><running/></target>).*(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">).*"
+ + "(<mef-services).*(<profiles>).*"
+ + "(<bwp-group>).*(<group-index>).*(</group-index>).*(</bwp-group>).*"
+ + "(<bwp-group>).*(<group-index>).*(</group-index>).*"
+ + "(<bwp>).*(<cos-index>).*(</cos-index>).*(<color-mode>).*(</color-mode>).*(</bwp>).*"
+ + "(<bwp>).*(<cos-index>).*(</cos-index>).*(<color-mode>).*(</color-mode>).*(</bwp>).*"
+ + "(</bwp-group>).*"
+ + "(</profiles>).*(</mef-services>).*"
+ + "(</config>).*(</edit-config>).*(</rpc>).*(]]>){2}", Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexEditConfigEvcDelete =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<edit-config>).*"
+ + "(<target><running/></target>).*(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">).*"
+ + "(<mef-services).*"
+ + "(<uni>).*"
+ + "(<evc nc:operation=\"delete\">).*(<evc-index>).*(</evc-index>).*(</evc>).*"
+ + "(</uni>).*"
+ + "(</mef-services>).*"
+ + "(</config>).*(</edit-config>).*(</rpc>).*(]]>){2}", Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexGetConfigCeVlanMapsEvc =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<get-config>)\\R?"
+ + "(<source>)\\R?(<running/>)\\R?(</source>)\\R?"
+ + "(<filter type=\"subtree\">)\\R?"
+ + "(<mef-services).*"
+ + "(<uni>)\\R?"
+ + "(<evc>)\\R?"
+ + "(<evc-index/>)\\R?"
+ + "(<evc-per-uni>)\\R?"
+ + "(<evc-per-uni-c><ce-vlan-map/><flow-mapping/><ingress-bwp-group-index/></evc-per-uni-c>)\\R?"
+ + "(<evc-per-uni-n><ce-vlan-map/><flow-mapping/><ingress-bwp-group-index/></evc-per-uni-n>)\\R?"
+ + "(</evc-per-uni>)\\R?"
+ + "(</evc>)\\R?"
+ + "(</uni>)\\R?"
+ + "(</mef-services>)\\R?"
+ + "(</filter>)\\R?"
+ + "(</get-config>)\\R?"
+ + "(</rpc>)\\R?"
+ + "(]]>){2}", Pattern.DOTALL);
+
+ //For test testRemoveEvcUniFlowEntries()
+ private Pattern sampleXmlRegexEditConfigCeVlanMapReplace =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<edit-config>).*"
+ + "(<target><running/></target>).*"
+ + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">).*"
+ + "(<mef-services xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\">).*"
+ + "(<uni>).*"
+ + "(<evc nc:operation=\"delete\">).*(<evc-index>.*</evc-index>).*(</evc>).*"
+ + "(<evc nc:operation=\"delete\">).*(<evc-index>.*</evc-index>).*(</evc>).*"
+ + "(<evc>).*(<evc-index>).*(</evc-index>).*(<evc-per-uni>).*"
+ + "(<evc-per-uni-c>).*"
+ + "(<ce-vlan-map nc:operation=\"replace\">).*(</ce-vlan-map>).*"
+ + "(<flow-mapping nc:operation=\"delete\">).*(<ce-vlan-id>).*(</ce-vlan-id>).*(</flow-mapping>).*"
+ + "(</evc-per-uni-c>).*"
+ + "(<evc-per-uni-n>).*"
+ + "(<ce-vlan-map nc:operation=\"replace\">).*(</ce-vlan-map>).*"
+ + "(<flow-mapping nc:operation=\"delete\">).*(<ce-vlan-id>).*(</ce-vlan-id>).*(</flow-mapping>).*"
+ + "(</evc-per-uni-n>).*"
+ + "(</evc-per-uni>).*(</evc>).*"
+ + "(<evc>).*(<evc-index>).*(</evc-index>).*(<evc-per-uni>).*"
+ + "(<evc-per-uni-c>).*"
+ + "(<ce-vlan-map nc:operation=\"replace\">).*(</ce-vlan-map>).*"
+ + "(<flow-mapping nc:operation=\"delete\">).*(<ce-vlan-id>).*(</ce-vlan-id>).*(</flow-mapping>).*"
+ + "(</evc-per-uni-c>).*"
+ + "(<evc-per-uni-n>).*"
+ + "(<ce-vlan-map nc:operation=\"replace\">).*(</ce-vlan-map>).*"
+ + "(<flow-mapping nc:operation=\"delete\">).*(<ce-vlan-id>).*(</ce-vlan-id>).*(</flow-mapping>).*"
+ + "(</evc-per-uni-n>).*"
+ + "(</evc-per-uni>).*(</evc>).*"
+ + "(</uni>).*(</mef-services>).*"
+ + "(</config>).*(</edit-config>).*(</rpc>).*(]]>){2}", Pattern.DOTALL);
+
+
+ //For testPerformMeterOperationDeviceIdMeterAdd()
+ private Pattern sampleXmlRegexEditConfigBwpGroup1 =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<edit-config>)\\R?"
+ + "(<target>\\R?<running/>\\R?</target>)\\R?"
+ + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+ + "(<mef-services "
+ + "xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\">)\\R?"
+ + "(<profiles>)\\R?"
+ + "(<bwp-group>)\\R?"
+ + "(<group-index>)[0-9]*(</group-index>)\\R?"
+ + "(<bwp>)\\R?"
+ + "(<cos-index>)[0-9]*(</cos-index>)\\R?"
+ + "(<name>).*(</name>)\\R?"
+ + "(<committed-information-rate>)[0-9]*(</committed-information-rate>)\\R?"
+ + "(<committed-burst-size>)[0-9]*(</committed-burst-size>)\\R?"
+ + "(<excess-information-rate>)[0-9]*(</excess-information-rate>)\\R?"
+ + "(<excess-burst-size>)[0-9]*(</excess-burst-size>)\\R?"
+ + "(</bwp>)\\R?"
+ + "(</bwp-group>)\\R?"
+ + "(<cos>)\\R?"
+ + "(<cos-index>)[0-9](</cos-index>)\\R?"
+ + "(<name>).*(</name>)\\R?"
+ + "(<outgoing-cos-value>)[0-9]*(</outgoing-cos-value>)\\R?"
+ + "(<color-aware>true</color-aware>)\\R?"
+ + "(<color-forward>true</color-forward>)\\R?"
+ + "(<evc-cos-type-all-8-prio-to-1-evc-color>)\\R?"
+ + "(<evc-all-8-color-to>green</evc-all-8-color-to>)\\R?"
+ + "(</evc-cos-type-all-8-prio-to-1-evc-color>)\\R?"
+ + "(</cos>)\\R?"
+ + "(</profiles>)\\R?"
+ + "(</mef-services>)\\R?"
+ + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?(]]>){2}", Pattern.DOTALL);
+
+ //For testPerformMeterOperationDeviceIdMeterRemove()
+ private Pattern sampleXmlRegexEditConfigBwpGroup1Delete =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<edit-config>)\\R?"
+ + "(<target>\\R?<running/>\\R?</target>)\\R?"
+ + "(<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">)\\R?"
+ + "(<mef-services xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\">)\\R?"
+ + "(<profiles>)\\R?"
+ + "((<bwp-group nc:operation=\"delete\">)\\R?"
+ + "(<group-index>)[0-9]*(</group-index>)\\R?"
+ + "(<bwp>.*</bwp>)?"
+ + "(</bwp-group>))++\\R?"
+ + "(</profiles>)\\R?"
+ + "(</mef-services>)\\R?"
+ + "(</config>)\\R?(</edit-config>)\\R?(</rpc>)\\R?(]]>){2}", Pattern.DOTALL);
+
+ private Pattern sampleXmlRegexSetCurrentDatetime =
+ Pattern.compile("(<\\?xml).*(<rpc).*"
+ + "(<set-current-datetime xmlns=\"urn:ietf:params:xml:ns:yang:ietf-system\">)\\R?"
+ + "(<current-datetime>)"
+ + "[0-9]{4}-[0-9]{2}-[0-9]{2}(T)[0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{2}:[0-9]{2}"
+ + "(</current-datetime>)\\R?"
+ + "(</set-current-datetime>)\\R?"
+ + "(</rpc>)\\R?(]]>){2}", Pattern.DOTALL);
+
+ //For testGetConfigMseaCfmEssentials
+ private Pattern sampleXmlRegexGetMseaCfmEssentials =
+ Pattern.compile("(<\\?xml).*(<rpc).*(<get>)\\R?"
+ + "(<filter type=\"subtree\">)\\R?"
+ + "(<mef-cfm).*"
+ + "(<maintenance-domain>)\\R?"
+ + "(<id/>)\\R?"
+ + "(<name>)([a-zA-Z0-9\\-:\\.]){1,48}(</name>)\\R?"
+ + "(<md-level/>)\\R?"
+ + "(<maintenance-association>)\\R?"
+ + "(<id/>)\\R?"
+ + "(<name>)([a-zA-Z0-9\\-:\\.]){1,48}(</name>)\\R?"
+ + "(<ccm-interval>)[0-9]{1,3}(ms</ccm-interval>)\\R?"
+ + "(<remote-meps/>)\\R?"
+ + "(<component-list/>)\\R?"
+ + "(<maintenance-association-end-point>)\\R?"
+ + "(<mep-identifier>)[0-9]{1,4}(</mep-identifier>)\\R?"
+ + "(<interface/>)\\R?"
+ + "(<primary-vid/>)\\R?"
+ + "(<administrative-state/>)\\R?"
+ + "(<ccm-ltm-priority/>)\\R?"
+ + "(<continuity-check/>)\\R?"
+ + "(<mac-address/>)\\R?"
+ + "(<msea-soam-fm:port-status/>)\\R?"
+ + "(<msea-soam-fm:interface-status/>)\\R?"
+ + "(<msea-soam-fm:last-defect-sent/>)\\R?"
+ + "(<msea-soam-fm:rdi-transmit-status/>)\\R?"
+ + "(<loopback/>)\\R?"
+ + "(<remote-mep-database/>)\\R?"
+ + "(<linktrace/>)\\R?"
+ + "(</maintenance-association-end-point>)\\R?"
+ + "(</maintenance-association>)\\R?"
+ + "(</maintenance-domain>)\\R?"
+ + "(</mef-cfm>)\\R?"
+ + "(</filter>)\\R?"
+ + "(</get>)\\R?"
+ + "(</rpc>)\\R?"
+ + "(]]>){2}", Pattern.DOTALL);
+
+
+ private static final String SAMPLE_SYSTEM_REPLY = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\">\n"
+ + "<data xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + "<system xmlns=\"urn:ietf:params:xml:ns:yang:ietf-system\">\n"
+ + "<clock><timezone-name>Etc/UTC</timezone-name></clock>\n"
+ + "</system>\n"
+ + "</data>\n"
+ + "</rpc-reply>";
+
+ private static final String SAMPLE_SYSTEM_REPLY_INIT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\">"
+ + "<data xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + "<system xmlns=\"urn:ietf:params:xml:ns:yang:ietf-system\">\n"
+ + "<longitude xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-system\">-8.4683990</longitude>\n"
+ + "<latitude xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-system\">51.9036140</latitude>\n"
+ + "</system>\n"
+ + "<system-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-system\""
+ + " xmlns:sysms=\"http://www.microsemi.com/microsemi-edge-assure/msea-system\">\n"
+ + "<platform>\n"
+ + "<os-release>4.4.0-53-generic</os-release>\n"
+ + "<sysms:device-identification>\n"
+ + "<sysms:serial-number>Eagle Simulator.</sysms:serial-number>\n"
+ + "</sysms:device-identification>\n"
+ + "</platform>\n"
+ + "</system-state>\n"
+ + "</data>"
+ + "</rpc-reply>";
+
+ private static final String SAMPLE_MSEASAFILTERING_FE_REPLY = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\">\n"
+ + "<data xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + "<source-ipaddress-filtering "
+ + "xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-sa-filtering\">\n"
+ + "<interface-eth0>\n"
+ + "<filter-admin-state>inactive</filter-admin-state>\n"
+ + "<source-address-range>\n"
+ + "<range-id>1</range-id>\n"
+ + "<ipv4-address-prefix>10.10.10.10/16</ipv4-address-prefix>\n"
+ + "<name>Filter1</name>\n"
+ + "</source-address-range>\n"
+ + "<source-address-range>\n"
+ + "<range-id>2</range-id>\n"
+ + "<ipv4-address-prefix>20.30.40.50/18</ipv4-address-prefix>\n"
+ + "<name>Flow:5e0000abaa2772</name>\n"
+ + "</source-address-range>\n"
+ + "</interface-eth0>\n"
+ + "</source-ipaddress-filtering>\n"
+ + "</data>\n"
+ + "</rpc-reply>";
+
+ private static final String SAMPLE_MSEAEVCUNI_REPLY_INIT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\">\n"
+ + "<data xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + "<mef-services xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\"/>"
+ + "</data>\n"
+ + "</rpc-reply>";
+
+ private static final String SAMPLE_MSEAEVCUNI_FE_REPLY = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\">\n"
+ + "<data xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + "<mef-services xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\">\n"
+ + "<uni>\n"
+ + "<name>Flow:7557655abfecd57865</name>\n"
+ + "<evc>\n"
+ + "<evc-index>7</evc-index\n>"
+ + "<name>evc-7</name>\n"
+ + "<evc-per-uni>\n"
+ + "<evc-per-uni-c>\n"
+ + "<ce-vlan-map>10</ce-vlan-map>\n"
+ + "<ingress-bwp-group-index>1</ingress-bwp-group-index>\n"
+ + "<tag-push>\n"
+ + "<push-tag-type>pushStag</push-tag-type>\n"
+ + "<outer-tag-vlan>3</outer-tag-vlan>\n"
+ + "</tag-push>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>10</ce-vlan-id>\n"
+ + "<flow-id>27021600672053710</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<evc-per-uni-service-type>epl</evc-per-uni-service-type>\n"
+ + "</evc-per-uni-c>\n"
+ + "<evc-per-uni-n>\n"
+ + "<ce-vlan-map>11</ce-vlan-map>\n"
+ + "<ingress-bwp-group-index>0</ingress-bwp-group-index>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>11</ce-vlan-id>\n"
+ + "<flow-id>27021600672053711</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "</evc-per-uni-n>\n"
+ + "</evc-per-uni>\n"
+ + "<uni-evc-id>EA1000-Uni-from-ONOS_5</uni-evc-id>\n"
+ + "<evc-status>\n"
+ + "<operational-state>unknown</operational-state>\n"
+ + "<max-mtu-size>9600</max-mtu-size>\n"
+ + "<max-num-uni>2</max-num-uni>\n"
+ + "</evc-status>\n"
+ + "</evc>\n"
+ + "<evc>\n"
+ + "<evc-index>8</evc-index>\n"
+ + "<name>evc-8</name>\n"
+ + "<evc-per-uni>\n"
+ + "<evc-per-uni-c>\n"
+ + "<ce-vlan-map>12:14,20:22,25</ce-vlan-map>\n"
+ + "<ingress-bwp-group-index>0</ingress-bwp-group-index>\n"
+ + "<tag-pop />\n"
+ + "<evc-per-uni-service-type>epl</evc-per-uni-service-type>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>12</ce-vlan-id>\n"
+ + "<flow-id>27021600672053712</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>13</ce-vlan-id>\n"
+ + "<flow-id>27021600672053713</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>14</ce-vlan-id>\n"
+ + "<flow-id>27021600672053714</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>20</ce-vlan-id>\n"
+ + "<flow-id>27021600672053720</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>21</ce-vlan-id>\n"
+ + "<flow-id>27021600672053721</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>22</ce-vlan-id>\n"
+ + "<flow-id>27021600672053722</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>25</ce-vlan-id>\n"
+ + "<flow-id>27021600672053725</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "</evc-per-uni-c>\n"
+ + "<evc-per-uni-n>\n"
+ + "<ce-vlan-map>13</ce-vlan-map>\n"
+ + "<ingress-bwp-group-index>0</ingress-bwp-group-index>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>13</ce-vlan-id>\n"
+ + "<flow-id>27021600672053713</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "</evc-per-uni-n>\n"
+ + "</evc-per-uni>\n"
+ + "<uni-evc-id>EA1000-Uni-from-ONOS_5</uni-evc-id>\n"
+ + "<evc-status>\n"
+ + "<operational-state>unknown</operational-state>\n"
+ + "<max-mtu-size>9600</max-mtu-size>\n"
+ + "<max-num-uni>2</max-num-uni>\n"
+ + "</evc-status>\n"
+ + "</evc>\n"
+ + "</uni>\n"
+ + "<profiles>\n"
+ + "<bwp-group>\n"
+ + "<group-index>0</group-index>\n"
+ + "</bwp-group>\n"
+ + "</profiles>\n"
+ + "</mef-services>\n"
+ + "</data>\n"
+ + "</rpc-reply>";
+
+ private static final String SAMPLE_MSEAEVCUNI_CEVLANMAP_EVC_REPLY = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\">\n"
+ + "<data xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + "<mef-services xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\">\n"
+ + "<uni>\n"
+
+ + "<evc><evc-index>1</evc-index>\n"
+ + "<evc-per-uni>\n"
+ + "<evc-per-uni-c>\n"
+ + "<ce-vlan-map>101</ce-vlan-map>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>101</ce-vlan-id>\n"
+ + "<flow-id>27021598629213101</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "</evc-per-uni-c>\n"
+ + "<evc-per-uni-n>\n"
+ + "<ce-vlan-map>102</ce-vlan-map>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>102</ce-vlan-id>\n"
+ + "<flow-id>27021598629213102</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "</evc-per-uni-n>\n"
+ + "</evc-per-uni>\n"
+ + "</evc>\n"
+
+ + "<evc><evc-index>7</evc-index>\n"
+ + "<evc-per-uni>\n"
+ + "<evc-per-uni-c>\n"
+ + "<ce-vlan-map>700,710,720</ce-vlan-map>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>700</ce-vlan-id>\n"
+ + "<flow-id>27021598629213700</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>710</ce-vlan-id>\n"
+ + "<flow-id>27021598629213710</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>720</ce-vlan-id>\n"
+ + "<flow-id>27021598629213720</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "</evc-per-uni-c>\n"
+ + "<evc-per-uni-n>\n"
+ + "<ce-vlan-map>701:703</ce-vlan-map>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>701</ce-vlan-id>\n"
+ + "<flow-id>27021598629213701</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>702</ce-vlan-id>\n"
+ + "<flow-id>27021598629213702</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "<flow-mapping>\n"
+ + "<ce-vlan-id>703</ce-vlan-id>\n"
+ + "<flow-id>27021598629213703</flow-id>\n"
+ + "</flow-mapping>\n"
+ + "</evc-per-uni-n>\n"
+ + "</evc-per-uni>\n"
+ + "</evc>\n"
+
+ + "<evc><evc-index>8</evc-index>\n"
+ + "<evc-per-uni>\n"
+ + "<evc-per-uni-c>\n<ce-vlan-map>800,810,820</ce-vlan-map>\n</evc-per-uni-c>\n"
+ + "<evc-per-uni-n>\n<ce-vlan-map>801:803</ce-vlan-map>\n</evc-per-uni-n>\n"
+ + "</evc-per-uni>\n"
+ + "</evc>\n"
+
+ + "</uni>\n"
+ + "</mef-services>\n"
+ + "</data>\n"
+ + "</rpc-reply>";
+
+ private static final String SAMPLE_MSEACFM_MD_MA_MEP_REPLY =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"47\">"
+ + "<data>"
+ + "<mef-cfm xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-cfm\" "
+ + "xmlns:msea-soam-fm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-fm\" "
+ + "xmlns:msea-soam-pm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-pm\">"
+ + "<maintenance-domain>"
+ + "<id>1</id>"
+ + "<name>md-1</name>"
+ + "<md-level>3</md-level>"
+ + "<maintenance-association>"
+ + "<id>1</id>"
+ + "<name>ma-1-1</name>"
+ + "<ccm-interval>10ms</ccm-interval>" //Causing problems on create of MA
+ + "<remote-meps>1</remote-meps>"
+ + "<remote-meps>2</remote-meps>"
+ + "<component-list>"
+ + "<vid>100</vid>"
+ + "<tag-type>vlan-stag</tag-type>"
+ + "</component-list>"
+ + "<maintenance-association-end-point>"
+ + "<mep-identifier>1</mep-identifier>"
+ + "<interface>eth1</interface>"
+ + "<primary-vid>100</primary-vid>"
+ + "<administrative-state>true</administrative-state>"
+ + "<ccm-ltm-priority>4</ccm-ltm-priority>"
+ + "<continuity-check>"
+ + "<cci-enabled>true</cci-enabled>"
+ + "<fng-state>report-defect</fng-state>"
+ + "<highest-priority-defect-found>remote-mac-error</highest-priority-defect-found>"
+ + "<active-defects> remote-mac-error invalid-ccm</active-defects>"
+ + "<last-error-ccm>U2FtcGxlIGxhc3QgZXJyb3IgY2NtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAA==</last-error-ccm>"
+ + "<ccm-sequence-error-count>10</ccm-sequence-error-count>"
+ + "<sent-ccms>15</sent-ccms>"
+ + "</continuity-check>"
+ + "<mac-address>53:65:61:6e:20:43</mac-address>"
+ + "<msea-soam-fm:port-status>no-status-tlv</msea-soam-fm:port-status>"
+ + "<msea-soam-fm:interface-status>no-status-tlv</msea-soam-fm:interface-status>"
+// + "<msea-soam-fm:last-defect-sent/>" --Can't handle this at the moment
+ + "<msea-soam-fm:rdi-transmit-status>false</msea-soam-fm:rdi-transmit-status>"
+ + "<loopback>"
+ + "<replies-received>123</replies-received>"
+ + "<replies-transmitted>456</replies-transmitted>"
+ + "</loopback>"
+ + "<remote-mep-database>"
+ + "<remote-mep>"
+ + "<remote-mep-id>2</remote-mep-id>"
+ + "<remote-mep-state>ok</remote-mep-state>"
+ + "<failed-ok-time>1490692834</failed-ok-time>"
+ + "<mac-address>53:65:61:6e:20:43</mac-address>"
+ + "<rdi>true</rdi>"
+ + "<port-status-tlv>up</port-status-tlv>"
+ + "<interface-status-tlv>dormant</interface-status-tlv>"
+ + "</remote-mep>"
+ + "</remote-mep-database>"
+ + "<linktrace>"
+ + "<unexpected-replies-received>0</unexpected-replies-received>"
+ + "<msea-soam-fm:ltm-msgs-transmitted>2</msea-soam-fm:ltm-msgs-transmitted>"
+ + "<msea-soam-fm:ltm-msgs-received>2</msea-soam-fm:ltm-msgs-received>"
+ + "<msea-soam-fm:ltr-msgs-transmitted>2</msea-soam-fm:ltr-msgs-transmitted>"
+ + "<msea-soam-fm:ltr-msgs-received>2</msea-soam-fm:ltr-msgs-received>"
+ + "<linktrace-database/>"
+ + "</linktrace>"
+ + "</maintenance-association-end-point>"
+ + "<remote-meps>4</remote-meps>"
+ + "</maintenance-association>"
+ + "</maintenance-domain>"
+ + "</mef-cfm>"
+ + "</data>"
+ + "</rpc-reply>";
+
+ private static final String SAMPLE_MSEACFM_MD_MA_MEP_REPLY2 =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"47\">"
+ + "<data>"
+ + "<mef-cfm xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-cfm\" "
+ + "xmlns:msea-soam-fm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-fm\" "
+ + "xmlns:msea-soam-pm=\"http://www.microsemi.com/microsemi-edge-assure/msea-soam-pm\">"
+ + "<maintenance-domain>"
+ + "<id>1</id>"
+ + "<name>Microsemi</name>"
+ + "<md-level>2</md-level>"
+ + "<maintenance-association>"
+ + "<id>1</id>"
+ + "<name>example-ma</name>"
+ + "<remote-meps>1</remote-meps>"
+ + "<remote-meps>2</remote-meps>"
+ + "<component-list>"
+ + "<vid>100</vid>"
+ + "<tag-type>vlan-stag</tag-type>"
+ + "</component-list>"
+ + "<maintenance-association-end-point>"
+ + "<mep-identifier>4</mep-identifier>"
+ + "<interface>eth1</interface>"
+ + "<primary-vid>100</primary-vid>"
+ + "<administrative-state>true</administrative-state>"
+ + "<ccm-ltm-priority>4</ccm-ltm-priority>"
+ + "<continuity-check>"
+ + "<cci-enabled>true</cci-enabled>"
+ + "<fng-state>defect-reported</fng-state>"
+ + "<highest-priority-defect-found>remote-invalid-ccm</highest-priority-defect-found>"
+// + "<active-defects> remote-invalid-ccm</active-defects>"
+ + "<active-defects/>"
+ + "<ccm-sequence-error-count>0</ccm-sequence-error-count>"
+ + "<sent-ccms>41013</sent-ccms>"
+ + "</continuity-check>"
+ + "<mac-address>00:b0:ae:03:ff:31</mac-address>"
+ + "<msea-soam-fm:port-status>up</msea-soam-fm:port-status>"
+ + "<msea-soam-fm:interface-status>up</msea-soam-fm:interface-status>"
+ + "<msea-soam-fm:rdi-transmit-status>true</msea-soam-fm:rdi-transmit-status>"
+ + "<loopback>"
+ + "<replies-received>0</replies-received>"
+ + "<replies-transmitted>0</replies-transmitted>"
+ + "</loopback>"
+ + "<remote-mep-database>"
+ + "<remote-mep>"
+ + "<remote-mep-id>1</remote-mep-id>"
+ + "<remote-mep-state>failed</remote-mep-state>"
+ + "<failed-ok-time>26315533</failed-ok-time>"
+ + "<mac-address>00:00:00:00:00:00</mac-address>"
+ + "<rdi>false</rdi>"
+ + "<port-status-tlv>no-status-tlv</port-status-tlv>"
+ + "<interface-status-tlv>no-status-tlv</interface-status-tlv>"
+ + "</remote-mep>"
+ + "<remote-mep>"
+ + "<remote-mep-id>2</remote-mep-id>"
+ + "<remote-mep-state>failed</remote-mep-state>"
+ + "<failed-ok-time>26315541</failed-ok-time>"
+ + "<mac-address>00:00:00:00:00:00</mac-address>"
+ + "<rdi>false</rdi>"
+ + "<port-status-tlv>no-status-tlv</port-status-tlv>"
+ + "<interface-status-tlv>no-status-tlv</interface-status-tlv>"
+ + "</remote-mep>"
+ + "</remote-mep-database>"
+ + "<linktrace />"
+ + "</maintenance-association-end-point>"
+ + "<remote-meps>4</remote-meps>"
+ + "</maintenance-association>"
+ + "</maintenance-domain>"
+ + "</mef-cfm>"
+ + "</data>"
+ + "</rpc-reply>";
+
+ private static final String SAMPLE_REPLY_OK = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"2\">"
+ + "<ok/>"
+ + "</rpc-reply>";
+
+ private NetconfDeviceInfo deviceInfo;
+
+ private final AtomicInteger messageIdInteger = new AtomicInteger(0);
+
+ public MockNetconfSessionEa1000(NetconfDeviceInfo deviceInfo) throws NetconfException {
+ this.deviceInfo = deviceInfo;
+ }
+
+ @Override
+ public CompletableFuture<String> request(String request) throws NetconfException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String get(String request) throws NetconfException {
+
+ return sendRequest(request);
+ }
+
+ @Override
+ public String get(String filterSchema, String withDefaultsMode) throws NetconfException {
+ StringBuilder rpc = new StringBuilder(XML_HEADER);
+ rpc.append(RPC_OPEN);
+ rpc.append(MESSAGE_ID_STRING);
+ rpc.append(EQUAL);
+ rpc.append("\"");
+ rpc.append(messageIdInteger.get());
+ rpc.append("\" ");
+ rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
+ rpc.append(GET_OPEN).append(NEW_LINE);
+ if (filterSchema != null) {
+ rpc.append(SUBTREE_FILTER_OPEN).append(NEW_LINE);
+ rpc.append(filterSchema).append(NEW_LINE);
+ rpc.append(SUBTREE_FILTER_CLOSE).append(NEW_LINE);
+ }
+ if (withDefaultsMode != null) {
+ rpc.append(WITH_DEFAULT_OPEN).append(NETCONF_WITH_DEFAULTS_NAMESPACE).append(">");
+ rpc.append(withDefaultsMode).append(WITH_DEFAULT_CLOSE).append(NEW_LINE);
+ }
+ rpc.append(GET_CLOSE).append(NEW_LINE);
+ rpc.append(RPC_CLOSE).append(NEW_LINE);
+ rpc.append(ENDPATTERN);
+ String reply = sendRequest(rpc.toString());
+ checkReply(reply);
+ return reply;
+ }
+
+ @Override
+ public String doWrappedRpc(String request) throws NetconfException {
+ StringBuilder rpc = new StringBuilder(XML_HEADER);
+ rpc.append(RPC_OPEN);
+ rpc.append(MESSAGE_ID_STRING);
+ rpc.append(EQUAL);
+ rpc.append("\"");
+ rpc.append(messageIdInteger.get());
+ rpc.append("\" ");
+ rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
+ rpc.append(request);
+ rpc.append(RPC_CLOSE).append(NEW_LINE);
+ rpc.append(ENDPATTERN);
+ String reply = sendRequest(rpc.toString());
+ checkReply(reply);
+ return reply;
+ }
+
+ @Override
+ public String requestSync(String request) throws NetconfException {
+ if (!request.contains(ENDPATTERN)) {
+ request = request + NEW_LINE + ENDPATTERN;
+ }
+ String reply = sendRequest(request);
+ checkReply(reply);
+ return reply;
+ }
+
+
+ @Override
+ public String getConfig(DatastoreId targetConfiguration, String configurationSchema) throws NetconfException {
+ StringBuilder rpc = new StringBuilder(XML_HEADER);
+ rpc.append("<rpc ");
+ rpc.append(MESSAGE_ID_STRING);
+ rpc.append(EQUAL);
+ rpc.append("\"");
+ rpc.append(messageIdInteger.get());
+ rpc.append("\" ");
+ rpc.append("xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n");
+ rpc.append("<get-config>\n");
+ rpc.append("<source>\n");
+ rpc.append("<").append(targetConfiguration).append("/>");
+ rpc.append("</source>");
+ if (configurationSchema != null) {
+ rpc.append("<filter type=\"subtree\">\n");
+ rpc.append(configurationSchema).append("\n");
+ rpc.append("</filter>\n");
+ }
+ rpc.append("</get-config>\n");
+ rpc.append("</rpc>\n");
+ rpc.append(ENDPATTERN);
+ String reply = sendRequest(rpc.toString());
+ return checkReply(reply) ? reply : "ERROR " + reply;
+ }
+
+ @Override
+ public boolean editConfig(String newConfiguration) throws NetconfException {
+ return editConfig(DatastoreId.RUNNING, null, newConfiguration);
+ }
+
+ @Override
+ public boolean editConfig(DatastoreId targetConfiguration, String mode, String newConfiguration)
+ throws NetconfException {
+ newConfiguration = newConfiguration.trim();
+ StringBuilder rpc = new StringBuilder(XML_HEADER);
+ rpc.append(RPC_OPEN);
+ rpc.append(MESSAGE_ID_STRING);
+ rpc.append(EQUAL);
+ rpc.append("\"");
+ rpc.append(messageIdInteger.get());
+ rpc.append("\" ");
+ rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
+ rpc.append(EDIT_CONFIG_OPEN).append("\n");
+ rpc.append(TARGET_OPEN);
+ rpc.append("<").append(targetConfiguration).append("/>");
+ rpc.append(TARGET_CLOSE).append("\n");
+ if (mode != null) {
+ rpc.append(DEFAULT_OPERATION_OPEN);
+ rpc.append(mode);
+ rpc.append(DEFAULT_OPERATION_CLOSE).append("\n");
+ }
+ rpc.append(CONFIG_OPEN).append("\n");
+ rpc.append(newConfiguration);
+ rpc.append(CONFIG_CLOSE).append("\n");
+ rpc.append(EDIT_CONFIG_CLOSE).append("\n");
+ rpc.append(RPC_CLOSE);
+ rpc.append(ENDPATTERN);
+ log.debug(rpc.toString());
+ String reply = sendRequest(rpc.toString());
+ return checkReply(reply);
+ }
+
+ @Override
+ public boolean copyConfig(String targetConfiguration, String newConfiguration) throws NetconfException {
+ return copyConfig(TargetConfig.valueOf(targetConfiguration), newConfiguration);
+ }
+
+ @Override
+ public void startSubscription() throws NetconfException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void startSubscription(String filterSchema) throws NetconfException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void endSubscription() throws NetconfException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean lock() throws NetconfException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean unlock() throws NetconfException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean close() throws NetconfException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public String getSessionId() {
+ return "mockSessionId";
+ }
+
+ @Override
+ public String getServerCapabilities() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void setDeviceCapabilities(List<String> capabilities) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void addDeviceOutputListener(NetconfDeviceOutputEventListener listener) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void removeDeviceOutputListener(NetconfDeviceOutputEventListener listener) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private boolean checkReply(String reply) throws NetconfException {
+ if (reply != null) {
+ if (!reply.contains("<rpc-error>")) {
+ log.debug("Device {} sent reply {}", deviceInfo, reply);
+ return true;
+ } else if (reply.contains("<ok/>")
+ || (reply.contains("<rpc-error>")
+ && reply.contains("warning"))) {
+ log.debug("Device {} sent reply {}", deviceInfo, reply);
+ return true;
+ }
+ }
+ log.warn("Device {} has error in reply {}", deviceInfo, reply);
+ return false;
+ }
+
+ private String sendRequest(String request) throws NetconfException {
+ log.info("Mocking NETCONF Session send request: \n" + request);
+
+ if (sampleXmlRegex1.matcher(request).matches()) {
+ return SAMPLE_SYSTEM_REPLY;
+
+ } else if (sampleXmlRegex2.matcher(request).matches()) {
+ return SAMPLE_SYSTEM_REPLY_INIT;
+
+ } else if (sampleXmlRegexSaFiltering.matcher(request).matches()) {
+ return SAMPLE_MSEASAFILTERING_FE_REPLY;
+
+ } else if (sampleXmlRegexEditConfigSaFilt.matcher(request).matches()) {
+ return SAMPLE_REPLY_OK;
+
+ } else if (sampleXmlRegexEditDeleteSaFilt.matcher(request).matches()) {
+ return SAMPLE_REPLY_OK;
+
+ } else if (sampleXmlRegexUniEvc.matcher(request).matches()) {
+ return SAMPLE_MSEAEVCUNI_REPLY_INIT;
+
+ } else if (sampleXmlRegexUniEvcUni.matcher(request).matches()) {
+ return SAMPLE_MSEAEVCUNI_FE_REPLY;
+
+ } else if (sampleXmlRegexEditConfigUni1Evc.matcher(request).matches()) {
+ return SAMPLE_REPLY_OK;
+
+ } else if (sampleXmlRegexEditConfigUni2Evc.matcher(request).matches()) {
+ return SAMPLE_REPLY_OK;
+
+ } else if (sampleXmlRegexEditConfigUniProfiles.matcher(request).matches()) {
+ return SAMPLE_REPLY_OK;
+
+ } else if (sampleXmlRegexEditConfigEvcDelete.matcher(request).matches()) {
+ return SAMPLE_REPLY_OK;
+
+ } else if (sampleXmlRegexGetConfigCeVlanMapsEvc.matcher(request).matches()) {
+ return SAMPLE_MSEAEVCUNI_CEVLANMAP_EVC_REPLY;
+
+ } else if (sampleXmlRegexEditConfigCeVlanMapReplace.matcher(request).matches()) {
+ return SAMPLE_REPLY_OK;
+
+ } else if (sampleXmlRegexEditConfigBwpGroup1.matcher(request).matches()) {
+ return SAMPLE_REPLY_OK;
+
+ } else if (sampleXmlRegexEditConfigBwpGroup1Delete.matcher(request).matches()) {
+ return SAMPLE_REPLY_OK;
+
+ } else if (sampleXmlRegexSetCurrentDatetime.matcher(request).matches()) {
+ return SAMPLE_REPLY_OK;
+
+ } else if (sampleXmlRegexGetMseaCfmEssentials.matcher(request).matches()) {
+ return SAMPLE_MSEACFM_MD_MA_MEP_REPLY2;
+
+ } else {
+ throw new NetconfException("MocknetconfSession. No sendRequest() case for query: " +
+ request);
+ }
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MseaCfmManagerTest.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MseaCfmManagerTest.java
new file mode 100644
index 0000000..e3a81bc
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MseaCfmManagerTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.UncheckedIOException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.drivers.microsemi.yang.impl.MseaCfmManager;
+import org.onosproject.netconf.NetconfDeviceInfo;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfm;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.DefaultMefCfm;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.MefCfm;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.DefaultMaintenanceDomain;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.MaintenanceDomain;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.DefaultNameCharacterString;
+import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.NameCharacterString;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.Identifier45;
+
+public class MseaCfmManagerTest {
+
+ MseaCfmManager mseaCfmService;
+ NetconfSession session;
+
+ @Before
+ public void setUp() throws Exception {
+ try {
+ mseaCfmService = new MockMseaCfmManager();
+ mseaCfmService.activate();
+ } catch (UncheckedIOException e) {
+ fail(e.getMessage());
+ }
+ NetconfDeviceInfo deviceInfo = new NetconfDeviceInfo("netconf", "netconf", Ip4Address.valueOf("1.2.3.4"), 830);
+ session = new MockNetconfSessionEa1000(deviceInfo);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testGetConfigMseaCfmEssentials() throws NetconfException {
+ MseaCfm mseaCfm = mseaCfmService.getMepEssentials("md-1", "ma-1-1", 1, session);
+ assertNotNull(mseaCfm);
+
+ //See SAMPLE_MSEACFM_MD_MA_MEP_REPLY in MockNetconfSessionEa1000
+ assertEquals(1, mseaCfm.mefCfm().maintenanceDomain().size());
+ assertEquals(2, mseaCfm.mefCfm().maintenanceDomain().get(0).mdLevel().uint8());
+ }
+
+ /**
+ * Create the Maintenance Domain "md-1".
+ * @throws NetconfException
+ */
+ @Test
+ public void testSetMseaCfm() throws NetconfException {
+ NameCharacterString mdName = new DefaultNameCharacterString();
+ mdName.name(Identifier45.fromString("md-1"));
+
+ MaintenanceDomain yangMd = new DefaultMaintenanceDomain();
+ yangMd.id((short) 1);
+ yangMd.mdNameAndTypeCombo(mdName);
+
+ MefCfm mefCfm = new DefaultMefCfm();
+ mefCfm.addToMaintenanceDomain(yangMd);
+ //FIXME implement this
+// MseaCfmOpParam mseaCfmOpParam = (MseaCfmOpParam) MseaCfmOpParam.builder().mefCfm(mefCfm).build();
+// mseaCfmService.setMseaCfm(mseaCfmOpParam, session, NcDsType.running);
+ }
+
+ @Test
+ public void testTransmitLoopback() throws NetconfException {
+ try {
+ mseaCfmService.transmitLoopback(null, session);
+ } catch (UnsupportedOperationException e) {
+ assertTrue(e.getMessage().contains("Not yet implemented"));
+ }
+ }
+
+ @Test
+ public void testAbortLoopback() throws NetconfException {
+ try {
+ mseaCfmService.abortLoopback(null, session);
+ } catch (UnsupportedOperationException e) {
+ assertTrue(e.getMessage().contains("Not yet implemented"));
+ }
+ }
+
+ @Test
+ public void testTransmitLinktrace() throws NetconfException {
+ try {
+ mseaCfmService.transmitLinktrace(null, session);
+ } catch (UnsupportedOperationException e) {
+ assertTrue(e.getMessage().contains("Not yet implemented"));
+ }
+ }
+
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MseaSaFilteringManagerTest.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MseaSaFilteringManagerTest.java
new file mode 100644
index 0000000..acb6ae6
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MseaSaFilteringManagerTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.UncheckedIOException;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.drivers.microsemi.yang.impl.MseaSaFilteringManager;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfDeviceInfo;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFilteringOpParam;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.DefaultSourceIpaddressFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.SourceIpaddressFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.DefaultInterfaceEth0;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.InterfaceEth0;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.interfaceeth0.DefaultSourceAddressRange;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.interfaceeth0.SourceAddressRange;
+
+public class MseaSaFilteringManagerTest {
+
+ MseaSaFilteringManager mseaSaSvc;
+ NetconfSession session;
+
+ @Before
+ public void setUp() throws Exception {
+ try {
+ mseaSaSvc = new MockMseaSaFilteringManager();
+ mseaSaSvc.activate();
+ } catch (UncheckedIOException e) {
+ fail(e.getMessage());
+ }
+ NetconfDeviceInfo deviceInfo = new NetconfDeviceInfo("netconf", "netconf", Ip4Address.valueOf("1.2.3.4"), 830);
+ session = new MockNetconfSessionEa1000(deviceInfo);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testGetMseaSaFilteringMseaSaFilteringOpParamNetconfSession() throws NetconfException {
+ SourceIpaddressFiltering sip = new DefaultSourceIpaddressFiltering();
+
+ MseaSaFilteringOpParam op = new MseaSaFilteringOpParam();
+ op.sourceIpaddressFiltering(sip);
+
+ MseaSaFiltering result = mseaSaSvc.getMseaSaFiltering(op, session);
+
+ //Results come from MockNetconfSession SAMPLE_MSEASAFILTERING_REPLY_INIT
+ assertNotNull(result.sourceIpaddressFiltering().interfaceEth0().sourceAddressRange());
+ List<SourceAddressRange> ranges = result.sourceIpaddressFiltering().interfaceEth0().sourceAddressRange();
+ assertEquals(2, ranges.size());
+
+ for (SourceAddressRange sa:ranges) {
+ if (sa.rangeId() == 1) {
+ assertEquals("10.10.10.10/16", sa.ipv4AddressPrefix());
+
+ } else if (sa.rangeId() == 2) {
+ assertEquals("20.30.40.50/18", sa.ipv4AddressPrefix());
+ }
+ }
+ }
+
+ @Test
+ public void testSetMseaSaFilteringMseaSaFilteringOpParamNetconfSessionNcDsType() {
+
+ MseaSaFilteringOpParam mseaSaFilteringConfig =
+ createConfigForEdit("192.168.60.10/27", (short) 3, "Filter3");
+
+ //Calling on the edit-config just makes the change and hopefully does not throw a Netconf Exception
+ try {
+ mseaSaSvc.setMseaSaFiltering(mseaSaFilteringConfig, session, DatastoreId.RUNNING);
+ } catch (NetconfException e) {
+ e.printStackTrace();
+ fail("NETCONF Exception: " + e.getMessage());
+ }
+ }
+
+ @Test
+ public void testDeleteMseaSaFilteringMseaSaFilteringOpParamNetconfSessionNcDsType() {
+
+ MseaSaFilteringOpParam mseaSaFilteringConfig =
+ createConfigForEdit("192.168.60.10/27", (short) 3, "Filter3");
+
+ SourceAddressRange sar2 = new DefaultSourceAddressRange();
+ sar2.ipv4AddressPrefix("10.205.86.10/27");
+ sar2.rangeId((short) 4);
+ sar2.name("Filter4");
+
+ mseaSaFilteringConfig.sourceIpaddressFiltering().interfaceEth0()
+ .addToSourceAddressRange(sar2);
+
+ //Calling on the edit-config just makes the change and hopefully does not throw a Netconf Exception
+ try {
+ mseaSaSvc.deleteMseaSaFilteringRange(mseaSaFilteringConfig, session, DatastoreId.RUNNING);
+ } catch (NetconfException e) {
+ e.printStackTrace();
+ fail("NETCONF Exception: " + e.getMessage());
+ }
+ }
+
+ /**
+ * This is also called from the test case EA1000FlowRuleProgrammableTest().
+ * In the ea1000driver project
+ * @return
+ */
+ public static MseaSaFilteringOpParam createConfigForEdit(String ipAddrPrefix, short rangeId, String rangeName) {
+ SourceAddressRange sar = new DefaultSourceAddressRange();
+ sar.ipv4AddressPrefix(ipAddrPrefix);
+ sar.rangeId(rangeId);
+ sar.name(rangeName);
+
+ InterfaceEth0 eth0 = new DefaultInterfaceEth0();
+ eth0.addToSourceAddressRange(sar);
+
+ SourceIpaddressFiltering sip = new DefaultSourceIpaddressFiltering();
+ sip.interfaceEth0(eth0);
+
+ MseaSaFilteringOpParam op = new MseaSaFilteringOpParam();
+ op.sourceIpaddressFiltering(sip);
+
+ return op;
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MseaUniEvcServiceManagerTest.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MseaUniEvcServiceManagerTest.java
new file mode 100644
index 0000000..8d8b2bd
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/MseaUniEvcServiceManagerTest.java
@@ -0,0 +1,496 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.UncheckedIOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.drivers.microsemi.yang.impl.MseaUniEvcServiceManager;
+import org.onosproject.drivers.microsemi.yang.utils.CeVlanMapUtils;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfDeviceInfo;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.Identifier45;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.ServiceListType;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.VlanIdType;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcService;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcServiceOpParam;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.DefaultMefServices;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.MefServices;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.EvcPerUniServiceTypeEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.TagPush;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.tagpush.tagpush.PushTagTypeEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.DefaultTagPush;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.Profiles;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.DefaultProfiles;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.DefaultUni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.Uni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.BwpGroup;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.Cos;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.DefaultBwpGroup;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.DefaultCos;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.bwpgroup.Bwp;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.bwpgroup.DefaultBwp;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.bwpgroup.bwp.ColorModeEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.DefaultEvc;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.Evc;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.UniSideInterfaceAssignmentEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.DefaultEvcPerUni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.EvcPerUni;
+import org.onosproject.drivers.microsemi.yang.custom.CustomEvcPerUnic;
+import org.onosproject.drivers.microsemi.yang.custom.CustomEvcPerUnin;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.evcperuni.EvcPerUnic;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.evcperuni.EvcPerUnin;
+
+public class MseaUniEvcServiceManagerTest {
+
+ MseaUniEvcServiceManager mseaUniEvcServiceSvc;
+ NetconfSession session;
+
+ @Before
+ public void setUp() throws Exception {
+ try {
+ mseaUniEvcServiceSvc = new MockMseaUniEvcServiceManager();
+ mseaUniEvcServiceSvc.activate();
+ } catch (UncheckedIOException e) {
+ fail(e.getMessage());
+ }
+ NetconfDeviceInfo deviceInfo = new NetconfDeviceInfo("netconf", "netconf", Ip4Address.valueOf("1.2.3.4"), 830);
+ session = new MockNetconfSessionEa1000(deviceInfo);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testGetMseaUniEvcServiceMseaUniEvcServiceOpParamNetconfSession() {
+ MefServices mefServices = new DefaultMefServices();
+ mefServices.uni(new DefaultUni());
+
+ MseaUniEvcServiceOpParam evcUni = new MseaUniEvcServiceOpParam();
+ evcUni.mefServices(mefServices);
+
+ MseaUniEvcService result = null;
+ try {
+ result =
+ mseaUniEvcServiceSvc.getConfigMseaUniEvcService(
+ evcUni, session, DatastoreId.RUNNING);
+ } catch (NetconfException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ fail("Error: " + e.getMessage());
+ }
+
+ assertNotNull(result);
+ }
+
+ @Test
+ public void testSetMseaUniEvcServiceMseaUniEvcServiceOpParamEvcs() {
+ TagPush tp1 = new DefaultTagPush();
+ org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice
+ .evcperuniextensionattributes.tagmanipulation
+ .tagpush.TagPush tpInner1 =
+ new org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317
+ .mseaunievcservice.evcperuniextensionattributes
+ .tagmanipulation.tagpush.DefaultTagPush();
+ tpInner1.outerTagVlan(new VlanIdType(3));
+ tpInner1.pushTagType(PushTagTypeEnum.PUSHSTAG);
+ tp1.tagPush(tpInner1);
+
+ EvcPerUnin epun1 = new CustomEvcPerUnin();
+ epun1.evcPerUniServiceType(EvcPerUniServiceTypeEnum.EVPL);
+ epun1.ceVlanMap(ServiceListType.fromString("10"));
+ epun1.ingressBwpGroupIndex("0");
+ epun1.tagManipulation(tp1);
+
+ EvcPerUnic epuc1 = new CustomEvcPerUnic();
+ epuc1.ceVlanMap(new ServiceListType("11"));
+ epuc1.ingressBwpGroupIndex("0");
+
+ EvcPerUni epu1 = new DefaultEvcPerUni();
+ epu1.evcPerUnic(epuc1);
+ epu1.evcPerUnin(epun1);
+
+ List<Evc> evcList = new ArrayList<Evc>();
+ Evc evc1 = new DefaultEvc();
+ evc1.evcIndex(1);
+ evc1.name(new Identifier45("evc-1"));
+ evc1.evcPerUni(epu1);
+
+ evcList.add(evc1);
+
+
+ EvcPerUnin epun2 = new CustomEvcPerUnin();
+ epun2.ceVlanMap(ServiceListType.fromString("13"));
+ epun2.ingressBwpGroupIndex("0");
+
+ EvcPerUnic epuc2 = new CustomEvcPerUnic();
+ epuc2.ceVlanMap(new ServiceListType("12"));
+ epuc2.ingressBwpGroupIndex("0");
+
+ EvcPerUni epu2 = new DefaultEvcPerUni();
+ epu2.evcPerUnic(epuc2);
+ epu2.evcPerUnin(epun2);
+
+ Evc evc2 = new DefaultEvc();
+ evc2.evcIndex(2);
+ evc2.name(new Identifier45("evc-2"));
+ evc2.evcPerUni(epu2);
+
+ evcList.add(evc2);
+
+ Uni uni = new DefaultUni();
+ uni.name(new Identifier45("testUni"));
+ uni.evc(evcList);
+
+ MefServices mefServices = new DefaultMefServices();
+ mefServices.uni(uni);
+
+ MseaUniEvcServiceOpParam evcUni = new MseaUniEvcServiceOpParam();
+ evcUni.mefServices(mefServices);
+ try {
+ mseaUniEvcServiceSvc.setMseaUniEvcService(evcUni, session, DatastoreId.RUNNING);
+ } catch (NetconfException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ fail("Error: " + e.getMessage());
+ }
+ }
+
+ @Test
+ public void testSetMseaUniEvcServiceMseaUniEvcServiceOpParamProfiles() {
+ List<Cos> cosList = new ArrayList<Cos>();
+ Cos cos0 = new DefaultCos();
+ cos0.cosIndex(0);
+ cos0.name("cos0");
+ cosList.add(cos0);
+
+ Cos cos1 = new DefaultCos();
+ cos1.cosIndex(1);
+ cos1.name("cos1");
+ cosList.add(cos1);
+
+ List<BwpGroup> bwpGroupList = new ArrayList<BwpGroup>();
+ BwpGroup bwpGrp = new DefaultBwpGroup();
+ bwpGrp.groupIndex((short) 0);
+ bwpGroupList.add(bwpGrp);
+
+ List<Bwp> bwpList = new ArrayList<Bwp>();
+ Bwp bwp1 = new DefaultBwp();
+ bwp1.cosIndex(0);
+ bwp1.colorMode(ColorModeEnum.COLORAWARE);
+ bwpList.add(bwp1);
+
+ Bwp bwp2 = new DefaultBwp();
+ bwp2.cosIndex(1);
+ bwp2.colorMode(ColorModeEnum.COLORBLIND);
+ bwpList.add(bwp2);
+
+ BwpGroup bwpGrp1 = new DefaultBwpGroup();
+ bwpGrp1.groupIndex((short) 1);
+ bwpGrp1.bwp(bwpList);
+ bwpGroupList.add(bwpGrp1);
+
+ Profiles profiles = new DefaultProfiles();
+ profiles.bwpGroup(bwpGroupList);
+
+ MefServices mefServices = new DefaultMefServices();
+ mefServices.profiles(profiles);
+
+ MseaUniEvcServiceOpParam evcUni = new MseaUniEvcServiceOpParam();
+ evcUni.mefServices(mefServices);
+ try {
+ mseaUniEvcServiceSvc.setMseaUniEvcService(evcUni, session, DatastoreId.RUNNING);
+ } catch (NetconfException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ fail("Error: " + e.getMessage());
+ }
+ }
+
+ @Test
+ public void testDeleteMseaUniEvcServiceMseaUniEvcServiceOpParamProfiles() {
+ List<Cos> cosList = new ArrayList<Cos>();
+ Cos cos0 = new DefaultCos();
+ cos0.cosIndex(0);
+ cos0.name("cos0");
+ cosList.add(cos0);
+
+ Cos cos1 = new DefaultCos();
+ cos1.cosIndex(1);
+ cos1.name("cos1");
+ cosList.add(cos1);
+
+ List<BwpGroup> bwpGroupList = new ArrayList<BwpGroup>();
+ BwpGroup bwpGrp = new DefaultBwpGroup();
+ bwpGrp.groupIndex((short) 0);
+ bwpGroupList.add(bwpGrp);
+
+ List<Bwp> bwpList = new ArrayList<Bwp>();
+ Bwp bwp1 = new DefaultBwp();
+ bwp1.cosIndex(0);
+ bwp1.colorMode(ColorModeEnum.COLORAWARE);
+ bwpList.add(bwp1);
+
+ Bwp bwp2 = new DefaultBwp();
+ bwp2.cosIndex(1);
+ bwp2.colorMode(ColorModeEnum.COLORBLIND);
+ bwpList.add(bwp2);
+
+ BwpGroup bwpGrp1 = new DefaultBwpGroup();
+ bwpGrp1.groupIndex((short) 1);
+ bwpGrp1.bwp(bwpList);
+ bwpGroupList.add(bwpGrp1);
+
+ Profiles profiles = new DefaultProfiles();
+ profiles.bwpGroup(bwpGroupList);
+
+ MefServices mefServices = new DefaultMefServices();
+ mefServices.profiles(profiles);
+
+ MseaUniEvcServiceOpParam evcUni = new MseaUniEvcServiceOpParam();
+ evcUni.mefServices(mefServices);
+ try {
+ mseaUniEvcServiceSvc.deleteMseaUniEvcService(evcUni, session, DatastoreId.RUNNING);
+ } catch (NetconfException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ fail("Error: " + e.getMessage());
+ }
+ }
+
+ @Test
+ public void testGetMseaUniEvcCeVlanMaps() {
+
+ try {
+ MseaUniEvcService ceVlanMapsResult7 =
+ mseaUniEvcServiceSvc.getmseaUniEvcCeVlanMaps(session, DatastoreId.RUNNING);
+
+ assertNotNull(ceVlanMapsResult7.mefServices().uni().evc());
+
+ List<Evc> evcList = ceVlanMapsResult7.mefServices().uni().evc();
+ assertEquals(3, evcList.size());
+ for (Evc evc : evcList) {
+ assertNotNull(evc.evcPerUni().evcPerUnic().ceVlanMap());
+ assertNotNull(evc.evcPerUni().evcPerUnin().ceVlanMap());
+
+ if (evc.evcIndex() == 7) {
+ assertEquals("700,710,720", evc.evcPerUni().evcPerUnic().ceVlanMap().string());
+ assertEquals("701:703", evc.evcPerUni().evcPerUnin().ceVlanMap().string());
+ }
+ }
+
+ } catch (NetconfException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ fail("Error: " + e.getMessage());
+ }
+ }
+
+ @Test
+ public void testChangeEvcCeVlanMap() {
+ EvcPerUnin epun1 = new CustomEvcPerUnin();
+ epun1.evcPerUniServiceType(EvcPerUniServiceTypeEnum.EVPL);
+ epun1.ceVlanMap(ServiceListType.fromString("10"));
+ epun1.ingressBwpGroupIndex("0");
+
+ EvcPerUnic epuc1 = new CustomEvcPerUnic();
+ epuc1.ceVlanMap(new ServiceListType("11"));
+ epuc1.ingressBwpGroupIndex("0");
+
+ EvcPerUni epu = new DefaultEvcPerUni();
+ epu.evcPerUnic(epuc1);
+ epu.evcPerUnin(epun1);
+
+ Evc evc = new DefaultEvc();
+ evc.evcPerUni(epu);
+
+ assertEquals("10", evc.evcPerUni().evcPerUnin().ceVlanMap().string());
+ assertEquals("11", evc.evcPerUni().evcPerUnic().ceVlanMap().string());
+
+ assertEquals("11", evc.evcPerUni().evcPerUnic().ceVlanMap().string());
+ }
+
+ @Test
+ public void testChangeEvcCeVlanMapNoValues() {
+ EvcPerUnin epun1 = new CustomEvcPerUnin();
+ epun1.evcPerUniServiceType(EvcPerUniServiceTypeEnum.EVPL);
+ epun1.ingressBwpGroupIndex("0");
+
+ EvcPerUnic epuc1 = new CustomEvcPerUnic();
+ epuc1.ingressBwpGroupIndex("0");
+
+ EvcPerUni epu = new DefaultEvcPerUni();
+ epu.evcPerUnic(epuc1);
+ epu.evcPerUnin(epun1);
+
+ Evc evc = new DefaultEvc();
+ evc.evcIndex(1);
+ evc.evcPerUni(epu);
+
+ assertEquals("0", evc.evcPerUni().evcPerUnin().ceVlanMap().string());
+ assertEquals("0", evc.evcPerUni().evcPerUnic().ceVlanMap().string());
+ }
+
+ @Test
+ public void testRemoveEvcUniFlowEntries() {
+
+ Map<Integer, String> ceVlanUpdates = new TreeMap<>();
+ ceVlanUpdates.put((1 << 2), "");
+ ceVlanUpdates.put((1 << 2) + 1, "");
+ ceVlanUpdates.put((2 << 2), "");
+ ceVlanUpdates.put((2 << 2) + 1, "");
+
+ ceVlanUpdates.put((7 << 2), "700,710,720");
+ ceVlanUpdates.put((7 << 2) + 1, "701:703");
+ ceVlanUpdates.put((8 << 2), "800,810,820");
+ ceVlanUpdates.put((8 << 2) + 1, "801,802,803");
+
+ Map<Integer, List<Short>> flowVlanIdMap = new HashMap<>();
+ //These should get ignored because whole EVC is being deleted
+ flowVlanIdMap.put(1 << 2, new ArrayList<Short>());
+ flowVlanIdMap.get(1 << 2).add((short) 11);
+
+ flowVlanIdMap.put((1 << 2) + 1, new ArrayList<Short>());
+ flowVlanIdMap.get((1 << 2) + 1).add((short) 12L);
+
+ //These are the EVCs being removed
+ flowVlanIdMap.put(7 << 2, new ArrayList<Short>());
+ flowVlanIdMap.get(7 << 2).add((short) 730L);
+ flowVlanIdMap.get(7 << 2).add((short) 740L);
+
+ flowVlanIdMap.put((7 << 2) + 1, new ArrayList<Short>());
+ flowVlanIdMap.get((7 << 2) + 1).add((short) 705L);
+ flowVlanIdMap.get((7 << 2) + 1).add((short) 706L);
+
+ flowVlanIdMap.put(8 << 2, new ArrayList<Short>());
+ flowVlanIdMap.get(8 << 2).add((short) 830L);
+ flowVlanIdMap.get(8 << 2).add((short) 840L);
+
+ flowVlanIdMap.put((8 << 2) + 1, new ArrayList<Short>());
+ flowVlanIdMap.get((8 << 2) + 1).add((short) 805L);
+ flowVlanIdMap.get((8 << 2) + 1).add((short) 806L);
+
+ try {
+ mseaUniEvcServiceSvc.removeEvcUniFlowEntries(
+ ceVlanUpdates, flowVlanIdMap, session, DatastoreId.RUNNING,
+ UniSideInterfaceAssignmentEnum.UNI_C_ON_OPTICS);
+ } catch (NetconfException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ fail("Error: " + e.getMessage());
+ }
+ }
+
+ @Test
+ public void testGetVlanSet1() {
+ Short[] vlanIds = CeVlanMapUtils.getVlanSet("10");
+ assertEquals(1, vlanIds.length);
+ }
+
+ @Test
+ public void testGetVlanSet2() {
+ Short[] vlanIds = CeVlanMapUtils.getVlanSet("10:20");
+ assertEquals(11, vlanIds.length);
+ assertEquals(10, vlanIds[0].shortValue());
+ assertEquals(20, vlanIds[10].shortValue());
+ }
+
+ @Test
+ public void testGetVlanSet3() {
+ Short[] vlanIds = CeVlanMapUtils.getVlanSet("10:20,30:40");
+ assertEquals(22, vlanIds.length);
+ assertEquals(10, vlanIds[0].shortValue());
+ assertEquals(40, vlanIds[21].shortValue());
+ }
+
+ @Test
+ public void testGetVlanSet4() {
+ Short[] vlanIds = CeVlanMapUtils.getVlanSet("10,20,30");
+ assertEquals(3, vlanIds.length);
+ assertEquals(10, vlanIds[0].shortValue());
+ assertEquals(30, vlanIds[2].shortValue());
+ }
+
+ @Test
+ public void testVlanListAsString() {
+ assertEquals("20:22", CeVlanMapUtils.vlanListAsString(new Short[]{20, 21, 22}));
+
+ assertEquals("20:22,24:25",
+ CeVlanMapUtils.vlanListAsString(new Short[]{20, 21, 22, 24, 25}));
+
+ assertEquals("30,33,36:40",
+ CeVlanMapUtils.vlanListAsString(new Short[]{30, 33, 36, 37, 38, 39, 40}));
+
+ assertEquals("20", CeVlanMapUtils.vlanListAsString(new Short[]{20}));
+
+ assertEquals("20,22,24,26,28",
+ CeVlanMapUtils.vlanListAsString(new Short[]{20, 22, 24, 26, 28}));
+ }
+
+ @Test
+ public void testAddtoCeVlanMap() {
+ assertEquals("20,22:24,26,28",
+ CeVlanMapUtils.addtoCeVlanMap("20,22,24,26,28", (short) 23));
+
+ assertEquals("20:26,28",
+ CeVlanMapUtils.addtoCeVlanMap("20,21,22,24,25,26,28", (short) 23));
+
+ assertEquals("20,23",
+ CeVlanMapUtils.addtoCeVlanMap("20", (short) 23));
+
+ assertEquals("20,22:23",
+ CeVlanMapUtils.addtoCeVlanMap("20,22", (short) 23));
+ }
+
+ @Test
+ public void testCombineVlanSets() {
+ assertEquals("10:11,13:14", CeVlanMapUtils.combineVlanSets("10:11", "13:14"));
+
+ assertEquals("10:14", CeVlanMapUtils.combineVlanSets("10:11", "12:14"));
+
+ assertEquals("10:11,14", CeVlanMapUtils.combineVlanSets("10:11", "14"));
+
+ assertEquals("10:12", CeVlanMapUtils.combineVlanSets("10:11", "11:12"));
+ }
+
+ @Test
+ public void testRemoveZeroIfPossible() {
+ assertEquals("0", CeVlanMapUtils.removeZeroIfPossible(""));
+
+ assertEquals("0", CeVlanMapUtils.removeZeroIfPossible("0"));
+
+ assertEquals("1,3", CeVlanMapUtils.removeZeroIfPossible("0:1,3"));
+
+ assertEquals("1:2", CeVlanMapUtils.removeZeroIfPossible("0:2"));
+
+ assertEquals("10:12", CeVlanMapUtils.removeZeroIfPossible("0,10:12"));
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/package-info.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/package-info.java
new file mode 100644
index 0000000..4173ece
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package for Microsemi device drivers support for NETCONF for EA1000.
+ */
+package org.onosproject.drivers.microsemi.yang;
\ No newline at end of file
diff --git a/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/utils/IetfYangTypesUtilsTest.java b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/utils/IetfYangTypesUtilsTest.java
new file mode 100644
index 0000000..da0954f
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/drivers/microsemi/yang/utils/IetfYangTypesUtilsTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.microsemi.yang.utils;
+
+import static org.junit.Assert.assertEquals;
+
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.ietfyangtypes.rev20130715.ietfyangtypes.DateAndTime;
+
+public class IetfYangTypesUtilsTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testFromYangDateTime() {
+ OffsetDateTime odt = IetfYangTypesUtils.fromYangDateTime(DateAndTime.fromString("2015-07-08T12:49:20.9Z"));
+ assertEquals(OffsetDateTime.of(2015, 7, 8, 12, 49, 20, 900000000, ZoneOffset.UTC), odt);
+ }
+
+ @Test
+ public void testFromYangDateTimeZoned() {
+ ZonedDateTime zdt = IetfYangTypesUtils.fromYangDateTimeZoned(DateAndTime.fromString("2015-07-08T12:49:20.9Z"),
+ ZoneId.systemDefault());
+
+ assertEquals(OffsetDateTime.of(2015, 7, 8, 12, 49, 20, 900000000, ZoneOffset.UTC).toInstant(),
+ zdt.toOffsetDateTime().toInstant());
+ }
+
+ @Test
+ public void testFromYangDateTimeToLocal() {
+ LocalDateTime ldt = IetfYangTypesUtils
+ .fromYangDateTimeToLocal(DateAndTime.fromString("2015-07-08T12:49:20.9Z"));
+
+ OffsetDateTime odtExpected = OffsetDateTime.of(2015, 7, 8, 12, 49, 20, 900000000, ZoneOffset.UTC);
+ ZoneOffset offsetForcurrentZone = ZoneId.systemDefault().getRules().getOffset(ldt);
+ assertEquals(odtExpected.toInstant(), ldt.toInstant(offsetForcurrentZone));
+ }
+
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/yang/MockYangRuntimeManager.java b/drivers/microsemi/src/test/java/org/onosproject/yang/MockYangRuntimeManager.java
new file mode 100644
index 0000000..e2f4389
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/yang/MockYangRuntimeManager.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.yang;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.core.CoreService;
+import org.onosproject.drivers.netconf.MockCoreService;
+import org.onosproject.yang.model.ModelConverter;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.NodeKey;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.model.SchemaContext;
+import org.onosproject.yang.model.SchemaContextProvider;
+import org.onosproject.yang.model.YangModel;
+import org.onosproject.yang.runtime.CompositeData;
+import org.onosproject.yang.runtime.CompositeStream;
+import org.onosproject.yang.runtime.ModelRegistrationParam;
+import org.onosproject.yang.runtime.RuntimeContext;
+import org.onosproject.yang.runtime.YangModelRegistry;
+import org.onosproject.yang.runtime.YangRuntimeService;
+import org.onosproject.yang.runtime.YangSerializer;
+import org.onosproject.yang.runtime.YangSerializerRegistry;
+import org.onosproject.yang.runtime.impl.DefaultModelConverter;
+import org.onosproject.yang.runtime.impl.DefaultYangModelRegistry;
+import org.onosproject.yang.runtime.impl.DefaultYangRuntimeHandler;
+import org.onosproject.yang.runtime.impl.DefaultYangSerializerRegistry;
+import org.onosproject.yang.serializers.json.JsonSerializer;
+import org.onosproject.yang.serializers.xml.XmlSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class MockYangRuntimeManager implements YangModelRegistry,
+ YangSerializerRegistry, YangRuntimeService, ModelConverter,
+ SchemaContextProvider {
+
+ private static final String APP_ID = "org.onosproject.yang";
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ private DefaultYangModelRegistry modelRegistry;
+ private DefaultYangSerializerRegistry serializerRegistry;
+ private DefaultYangRuntimeHandler runtimeService;
+ private DefaultModelConverter modelConverter;
+
+ public void setModelRegistry(DefaultYangModelRegistry yReg) {
+ this.modelRegistry = yReg;
+ }
+
+ @Activate
+ public void activate() {
+ coreService = new MockCoreService();
+ coreService.registerApplication(APP_ID);
+ serializerRegistry = new DefaultYangSerializerRegistry();
+ runtimeService =
+ new DefaultYangRuntimeHandler(serializerRegistry, modelRegistry);
+ serializerRegistry.registerSerializer(new JsonSerializer());
+ serializerRegistry.registerSerializer(new XmlSerializer());
+ modelConverter = new DefaultModelConverter(modelRegistry);
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ log.info("Stopped");
+ }
+
+
+ @Override
+ public void registerModel(ModelRegistrationParam p) {
+ modelRegistry.registerModel(p);
+ }
+
+ @Override
+ public void unregisterModel(ModelRegistrationParam p) {
+ modelRegistry.unregisterModel(p);
+ }
+
+ @Override
+ public Set<YangModel> getModels() {
+ return modelRegistry.getModels();
+ }
+
+ @Override
+ public void registerSerializer(YangSerializer ys) {
+ serializerRegistry.registerSerializer(ys);
+ }
+
+ @Override
+ public void unregisterSerializer(YangSerializer ys) {
+ serializerRegistry.unregisterSerializer(ys);
+ }
+
+ @Override
+ public Set<YangSerializer> getSerializers() {
+ return serializerRegistry.getSerializers();
+ }
+
+ @Override
+ public CompositeData decode(CompositeStream cs, RuntimeContext rc) {
+ return runtimeService.decode(cs, rc);
+ }
+
+ @Override
+ public CompositeStream encode(CompositeData cd, RuntimeContext rc) {
+ return runtimeService.encode(cd, rc);
+ }
+
+ @Override
+ public ModelObjectData createModel(ResourceData resourceData) {
+ return modelConverter.createModel(resourceData);
+ }
+
+ @Override
+ public ResourceData createDataNode(ModelObjectData modelObjectData) {
+ return modelConverter.createDataNode(modelObjectData);
+ }
+
+ @Override
+ public SchemaContext getSchemaContext(ResourceId resourceId) {
+ checkNotNull(resourceId, " resource id can't be null.");
+ NodeKey key = resourceId.nodeKeys().get(0);
+ if (resourceId.nodeKeys().size() == 1 &&
+ "/".equals(key.schemaId().name())) {
+ return modelRegistry;
+ }
+ log.info("To be implemented.");
+ return null;
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/yang/serializers/xml/MockYangSchemaNodeProvider.java b/drivers/microsemi/src/test/java/org/onosproject/yang/serializers/xml/MockYangSchemaNodeProvider.java
new file mode 100644
index 0000000..dab269d
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/yang/serializers/xml/MockYangSchemaNodeProvider.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.yang.serializers.xml;
+
+
+import org.onosproject.yang.compiler.datamodel.YangNode;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.model.YangModel;
+import org.onosproject.yang.runtime.AppModuleInfo;
+import org.onosproject.yang.runtime.DefaultAppModuleInfo;
+import org.onosproject.yang.runtime.DefaultModelRegistrationParam;
+import org.onosproject.yang.runtime.ModelRegistrationParam;
+import org.onosproject.yang.runtime.YangModelRegistry;
+import org.onosproject.yang.runtime.impl.DefaultYangModelRegistry;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.onosproject.yang.compiler.datamodel.utils.DataModelUtils;
+import org.onosproject.yang.compiler.utils.UtilConstants;
+import org.onosproject.yang.compiler.utils.io.impl.YangIoUtils;
+import org.onosproject.yang.runtime.helperutils.YangApacheUtils;
+import org.onosproject.yang.runtime.RuntimeHelper;
+
+public class MockYangSchemaNodeProvider {
+
+ private static final String FS = File.separator;
+ private static final String PATH = System.getProperty("user.dir") +
+ FS + "buck-out" + FS + "gen" +
+ FS + "models" + FS + "microsemi" + FS + "onos-models-microsemi-schema" + FS;
+ private static final String SER_FILE_PATH = "yang" + FS + "resources" +
+ FS + "YangMetaData.ser";
+ private static final String META_PATH =
+ PATH.replace("drivers/microsemi", "")
+ + SER_FILE_PATH;
+ private static final String TEMP_FOLDER_PATH = PATH + UtilConstants.TEMP;
+ private YangModelRegistry reg = new DefaultYangModelRegistry();
+ private List<YangNode> nodes = new ArrayList<>();
+
+ /**
+ * Creates an instance of mock bundle context.
+ */
+ public MockYangSchemaNodeProvider() {
+ }
+
+ /**
+ * Process YANG schema node for a application.
+ */
+ public void processSchemaRegistry() {
+ try {
+ //Need to deserialize generated meta data file for unit tests.
+ Set<YangNode> appNode = DataModelUtils.deSerializeDataModel(META_PATH);
+ RuntimeHelper.addLinkerAndJavaInfo(appNode);
+ nodes.addAll(appNode);
+ reg.registerModel(prepareParam(nodes));
+ YangIoUtils.deleteDirectory(TEMP_FOLDER_PATH);
+ } catch (IOException e) {
+ throw new IllegalArgumentException("YangMetaData.ser could not " +
+ "be loaded from " + META_PATH, e);
+ }
+ }
+
+ /**
+ * Unregister given nodes from runtime service.
+ *
+ * @param nodes list of nodes
+ */
+ public void unRegister(List<YangNode> nodes) {
+ reg.unregisterModel(prepareParam(nodes));
+ }
+
+ /**
+ * Prepares model registration parameter.
+ *
+ * @param nodes list of nodes
+ * @return model registration parameter
+ */
+ private ModelRegistrationParam prepareParam(List<YangNode> nodes) {
+ //Process loading class file.
+ String appName;
+ ClassLoader classLoader = getClass().getClassLoader();
+
+ //Create model registration param.
+ ModelRegistrationParam.Builder b =
+ DefaultModelRegistrationParam.builder();
+
+ //create a new YANG model
+ YangModel model = YangApacheUtils.processYangModel(META_PATH, nodes);
+ //set YANG model
+ b.setYangModel(model);
+
+ Iterator<YangNode> it = nodes.iterator();
+ while (it.hasNext()) {
+ YangSchemaNode node = it.next();
+
+ //If service class is not generated then use
+ // interface file to load this class.
+ appName = RuntimeHelper.getInterfaceClassName(node);
+ Class<?> cls;
+ try {
+ cls = classLoader.loadClass(appName);
+ } catch (ClassNotFoundException e) {
+ continue;
+ }
+
+ //generate app info.
+ AppModuleInfo info = new DefaultAppModuleInfo(cls, null);
+ b.addAppModuleInfo(YangApacheUtils.processModuleId((YangNode) node), info);
+ }
+ return b.build();
+ }
+
+ /**
+ * Returns schema registry.
+ *
+ * @return schema registry
+ */
+ public DefaultYangModelRegistry registry() {
+ return (DefaultYangModelRegistry) reg;
+ }
+}
diff --git a/drivers/microsemi/src/test/java/org/onosproject/yang/serializers/xml/MockYangSerializerContext.java b/drivers/microsemi/src/test/java/org/onosproject/yang/serializers/xml/MockYangSerializerContext.java
new file mode 100644
index 0000000..cfe7b9b
--- /dev/null
+++ b/drivers/microsemi/src/test/java/org/onosproject/yang/serializers/xml/MockYangSerializerContext.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.yang.serializers.xml;
+
+import org.onosproject.yang.model.SchemaContext;
+import org.onosproject.yang.runtime.Annotation;
+import org.onosproject.yang.runtime.DefaultAnnotation;
+import org.onosproject.yang.runtime.YangSerializerContext;
+import org.onosproject.yang.runtime.impl.DefaultYangModelRegistry;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class MockYangSerializerContext implements YangSerializerContext {
+
+ private static MockYangSchemaNodeProvider schemaProvider =
+ new MockYangSchemaNodeProvider();
+ private static final String NETCONF_NS =
+ "urn:ietf:params:xml:ns:netconf:base:1.0";
+ private static final String XMNLS_NC = "xmlns:xc";
+
+
+ @Override
+ public SchemaContext getContext() {
+ schemaProvider.processSchemaRegistry();
+ DefaultYangModelRegistry registry = schemaProvider.registry();
+ return registry;
+ }
+
+ @Override
+ public List<Annotation> getProtocolAnnotations() {
+ Annotation annotation = new DefaultAnnotation(XMNLS_NC, NETCONF_NS);
+ List<Annotation> protocolAnnotation = new LinkedList<>();
+ protocolAnnotation.add(annotation);
+ return protocolAnnotation;
+ }
+}
diff --git a/drivers/microsemi/src/test/resources/CarrierEthernetFeature-sampleEvcConfig1.txt b/drivers/microsemi/src/test/resources/CarrierEthernetFeature-sampleEvcConfig1.txt
new file mode 100644
index 0000000..04db8030
--- /dev/null
+++ b/drivers/microsemi/src/test/resources/CarrierEthernetFeature-sampleEvcConfig1.txt
@@ -0,0 +1,85 @@
+onos> ce-evc-list
+CarrierEthernetVirtualConnection{
+ id=EP-Line-1, cfgId=evpl1, type=POINT_TO_POINT, state=ACTIVE,
+ UNIs=[
+ CarrierEthernetUni{
+ id=netconf:192.168.56.10:830/0,
+ cfgId=netconf:192.168.56.10:830/0,
+ role=Root,
+ refCount=0,
+ ceVlanIds=[100],
+ capacity=1000000000,
+ usedCapacity=3.0E8,
+ bandwidthProfiles=[
+ CarrierEthernetBandwidthProfile{
+ id=FC-1,
+ type=EVC,
+ cir=3.0E8,
+ cbs=2000,
+ eir=0.0,
+ ebs=0}]},
+ CarrierEthernetUni{
+ id=netconf:192.168.56.20:830/0,
+ cfgId=netconf:192.168.56.20:830/0,
+ role=Root,
+ refCount=0,
+ ceVlanIds=[100],
+ capacity=1000000000,
+ usedCapacity=3.0E8,
+ bandwidthProfiles=[
+ CarrierEthernetBandwidthProfile{
+ id=FC-1,
+ type=EVC,
+ cir=3.0E8,
+ cbs=2000,
+ eir=0.0,
+ ebs=0}]}],
+ FCs=[
+ CarrierEthernetForwardingConstruct{
+ id=FC-1,
+ cfgId=null,
+ type=POINT_TO_POINT,
+ vlanId=1,
+ metroConnectId=null,
+ refCount=1,
+ LTPs=[
+ CarrierEthernetLogicalTerminationPoint{
+ id=netconf:192.168.56.10:830/0,
+ cfgId=netconf:192.168.56.10:830/0,
+ role=Root,
+ ni=CarrierEthernetUni{
+ id=netconf:192.168.56.10:830/0,
+ cfgId=netconf:192.168.56.10:830/0,
+ role=Root,
+ refCount=0,
+ ceVlanIds=[100],
+ capacity=1000000000,
+ usedCapacity=3.0E8,
+ bandwidthProfiles=[
+ CarrierEthernetBandwidthProfile{
+ id=FC-1,
+ type=EVC,
+ cir=3.0E8,
+ cbs=2000,
+ eir=0.0,
+ ebs=0}]}},
+ CarrierEthernetLogicalTerminationPoint{
+ id=netconf:192.168.56.20:830/0,
+ cfgId=netconf:192.168.56.20:830/0,
+ role=Root,
+ ni=CarrierEthernetUni{
+ id=netconf:192.168.56.20:830/0,
+ cfgId=netconf:192.168.56.20:830/0,
+ role=Root,
+ refCount=0,
+ ceVlanIds=[100],
+ capacity=1000000000,
+ usedCapacity=3.0E8,
+ bandwidthProfiles=[
+ CarrierEthernetBandwidthProfile{
+ id=FC-1,
+ type=EVC,
+ cir=3.0E8,
+ cbs=2000,
+ eir=0.0,
+ ebs=0}]}}]}]}
diff --git a/drivers/microsemi/src/test/resources/getConfigSaFiltering.xml b/drivers/microsemi/src/test/resources/getConfigSaFiltering.xml
new file mode 100644
index 0000000..53bfe46
--- /dev/null
+++ b/drivers/microsemi/src/test/resources/getConfigSaFiltering.xml
@@ -0,0 +1,11 @@
+<rpc message-id="101"
+ xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <get-config>
+ <source>
+ <running/>
+ </source>
+ <filter type="subtree">
+ <source-ipaddress-filtering xmlns="http://www.microsemi.com/microsemi-edge-assure/msea-sa-filtering"/>
+ </filter>
+ </get-config>
+</rpc>
\ No newline at end of file
diff --git a/drivers/microsemi/src/test/resources/getConfigSaFilteringReply.xml b/drivers/microsemi/src/test/resources/getConfigSaFilteringReply.xml
new file mode 100644
index 0000000..6e1e040
--- /dev/null
+++ b/drivers/microsemi/src/test/resources/getConfigSaFilteringReply.xml
@@ -0,0 +1,14 @@
+<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="7">
+ <data>
+ <source-ipaddress-filtering xmlns="http://www.microsemi.com/microsemi-edge-assure/msea-sa-filtering">
+ <interface-eth0>
+ <source-address-range>
+ <range-id>1</range-id>
+ <ipv4-address-prefix>10.10.10.10/16</ipv4-address-prefix>
+ <name>Filter1</name>
+ </source-address-range>
+ <filter-admin-state>inactive</filter-admin-state>
+ </interface-eth0>
+ </source-ipaddress-filtering>
+ </data>
+</rpc-reply>
\ No newline at end of file
diff --git a/drivers/microsemi/src/test/resources/systemReply-Sample1.xml b/drivers/microsemi/src/test/resources/systemReply-Sample1.xml
new file mode 100644
index 0000000..206bf45
--- /dev/null
+++ b/drivers/microsemi/src/test/resources/systemReply-Sample1.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
+ <data>
+ <system xmlns="urn:ietf:params:xml:ns:yang:ietf-system">
+ <longitude xmlns="http://www.microsemi.com/microsemi-edge-assure/msea-system">-8.4683990</longitude>
+ <latitude xmlns="http://www.microsemi.com/microsemi-edge-assure/msea-system">51.9036140</latitude>
+ </system>
+ <system-state xmlns="urn:ietf:params:xml:ns:yang:ietf-system" xmlns:sysms="http://www.microsemi.com/microsemi-edge-assure/msea-system">
+ <platform>
+ <os-release>2.6.33-arm1-MSEA1000--00326-g643be76.x.0.0.212</os-release>
+ <sysms:device-identification>
+ <sysms:serial-number>Eagle Simulator.</sysms:serial-number>
+ </sysms:device-identification>
+ </platform>
+ </system-state>
+ </data>
+</rpc-reply>
\ No newline at end of file
diff --git a/drivers/microsemi/src/test/resources/systemReply-Sample2.xml b/drivers/microsemi/src/test/resources/systemReply-Sample2.xml
new file mode 100644
index 0000000..9592538
--- /dev/null
+++ b/drivers/microsemi/src/test/resources/systemReply-Sample2.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
+ <data>
+ <system-state xmlns="urn:ietf:params:xml:ns:yang:ietf-system">
+ <platform/>
+ </system-state>
+ </data>
+</rpc-reply>
\ No newline at end of file