/* * 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 static org.onosproject.yms.ych.YangProtocolEncodingFormat.XML; import static org.onosproject.yms.ydt.YmsOperationType.QUERY_CONFIG_REPLY; 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.NetconfException; import org.onosproject.netconf.NetconfSession; import org.onosproject.netconf.TargetConfig; import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.MseaUniEvcService; import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.MseaUniEvcServiceOpParam; import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.MseaUniEvcServiceService; import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.uni.UniSideInterfaceAssignmentEnum; /** * 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_SA_FILTERING = "org.onosproject.drivers.microsemi.yang.mseaunievcservice"; @Activate public void activate() { appId = coreService.registerApplication(MSEA_SA_FILTERING); ych = ymsService.getYangCodecHandler(); ych.addDeviceSchema(MseaUniEvcServiceService.class); log.info("MseaUniEvcServiceManager Started"); } @Deactivate public void deactivate() { super.deactivate(); ymsService.unRegisterService(this, MseaUniEvcServiceService.class); ych = null; log.info("MseaUniEvcServiceManager Stopped"); } @Override public MseaUniEvcService getMseaUniEvcService( MseaUniEvcServiceOpParam mseaUniEvcService, NetconfSession session) throws NetconfException { return (MseaUniEvcService) getNetconfObject(mseaUniEvcService, session); } @Override public MseaUniEvcService getConfigMseaUniEvcService( MseaUniEvcServiceOpParam mseaUniEvcService, NetconfSession session, TargetConfig targetDs) throws NetconfException { return (MseaUniEvcService) getConfigNetconfObject(mseaUniEvcService, session, targetDs); } /** * Modify the configuration. */ @Override public void setMseaUniEvcService( MseaUniEvcServiceOpParam mseaUniEvcService, NetconfSession session, TargetConfig ncDs) throws NetconfException { setNetconfObject(mseaUniEvcService, session, ncDs); } @Override public MseaUniEvcService getmseaUniEvcCeVlanMaps( NetconfSession session, TargetConfig ncDs) throws NetconfException { if (session == null) { throw new NetconfException("Session is null when calling getMseaSaFiltering()"); } String xmlResult = session.getConfig(ncDs, evcFilterQuery()); List<Object> objectList = ych.decode(xmlResult, XML, QUERY_CONFIG_REPLY); if (objectList != null && objectList.size() > 0) { return (MseaUniEvcService) objectList.get(0); } return null; } @Override public void removeEvcUniFlowEntries( Map<Integer, String> ceVlanUpdates, Map<Integer, List<Short>> flowVlanIds, NetconfSession session, TargetConfig 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(); } }