| /* |
| * 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(); |
| } |
| } |