blob: f965541885f09e70f1d1761c9d3bfc9c1f4a20e0 [file] [log] [blame]
/*
* 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();
}
}