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