Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2017-present Open Networking Laboratory |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | package org.onosproject.drivers.microsemi.yang.impl; |
| 17 | |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 18 | import java.io.ByteArrayInputStream; |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 19 | import java.util.ArrayList; |
| 20 | import java.util.List; |
| 21 | import java.util.Map; |
| 22 | |
| 23 | import org.apache.felix.scr.annotations.Activate; |
| 24 | import org.apache.felix.scr.annotations.Component; |
| 25 | import org.apache.felix.scr.annotations.Deactivate; |
| 26 | import org.apache.felix.scr.annotations.Service; |
| 27 | import org.onosproject.drivers.microsemi.yang.MseaUniEvcServiceNetconfService; |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 28 | import org.onosproject.netconf.DatastoreId; |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 29 | import org.onosproject.netconf.NetconfException; |
| 30 | import org.onosproject.netconf.NetconfSession; |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 31 | import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcService; |
| 32 | import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcServiceOpParam; |
| 33 | import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.MefServices; |
| 34 | import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.BwpGroup; |
| 35 | import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.UniSideInterfaceAssignmentEnum; |
| 36 | import org.onosproject.yang.model.DefaultModelObjectData; |
| 37 | import org.onosproject.yang.model.ModelConverter; |
| 38 | import org.onosproject.yang.model.ModelObject; |
| 39 | import org.onosproject.yang.model.ModelObjectData; |
| 40 | import org.onosproject.yang.model.ResourceId; |
| 41 | import org.onosproject.yang.runtime.AnnotatedNodeInfo; |
| 42 | import org.onosproject.yang.runtime.CompositeData; |
| 43 | import org.onosproject.yang.runtime.DefaultAnnotatedNodeInfo; |
| 44 | import org.onosproject.yang.runtime.DefaultAnnotation; |
| 45 | import org.onosproject.yang.runtime.DefaultCompositeStream; |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 46 | |
| 47 | /** |
| 48 | * Implementation of the MseaUniEvcServiceService YANG model service. |
| 49 | */ |
| 50 | @Component(immediate = true, inherit = true) |
| 51 | @Service |
| 52 | public class MseaUniEvcServiceManager extends AbstractYangServiceImpl |
| 53 | implements MseaUniEvcServiceNetconfService { |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 54 | public static final String MSEA_UNI_EVC_SVC = |
| 55 | "org.onosproject.drivers.microsemi.yang.mseaunievcservice"; |
| 56 | public static final String MSEA_UNI_EVC_SVC_NS = |
| 57 | "http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service"; |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 58 | |
| 59 | @Activate |
| 60 | public void activate() { |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 61 | super.activate(); |
| 62 | appId = coreService.registerApplication(MSEA_UNI_EVC_SVC); |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 63 | log.info("MseaUniEvcServiceManager Started"); |
| 64 | } |
| 65 | |
| 66 | @Deactivate |
| 67 | public void deactivate() { |
| 68 | super.deactivate(); |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 69 | log.info("MseaUniEvcServiceManager Stopped"); |
| 70 | } |
| 71 | |
| 72 | @Override |
| 73 | public MseaUniEvcService getMseaUniEvcService( |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 74 | MseaUniEvcServiceOpParam mseaUniEvcService, NetconfSession session) |
| 75 | throws NetconfException { |
| 76 | |
| 77 | return getConfigMseaUniEvcService(mseaUniEvcService, session, null); |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 78 | } |
| 79 | |
| 80 | @Override |
| 81 | public MseaUniEvcService getConfigMseaUniEvcService( |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 82 | MseaUniEvcServiceOpParam mseaUniEvcService, NetconfSession session, |
| 83 | DatastoreId targetDs) throws NetconfException { |
| 84 | |
| 85 | ModelObjectData moFilter = DefaultModelObjectData.builder() |
| 86 | .addModelObject((ModelObject) mseaUniEvcService.mefServices()).build(); |
| 87 | |
| 88 | ModelObjectData moReply = getConfigNetconfObject(moFilter, session, targetDs); |
| 89 | |
| 90 | MseaUniEvcService reply = new MseaUniEvcServiceOpParam(); |
| 91 | for (ModelObject mo:moReply.modelObjects()) { |
| 92 | if (mo instanceof MefServices) { |
| 93 | reply.mefServices((MefServices) mo); |
| 94 | } |
| 95 | } |
| 96 | return reply; |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 97 | } |
| 98 | |
| 99 | /** |
| 100 | * Modify the configuration. |
| 101 | */ |
| 102 | @Override |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 103 | public boolean setMseaUniEvcService(MseaUniEvcServiceOpParam mseaUniEvcService, |
| 104 | NetconfSession session, DatastoreId ncDs) throws NetconfException { |
| 105 | ModelObjectData moEdit = DefaultModelObjectData.builder() |
| 106 | .addModelObject((ModelObject) mseaUniEvcService.mefServices()).build(); |
| 107 | |
| 108 | return setNetconfObject(moEdit, session, ncDs, null); |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 109 | } |
| 110 | |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 111 | /** |
| 112 | * Delete the configuration. |
| 113 | */ |
| 114 | @Override |
| 115 | public boolean deleteMseaUniEvcService(MseaUniEvcServiceOpParam mseaUniEvcService, |
| 116 | NetconfSession session, DatastoreId ncDs) throws NetconfException { |
| 117 | ModelObjectData moEdit = DefaultModelObjectData.builder() |
| 118 | .addModelObject((ModelObject) mseaUniEvcService.mefServices()).build(); |
| 119 | |
| 120 | ArrayList anis = new ArrayList<AnnotatedNodeInfo>(); |
| 121 | for (BwpGroup bwpGrp:mseaUniEvcService.mefServices().profiles().bwpGroup()) { |
| 122 | String bwpGroupIndex = String.valueOf(bwpGrp.groupIndex()); |
| 123 | |
| 124 | ResourceId.Builder ridBuilder = ResourceId.builder() |
| 125 | .addBranchPointSchema("/", null) |
| 126 | .addBranchPointSchema("mef-services", MSEA_UNI_EVC_SVC_NS) |
| 127 | .addBranchPointSchema("profiles", MSEA_UNI_EVC_SVC_NS) |
| 128 | .addBranchPointSchema("bwp-group", MSEA_UNI_EVC_SVC_NS) |
| 129 | .addKeyLeaf("group-index", MSEA_UNI_EVC_SVC_NS, bwpGroupIndex); |
| 130 | |
| 131 | AnnotatedNodeInfo ani = DefaultAnnotatedNodeInfo.builder() |
| 132 | .resourceId(ridBuilder.build()) |
| 133 | .addAnnotation(new DefaultAnnotation(NC_OPERATION, OP_DELETE)) |
| 134 | .build(); |
| 135 | |
| 136 | anis.add(ani); |
| 137 | } |
| 138 | |
| 139 | |
| 140 | return setNetconfObject(moEdit, session, ncDs, anis); |
| 141 | } |
| 142 | |
| 143 | |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 144 | @Override |
| 145 | public MseaUniEvcService getmseaUniEvcCeVlanMaps( |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 146 | NetconfSession session, DatastoreId ncDs) |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 147 | throws NetconfException { |
| 148 | if (session == null) { |
| 149 | throw new NetconfException("Session is null when calling getMseaSaFiltering()"); |
| 150 | } |
| 151 | |
| 152 | String xmlResult = session.getConfig(ncDs, evcFilterQuery()); |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 153 | xmlResult = removeRpcReplyData(xmlResult); |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 154 | |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 155 | DefaultCompositeStream resultDcs = new DefaultCompositeStream( |
| 156 | null, new ByteArrayInputStream(xmlResult.getBytes())); |
| 157 | CompositeData compositeData = xSer.decode(resultDcs, yCtx); |
| 158 | |
| 159 | ModelObjectData moReply = ((ModelConverter) yangModelRegistry).createModel(compositeData.resourceData()); |
| 160 | |
| 161 | MseaUniEvcService reply = new MseaUniEvcServiceOpParam(); |
| 162 | for (ModelObject mo:moReply.modelObjects()) { |
| 163 | if (mo instanceof MefServices) { |
| 164 | reply.mefServices((MefServices) mo); |
| 165 | } |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 166 | } |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 167 | return reply; |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 168 | } |
| 169 | |
| 170 | @Override |
| 171 | public void removeEvcUniFlowEntries( |
| 172 | Map<Integer, String> ceVlanUpdates, |
| 173 | Map<Integer, List<Short>> flowVlanIds, |
Sean Condon | 06613e9 | 2017-06-09 15:14:01 +0100 | [diff] [blame^] | 174 | NetconfSession session, DatastoreId targetDs, |
Sean Condon | fae8e66 | 2016-12-15 10:25:13 +0000 | [diff] [blame] | 175 | UniSideInterfaceAssignmentEnum portAssign) throws NetconfException { |
| 176 | |
| 177 | List<Integer> evcAlreadyHandled = new ArrayList<>(); |
| 178 | StringBuilder xmlEvcUpdate = new StringBuilder(evcUniOpener()); |
| 179 | for (Integer evcKey:ceVlanUpdates.keySet()) { |
| 180 | int evcId = (evcKey & ((1 << 8) - 100)) >> 2; |
| 181 | if (evcAlreadyHandled.contains(new Integer(evcId))) { |
| 182 | continue; |
| 183 | } |
| 184 | evcAlreadyHandled.add(evcId); |
| 185 | int port = (evcKey & 3); |
| 186 | String ceVlanMapThis = ceVlanUpdates.get(evcKey); |
| 187 | String ceVlanMapOpposite = ceVlanUpdates.get(evcKey ^ 1); |
| 188 | |
| 189 | if ((ceVlanMapThis == null || ceVlanMapThis.isEmpty()) && |
| 190 | (ceVlanMapOpposite == null || ceVlanMapOpposite.isEmpty())) { |
| 191 | xmlEvcUpdate.append("<evc nc:operation=\"delete\">\n<evc-index>"); |
| 192 | xmlEvcUpdate.append(Integer.toString(evcId)); |
| 193 | xmlEvcUpdate.append("</evc-index>\n</evc>\n"); |
| 194 | } else { |
| 195 | xmlEvcUpdate.append("<evc>\n<evc-index>"); |
| 196 | xmlEvcUpdate.append(Integer.toString(evcId)); |
| 197 | xmlEvcUpdate.append("</evc-index>\n<evc-per-uni>\n"); |
| 198 | if (port == 0 && portAssign == UniSideInterfaceAssignmentEnum.UNI_C_ON_OPTICS || |
| 199 | port == 1 && portAssign == UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST) { |
| 200 | if (ceVlanMapThis != null) { |
| 201 | xmlEvcUpdate.append("<evc-per-uni-c>\n<ce-vlan-map nc:operation=\"replace\">"); |
| 202 | xmlEvcUpdate.append(ceVlanMapThis); |
| 203 | xmlEvcUpdate.append("</ce-vlan-map>\n"); |
| 204 | xmlEvcUpdate.append(deleteFlowMapping(flowVlanIds.get(evcKey))); |
| 205 | xmlEvcUpdate.append("</evc-per-uni-c>\n"); |
| 206 | } |
| 207 | if (ceVlanMapOpposite != null) { |
| 208 | xmlEvcUpdate.append("<evc-per-uni-n>\n<ce-vlan-map nc:operation=\"replace\">"); |
| 209 | xmlEvcUpdate.append(ceVlanMapOpposite); |
| 210 | xmlEvcUpdate.append("</ce-vlan-map>\n"); |
| 211 | xmlEvcUpdate.append(deleteFlowMapping(flowVlanIds.get(evcKey ^ 1))); |
| 212 | xmlEvcUpdate.append("</evc-per-uni-n>\n"); |
| 213 | } |
| 214 | } else { |
| 215 | if (ceVlanMapThis != null) { |
| 216 | xmlEvcUpdate.append("<evc-per-uni-n>\n<ce-vlan-map nc:operation=\"replace\">"); |
| 217 | xmlEvcUpdate.append(ceVlanMapThis); |
| 218 | xmlEvcUpdate.append("</ce-vlan-map>\n"); |
| 219 | xmlEvcUpdate.append(deleteFlowMapping(flowVlanIds.get(evcKey))); |
| 220 | xmlEvcUpdate.append("</evc-per-uni-n>\n"); |
| 221 | } |
| 222 | if (ceVlanMapOpposite != null) { |
| 223 | xmlEvcUpdate.append("<evc-per-uni-c>\n<ce-vlan-map nc:operation=\"replace\">"); |
| 224 | xmlEvcUpdate.append(ceVlanMapOpposite); |
| 225 | xmlEvcUpdate.append("</ce-vlan-map>\n"); |
| 226 | xmlEvcUpdate.append(deleteFlowMapping(flowVlanIds.get(evcKey ^ 1))); |
| 227 | xmlEvcUpdate.append("</evc-per-uni-c>\n"); |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | xmlEvcUpdate.append("</evc-per-uni>\n</evc>\n"); |
| 232 | } |
| 233 | } |
| 234 | xmlEvcUpdate.append("</uni>\n</mef-services>"); |
| 235 | |
| 236 | log.info("Sending XML <edit-config> on NETCONF session " + session.getSessionId() + |
| 237 | ":\n" + xmlEvcUpdate.toString()); |
| 238 | |
| 239 | |
| 240 | session.editConfig(targetDs, null, xmlEvcUpdate.toString()); |
| 241 | } |
| 242 | |
| 243 | |
| 244 | private static String deleteFlowMapping(List<Short> vlanIds) { |
| 245 | if (vlanIds == null || vlanIds.size() == 0) { |
| 246 | return ""; |
| 247 | } |
| 248 | StringBuilder fmXmlBuilder = new StringBuilder(); |
| 249 | for (long vlanId:vlanIds) { |
| 250 | fmXmlBuilder.append("<flow-mapping nc:operation=\"delete\">\n"); |
| 251 | fmXmlBuilder.append("<ce-vlan-id>"); |
| 252 | fmXmlBuilder.append(String.valueOf(vlanId)); |
| 253 | fmXmlBuilder.append("</ce-vlan-id>\n"); |
| 254 | fmXmlBuilder.append("</flow-mapping>\n"); |
| 255 | } |
| 256 | |
| 257 | return fmXmlBuilder.toString(); |
| 258 | } |
| 259 | |
| 260 | private String evcFilterQuery() { |
| 261 | StringBuilder sb = new StringBuilder("<mef-services " |
| 262 | + "xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\">"); |
| 263 | sb.append("<uni>"); |
| 264 | sb.append("<evc>"); |
| 265 | sb.append("<evc-index/>"); |
| 266 | sb.append("<evc-per-uni>"); |
| 267 | sb.append("<evc-per-uni-c>"); |
| 268 | sb.append("<ce-vlan-map/>"); |
| 269 | sb.append("<flow-mapping/>"); |
| 270 | sb.append("<ingress-bwp-group-index/>"); |
| 271 | sb.append("</evc-per-uni-c>"); |
| 272 | sb.append("<evc-per-uni-n>"); |
| 273 | sb.append("<ce-vlan-map/>"); |
| 274 | sb.append("<flow-mapping/>"); |
| 275 | sb.append("<ingress-bwp-group-index/>"); |
| 276 | sb.append("</evc-per-uni-n>"); |
| 277 | sb.append("</evc-per-uni>"); |
| 278 | sb.append("</evc>"); |
| 279 | sb.append("</uni>"); |
| 280 | sb.append("</mef-services>"); |
| 281 | |
| 282 | return sb.toString(); |
| 283 | } |
| 284 | |
| 285 | private String evcUniOpener() { |
| 286 | StringBuilder sb = new StringBuilder("<mef-services "); |
| 287 | sb.append("xmlns=\"http://www.microsemi.com/microsemi-edge-assure/msea-uni-evc-service\">\n"); |
| 288 | sb.append("<uni>\n"); |
| 289 | |
| 290 | return sb.toString(); |
| 291 | } |
| 292 | } |