blob: 8a25aaeed65d1ed2a90a26773df8123ddb5e11b5 [file] [log] [blame]
Sean Condon0e89bda2017-03-21 14:23:19 +00001/*
2 * Copyright 2017-present Open Networking Foundation
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 */
16package org.onosproject.drivers.microsemi;
17
18import static com.google.common.base.Preconditions.checkNotNull;
Sean Condon96b896d2017-12-11 12:44:29 -080019import static org.onosproject.drivers.microsemi.yang.utils.MaNameUtil.getApiMaIdFromYangMaName;
20import static org.onosproject.drivers.microsemi.yang.utils.MdNameUtil.getApiMdIdFromYangMdName;
21import static org.onosproject.drivers.microsemi.yang.utils.MdNameUtil.getYangMdNameFromApiMdId;
Sean Condon0e89bda2017-03-21 14:23:19 +000022import static org.slf4j.LoggerFactory.getLogger;
23
24import java.time.Duration;
Sean Condon96b896d2017-12-11 12:44:29 -080025import java.util.ArrayList;
Sean Condon0e89bda2017-03-21 14:23:19 +000026import java.util.Collection;
Sean Condon96b896d2017-12-11 12:44:29 -080027import java.util.NoSuchElementException;
28import java.util.Optional;
Sean Condon0e89bda2017-03-21 14:23:19 +000029
Sean Condon0e89bda2017-03-21 14:23:19 +000030import org.onlab.packet.MacAddress;
31import org.onlab.packet.VlanId;
32import org.onlab.util.HexString;
33import org.onosproject.drivers.microsemi.yang.MseaCfmNetconfService;
34import org.onosproject.drivers.microsemi.yang.utils.MaNameUtil;
35import org.onosproject.incubator.net.l2monitoring.cfm.Component;
36import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
37import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLbEntry;
38import org.onosproject.incubator.net.l2monitoring.cfm.DefaultRemoteMepEntry;
39import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
40import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
41import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
42import org.onosproject.incubator.net.l2monitoring.cfm.Mep.MepDirection;
43import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
44import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
45import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
46import org.onosproject.incubator.net.l2monitoring.cfm.MepLbEntry.MepLbEntryBuilder;
47import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
48import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry;
49import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.InterfaceStatusTlvType;
50import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.PortStatusTlvType;
51import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.RemoteMepEntryBuilder;
52import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.RemoteMepState;
53import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
54import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
Sean Condon0e89bda2017-03-21 14:23:19 +000055import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
Sean Condon96b896d2017-12-11 12:44:29 -080056import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepKeyId;
Sean Condon0e89bda2017-03-21 14:23:19 +000057import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
58import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
59import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepProgrammable;
Sean Condon96b896d2017-12-11 12:44:29 -080060import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
Sean Condon0e89bda2017-03-21 14:23:19 +000061import org.onosproject.net.DeviceId;
62import org.onosproject.net.PortNumber;
63import org.onosproject.net.driver.AbstractHandlerBehaviour;
64import org.onosproject.netconf.DatastoreId;
65import org.onosproject.netconf.NetconfController;
66import org.onosproject.netconf.NetconfException;
67import org.onosproject.netconf.NetconfSession;
Sean Condon0e89bda2017-03-21 14:23:19 +000068import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfm;
69import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfmOpParam;
70import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.DefaultMefCfm;
71import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.MefCfm;
72import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.abortloopback.AbortLoopbackInput;
73import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.abortloopback.DefaultAbortLoopbackInput;
74import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.faultalarmdefectbitstype.Bits;
75import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.DefaultMaintenanceDomain;
76import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.DefaultMaintenanceAssociation;
77import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.MdNameAndTypeCombo;
78import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.CcmIntervalEnum;
79import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.ComponentList;
80import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.DefaultComponentList;
81import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.DefaultMaintenanceAssociationEndPoint;
82import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaNameAndTypeCombo;
83import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaintenanceAssociationEndPoint;
84import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.componentlist.TagTypeEnum;
85import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.ContinuityCheck;
86import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.DefaultContinuityCheck;
87import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.InterfaceEnum;
Sean Condon0e89bda2017-03-21 14:23:19 +000088import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.remotemepstatetype.RemoteMepStateTypeEnum;
89import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype.DefaultMacAddress;
90import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype.DefaultMepId;
91import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.DefaultTransmitLoopbackInput;
92import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.TransmitLoopbackInput;
93import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.transmitloopbackinput.DefaultTargetAddress;
94import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.transmitloopbackinput.TargetAddress;
95import org.onosproject.yang.gen.v1.mseasoamfm.rev20160229.mseasoamfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.AugmentedMseaCfmMaintenanceAssociationEndPoint;
96import org.onosproject.yang.gen.v1.mseasoamfm.rev20160229.mseasoamfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint;
Sean Condon0e89bda2017-03-21 14:23:19 +000097import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.MdLevelType;
98import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.MepIdType;
99import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.PriorityType;
100import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.VlanIdType;
101import org.slf4j.Logger;
102
103/**
104 * Implementation of CfmMepProgrammable for Microsemi EA1000.
105 */
106public class EA1000CfmMepProgrammable extends AbstractHandlerBehaviour
107 implements CfmMepProgrammable {
108
109 private static final int NUMERIC_ID_MAX = 64;
Sean Condon0e89bda2017-03-21 14:23:19 +0000110 private static final int COMPONENT_LIST_SIZE = 1;
111 private static final int VIDLIST_SIZE_MIN = 1;
112 private static final int MEP_PORT_MIN = 0;
113 private static final int MEP_PORT_MAX = 1;
Sean Condon3a1efef2018-02-24 13:16:03 +0000114 public static final String MUST_1_64_MSG = " must be between 1 and 64 inclusive for EA1000";
Sean Condon0e89bda2017-03-21 14:23:19 +0000115 private final Logger log = getLogger(getClass());
116
Sean Condon3a1efef2018-02-24 13:16:03 +0000117 /**
118 * Creates the instance of the EA1000CfmMepProgrammable.
119 */
Sean Condon0e89bda2017-03-21 14:23:19 +0000120 public EA1000CfmMepProgrammable() {
121 log.debug("Loaded handler behaviour EA1000CfmMepProgrammable");
122 }
123
124 @Override
125 public boolean createMep(MdId mdName, MaIdShort maName, Mep mep)
126 throws CfmConfigException {
127 NetconfController controller = checkNotNull(handler().get(NetconfController.class));
Sean Condon96b896d2017-12-11 12:44:29 -0800128 NetconfSession session = checkNotNull(controller.getDevicesMap()
129 .get(handler().data().deviceId()).getSession());
Sean Condon0e89bda2017-03-21 14:23:19 +0000130 MseaCfmNetconfService mseaCfmService =
131 checkNotNull(handler().get(MseaCfmNetconfService.class));
Sean Condon96b896d2017-12-11 12:44:29 -0800132 CfmMepService cfmMepService =
133 checkNotNull(handler().get(CfmMepService.class));
Sean Condon0e89bda2017-03-21 14:23:19 +0000134
135 MaintenanceAssociationEndPoint yangMep = buildYangMepFromApiMep(mep);
136
137 CfmMdService cfmMdService = checkNotNull(handler().get(CfmMdService.class));
Sean Condon96b896d2017-12-11 12:44:29 -0800138 MseaCfmOpParam mseaCfmOpParam = getMaYangObject(cfmMdService, mdName, maName);
Sean Condon0e89bda2017-03-21 14:23:19 +0000139
Sean Condon96b896d2017-12-11 12:44:29 -0800140 mseaCfmOpParam.mefCfm().maintenanceDomain().get(0)
141 .maintenanceAssociation().get(0).addToMaintenanceAssociationEndPoint(yangMep);
142 //Add this mepId to the list of remoteMeps on the device
143 mseaCfmOpParam.mefCfm().maintenanceDomain().get(0)
144 .maintenanceAssociation().get(0).addToRemoteMeps(MepIdType.of(mep.mepId().value()));
Sean Condon0e89bda2017-03-21 14:23:19 +0000145
Sean Condon96b896d2017-12-11 12:44:29 -0800146 //Add all of the existing meps on this MD/MA to the remote meps list
Sean Condon3a1efef2018-02-24 13:16:03 +0000147 cfmMepService.getAllMeps(mdName, maName).forEach(m -> mseaCfmOpParam.mefCfm()
148 .maintenanceDomain().get(0).maintenanceAssociation().get(0)
149 .addToRemoteMeps(MepIdType.of(m.mepId().value())));
Sean Condon0e89bda2017-03-21 14:23:19 +0000150 try {
151 mseaCfmService.setMseaCfm(mseaCfmOpParam, session, DatastoreId.RUNNING);
152 log.info("Created MEP {} on device {}", mdName + "/" + maName +
153 "/" + mep.mepId(), handler().data().deviceId());
Sean Condon96b896d2017-12-11 12:44:29 -0800154
Sean Condon0e89bda2017-03-21 14:23:19 +0000155 return true;
156 } catch (NetconfException e) {
157 log.error("Unable to create MEP {}/{}/{} on device {}",
Sean Condon3a1efef2018-02-24 13:16:03 +0000158 mdName, maName, mep.mepId(), handler().data().deviceId(), e);
159 throw new CfmConfigException("Unable to create MEP :" + e.getMessage(), e);
Sean Condon0e89bda2017-03-21 14:23:19 +0000160 }
161 }
162
163 @Override
Sean Condon0e89bda2017-03-21 14:23:19 +0000164 public MepEntry getMep(MdId mdName, MaIdShort maName, MepId mepId)
165 throws CfmConfigException {
166 NetconfController controller = checkNotNull(handler().get(NetconfController.class));
167 if (handler().data().deviceId() == null) {
168 throw new CfmConfigException("Device is not ready - connecting or "
169 + "disconnected for MEP " + mdName + "/" + maName + "/" + mepId);
170 }
Sean Condon96b896d2017-12-11 12:44:29 -0800171 NetconfSession session = checkNotNull(controller.getDevicesMap()
172 .get(handler().data().deviceId()).getSession());
Sean Condon0e89bda2017-03-21 14:23:19 +0000173 MseaCfmNetconfService mseaCfmService = checkNotNull(handler().get(MseaCfmNetconfService.class));
174
175 try {
176 MseaCfm mseacfm =
177 mseaCfmService.getMepFull(mdName, maName, mepId, session);
Sean Condon96b896d2017-12-11 12:44:29 -0800178 Collection<MepEntry> mepEntries = getMepEntriesFromYangResponse(mseacfm);
179 if (mepEntries == null || mepEntries.size() != 1) {
180 log.warn("Mep " + mepId + " not found on device " + handler().data().deviceId());
181 return null;
182 } else {
183 return mepEntries.stream().findFirst().get();
Sean Condon0e89bda2017-03-21 14:23:19 +0000184 }
Sean Condon0e89bda2017-03-21 14:23:19 +0000185 } catch (NetconfException e) {
186 log.error("Unable to get MEP {}/{}/{} on device {}",
Sean Condon3a1efef2018-02-24 13:16:03 +0000187 mdName, maName, mepId, handler().data().deviceId(), e);
188 throw new CfmConfigException("Unable to get MEP :" + e.getMessage(), e);
Sean Condon0e89bda2017-03-21 14:23:19 +0000189 }
190 }
191
Sean Condon96b896d2017-12-11 12:44:29 -0800192 private Collection<MepEntry> getMepEntriesFromYangResponse(MseaCfm mseacfm)
193 throws CfmConfigException {
194
195 Collection<MepEntry> mepEntries = new ArrayList<>();
196 if (mseacfm == null || mseacfm.mefCfm() == null || mseacfm.mefCfm().maintenanceDomain() == null) {
197 return mepEntries;
198 }
199
200 for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.
201 mseacfm.mefcfm.MaintenanceDomain replyMd:mseacfm.mefCfm().maintenanceDomain()) {
202 for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.
203 mseacfm.mefcfm.maintenancedomain.
204 MaintenanceAssociation replyMa:replyMd.maintenanceAssociation()) {
205 for (MaintenanceAssociationEndPoint replyMep:replyMa.maintenanceAssociationEndPoint()) {
206 mepEntries.add(buildApiMepEntryFromYangMep(
207 replyMep, handler().data().deviceId(), replyMd, replyMa));
208 }
209 }
210 }
211 return mepEntries;
212 }
213
Sean Condon0e89bda2017-03-21 14:23:19 +0000214 @Override
Sean Condon96b896d2017-12-11 12:44:29 -0800215 public boolean deleteMep(MdId mdName, MaIdShort maName, MepId mepId,
216 Optional<MaintenanceDomain> oldMd) throws CfmConfigException {
Sean Condon0e89bda2017-03-21 14:23:19 +0000217
218 NetconfController controller = checkNotNull(handler().get(NetconfController.class));
Sean Condon96b896d2017-12-11 12:44:29 -0800219 NetconfSession session = checkNotNull(controller.getDevicesMap()
220 .get(handler().data().deviceId()).getSession());
Sean Condon0e89bda2017-03-21 14:23:19 +0000221 MseaCfmNetconfService mseaCfmService = checkNotNull(handler().get(MseaCfmNetconfService.class));
Sean Condon96b896d2017-12-11 12:44:29 -0800222 CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
Sean Condon0e89bda2017-03-21 14:23:19 +0000223
224 MaintenanceAssociationEndPoint mep =
225 new DefaultMaintenanceAssociationEndPoint();
226 mep.mepIdentifier(MepIdType.of(mepId.id()));
227
228 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
229 .MaintenanceAssociation yangMa = new DefaultMaintenanceAssociation();
Sean Condon96b896d2017-12-11 12:44:29 -0800230 Short maNumericId = null;
231 try {
232 maNumericId =
233 mdService.getMaintenanceAssociation(mdName, maName).get().maNumericId();
234 yangMa.id(maNumericId);
235 } catch (NoSuchElementException | IllegalArgumentException e) {
236 //The MA and/or MD have probably been deleted
237 // try to get numeric id values from oldMd
238 log.debug("Could not get MD/MA details from MD service during deletion of MEP {}." +
Sean Condon3a1efef2018-02-24 13:16:03 +0000239 "Continuing with values from event", new MepKeyId(mdName, maName, mepId), e);
Sean Condon96b896d2017-12-11 12:44:29 -0800240 yangMa.id(getMaNumericId(oldMd.get(), maName));
241 }
242
Sean Condon0e89bda2017-03-21 14:23:19 +0000243 yangMa.addToMaintenanceAssociationEndPoint(mep);
244
245 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.MaintenanceDomain yangMd =
246 new DefaultMaintenanceDomain();
Sean Condon96b896d2017-12-11 12:44:29 -0800247 Short mdNumericId = null;
248 try {
249 mdNumericId = mdService.getMaintenanceDomain(mdName).get().mdNumericId();
250 yangMd.id(mdNumericId);
251 } catch (NoSuchElementException | IllegalArgumentException e) {
252 //The MD has probably been deleted
253 // try to get numeric id values from oldMd
254 log.debug("Could not get MD details from MD service during deletion of MEP {}." +
Sean Condon3a1efef2018-02-24 13:16:03 +0000255 "Continuing with values from event", new MepKeyId(mdName, maName, mepId), e);
Sean Condon96b896d2017-12-11 12:44:29 -0800256 yangMd.id(oldMd.get().mdNumericId());
257 }
Sean Condon0e89bda2017-03-21 14:23:19 +0000258 yangMd.addToMaintenanceAssociation(yangMa);
259
260 MefCfm mefCfm = new DefaultMefCfm();
261 mefCfm.addToMaintenanceDomain(yangMd);
262
263 MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
264 mseaCfmOpParam.mefCfm(mefCfm);
265
266 try {
267 mseaCfmService.deleteMseaMep(mseaCfmOpParam, session, DatastoreId.RUNNING);
268 log.info("Deleted MEP {} on device {}", mdName + "/" + maName +
269 "/" + mepId, handler().data().deviceId());
270 return true;
271 } catch (NetconfException e) {
Sean Condon96b896d2017-12-11 12:44:29 -0800272 log.error("Unable to delete MEP {} ({}) on device {}",
273 mdName + "/" + maName + "/" + mepId,
274 mdNumericId + "/" + maNumericId, handler().data().deviceId(), e);
Sean Condon0e89bda2017-03-21 14:23:19 +0000275 throw new CfmConfigException("Unable to delete MEP :" + e.getMessage());
276 }
277
278 }
279
280 @Override
Sean Condon96b896d2017-12-11 12:44:29 -0800281 public boolean createMdOnDevice(MdId mdId) throws CfmConfigException {
282 NetconfController controller =
283 checkNotNull(handler().get(NetconfController.class));
284 NetconfSession session = checkNotNull(controller.getDevicesMap()
285 .get(handler().data().deviceId()).getSession());
286
287 CfmMdService cfmMdService = checkNotNull(handler().get(CfmMdService.class));
288 MaintenanceDomain md = cfmMdService.getMaintenanceDomain(mdId).get();
289
290 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm
291 .mefcfm.MaintenanceDomain yangMd = buildYangMdFromApiMd(md);
292
293 if (md.mdNumericId() <= 0 || md.mdNumericId() > NUMERIC_ID_MAX) {
Sean Condon3a1efef2018-02-24 13:16:03 +0000294 throw new CfmConfigException("Numeric id of MD " + mdId + MUST_1_64_MSG);
Sean Condon96b896d2017-12-11 12:44:29 -0800295 }
296
297 for (MaintenanceAssociation ma:md.maintenanceAssociationList()) {
298 if (ma.maNumericId() <= 0 || ma.maNumericId() > NUMERIC_ID_MAX) {
Sean Condon3a1efef2018-02-24 13:16:03 +0000299 throw new CfmConfigException("Numeric id of MA " + mdId + MUST_1_64_MSG);
Sean Condon96b896d2017-12-11 12:44:29 -0800300 }
301 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
302 .MaintenanceAssociation yangMa = buildYangMaFromApiMa(ma);
303 yangMd.addToMaintenanceAssociation(yangMa);
304 }
305
306 MefCfm mefCfm = new DefaultMefCfm();
307 mefCfm.addToMaintenanceDomain(yangMd);
308
309 MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
310 mseaCfmOpParam.mefCfm(mefCfm);
311
312 MseaCfmNetconfService mseaCfmService =
313 checkNotNull(handler().get(MseaCfmNetconfService.class));
314
315 try {
316 boolean created = mseaCfmService.setMseaCfm(mseaCfmOpParam, session, DatastoreId.RUNNING);
317 log.info("Created MD {} on device {}", mdId.mdName(),
318 handler().data().deviceId());
319 return created;
320 } catch (NetconfException e) {
321 log.error("Unable to create MD {} on device {}",
Sean Condon3a1efef2018-02-24 13:16:03 +0000322 mdId.mdName(), handler().data().deviceId(), e);
323 throw new CfmConfigException("Unable to create MD :" + e.getMessage(), e);
Sean Condon96b896d2017-12-11 12:44:29 -0800324 }
325 }
326
327 @Override
328 public boolean createMaOnDevice(MdId mdId, MaIdShort maId) throws CfmConfigException {
329 NetconfController controller =
330 checkNotNull(handler().get(NetconfController.class));
331 NetconfSession session = checkNotNull(controller.getDevicesMap()
332 .get(handler().data().deviceId()).getSession());
333
334 CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
335 MseaCfmOpParam mseaCfmOpParam = getMaYangObject(mdService, mdId, maId);
336 MseaCfmNetconfService mseaCfmService =
337 checkNotNull(handler().get(MseaCfmNetconfService.class));
338
339 try {
340 boolean created = mseaCfmService.setMseaCfm(mseaCfmOpParam, session, DatastoreId.RUNNING);
341 log.info("Created MA {} on device {}", mdId.mdName() + "/" + maId.maName(),
342 handler().data().deviceId());
343 return created;
344 } catch (NetconfException e) {
345 log.error("Unable to create MA {} on device {}",
Sean Condon3a1efef2018-02-24 13:16:03 +0000346 mdId.mdName() + "/" + maId.maName(), handler().data().deviceId(), e);
347 throw new CfmConfigException("Unable to create MA :" + e.getMessage(), e);
Sean Condon96b896d2017-12-11 12:44:29 -0800348 }
349 }
350
351 private static MseaCfmOpParam getMaYangObject(CfmMdService cfmMdService,
352 MdId mdName, MaIdShort maName) throws CfmConfigException {
353 MaintenanceDomain md = cfmMdService.getMaintenanceDomain(mdName).get();
354 MaintenanceAssociation ma = cfmMdService.getMaintenanceAssociation(mdName, maName).get();
355
356 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
357 .MaintenanceAssociation yangMa = buildYangMaFromApiMa(ma);
358
359 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm
360 .mefcfm.MaintenanceDomain yangMd = buildYangMdFromApiMd(md);
361 yangMd.addToMaintenanceAssociation(yangMa);
362
363 if (md.mdNumericId() <= 0 || md.mdNumericId() > NUMERIC_ID_MAX) {
Sean Condon3a1efef2018-02-24 13:16:03 +0000364 throw new CfmConfigException("Numeric id of MD " + mdName + MUST_1_64_MSG);
Sean Condon96b896d2017-12-11 12:44:29 -0800365 } else if (ma.maNumericId() <= 0 || ma.maNumericId() > NUMERIC_ID_MAX) {
Sean Condon3a1efef2018-02-24 13:16:03 +0000366 throw new CfmConfigException("Numeric id of MA " + maName + MUST_1_64_MSG);
Sean Condon96b896d2017-12-11 12:44:29 -0800367 }
368
369 MefCfm mefCfm = new DefaultMefCfm();
370 mefCfm.addToMaintenanceDomain(yangMd);
371
372 MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
373 mseaCfmOpParam.mefCfm(mefCfm);
374
375 return mseaCfmOpParam;
376 }
377
378 @Override
379 public boolean deleteMdOnDevice(MdId mdId, Optional<MaintenanceDomain> oldMd)
380 throws CfmConfigException {
381 NetconfController controller =
382 checkNotNull(handler().get(NetconfController.class));
383 NetconfSession session = controller.getDevicesMap()
384 .get(handler().data().deviceId()).getSession();
385
386 //First check if this MD is known to ONOS if it is does it have MAs and
387 // do they have any Meps known to ONOS. If there are Meps throw an exception -
388 // the Meps should have been deleted first
389 //If there are none known to ONOS we do not check for Meps on the actual device
390 // - there might might be some orphaned ones down there - we want to delete these
Sean Condon96b896d2017-12-11 12:44:29 -0800391 CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
392 MseaCfmNetconfService mseaCfmService =
393 checkNotNull(handler().get(MseaCfmNetconfService.class));
394
395 MdNameAndTypeCombo mdName = getYangMdNameFromApiMdId(mdId);
396 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.MaintenanceDomain yangMd =
397 new DefaultMaintenanceDomain();
398 Short mdNumericId = null;
399 try {
400 mdNumericId = mdService.getMaintenanceDomain(mdId).get().mdNumericId();
401 yangMd.id(mdNumericId);
402 } catch (NoSuchElementException e) {
Sean Condon3a1efef2018-02-24 13:16:03 +0000403 log.debug("Cannot get numericId of MD from service - getting from oldValue", e);
Sean Condon96b896d2017-12-11 12:44:29 -0800404 yangMd.id(oldMd.get().mdNumericId());
405 }
406
407 MefCfm mefCfm = new DefaultMefCfm();
408 mefCfm.addToMaintenanceDomain(yangMd);
409
410 MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
411 mseaCfmOpParam.mefCfm(mefCfm);
412
413 try {
414 boolean deleted = mseaCfmService.deleteMseaMd(mseaCfmOpParam, session, DatastoreId.RUNNING);
Sean Condon3a1efef2018-02-24 13:16:03 +0000415 log.info("Deleted MD {} on device {}", mdName, handler().data().deviceId());
Sean Condon96b896d2017-12-11 12:44:29 -0800416 return deleted;
417 } catch (NetconfException e) {
418 log.error("Unable to delete MD {} ({}) on device {}",
Sean Condon3a1efef2018-02-24 13:16:03 +0000419 mdName, mdNumericId, handler().data().deviceId(), e);
420 throw new CfmConfigException("Unable to delete MD :" + e.getMessage(), e);
Sean Condon96b896d2017-12-11 12:44:29 -0800421 }
422
423 }
424
425 @Override
426 public boolean deleteMaOnDevice(MdId mdId, MaIdShort maId, Optional<MaintenanceDomain> oldMd)
427 throws CfmConfigException {
428 NetconfController controller =
429 checkNotNull(handler().get(NetconfController.class));
430 NetconfSession session = controller.getDevicesMap()
431 .get(handler().data().deviceId()).getSession();
432
433 CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
434
435 MseaCfmNetconfService mseaCfmService =
436 checkNotNull(handler().get(MseaCfmNetconfService.class));
437
438 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
439 .MaintenanceAssociation yangMa = new DefaultMaintenanceAssociation();
440 Short maNumericId = null;
441 try {
442 maNumericId =
443 mdService.getMaintenanceAssociation(mdId, maId).get().maNumericId();
444 yangMa.id(maNumericId);
445 } catch (NoSuchElementException e) {
Sean Condon3a1efef2018-02-24 13:16:03 +0000446 log.debug("Cannot get numericId of MA from service - getting from oldValue", e);
Sean Condon96b896d2017-12-11 12:44:29 -0800447 yangMa.id(getMaNumericId(oldMd.get(), maId));
448 }
449
450 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.MaintenanceDomain yangMd =
451 new DefaultMaintenanceDomain();
452 Short mdNumericId = null;
453 try {
454 mdNumericId = mdService.getMaintenanceDomain(mdId).get().mdNumericId();
455 yangMd.id(mdNumericId);
456 } catch (NoSuchElementException e) {
Sean Condon3a1efef2018-02-24 13:16:03 +0000457 log.debug("Cannot get numericId of MD from service - getting from oldValue", e);
Sean Condon96b896d2017-12-11 12:44:29 -0800458 yangMd.id(oldMd.get().mdNumericId());
459 }
460 yangMd.addToMaintenanceAssociation(yangMa);
461
462 MefCfm mefCfm = new DefaultMefCfm();
463 mefCfm.addToMaintenanceDomain(yangMd);
464
465 MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
466 mseaCfmOpParam.mefCfm(mefCfm);
467
468 try {
469 boolean deleted = mseaCfmService.deleteMseaMa(mseaCfmOpParam, session, DatastoreId.RUNNING);
470 log.info("Deleted MA {} ({})on device {}", mdId.mdName() + "/" + maId.maName(),
471 mdNumericId + "/" + maNumericId, handler().data().deviceId());
472 return deleted;
473 } catch (NetconfException e) {
474 log.error("Unable to delete MA {} ({}) on device {}",
475 mdId.mdName() + "/" + maId.maName(),
Sean Condon3a1efef2018-02-24 13:16:03 +0000476 mdNumericId + "/" + maNumericId, handler().data().deviceId(), e);
477 throw new CfmConfigException("Unable to delete MA :" + e.getMessage(), e);
Sean Condon96b896d2017-12-11 12:44:29 -0800478 }
479 }
480
481 @Override
482 public boolean createMaRemoteMepOnDevice(MdId mdId, MaIdShort maId, MepId remoteMep) throws CfmConfigException {
483 return crDelMaRemoteMep(mdId, maId, remoteMep, true);
484 }
485
486 @Override
487 public boolean deleteMaRemoteMepOnDevice(MdId mdId, MaIdShort maId, MepId remoteMep) throws CfmConfigException {
488 return crDelMaRemoteMep(mdId, maId, remoteMep, false);
489 }
490
491 private boolean crDelMaRemoteMep(MdId mdId, MaIdShort maId, MepId remoteMep,
492 boolean isCreate) throws CfmConfigException {
493 NetconfController controller =
494 checkNotNull(handler().get(NetconfController.class));
495 NetconfSession session = controller.getDevicesMap()
496 .get(handler().data().deviceId()).getSession();
497
498 CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
499
500 Short mdNumericId = mdService.getMaintenanceDomain(mdId).get().mdNumericId();
501 Short maNumericId =
502 mdService.getMaintenanceAssociation(mdId, maId).get().maNumericId();
503
504 MseaCfmNetconfService mseaCfmService =
505 checkNotNull(handler().get(MseaCfmNetconfService.class));
506
507 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
508 .MaintenanceAssociation yangMa = new DefaultMaintenanceAssociation();
509 yangMa.id(maNumericId);
510 yangMa.addToRemoteMeps(MepIdType.of(remoteMep.value()));
511
512 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.MaintenanceDomain yangMd =
513 new DefaultMaintenanceDomain();
514 yangMd.id(mdNumericId);
515 yangMd.addToMaintenanceAssociation(yangMa);
516
517 MefCfm mefCfm = new DefaultMefCfm();
518 mefCfm.addToMaintenanceDomain(yangMd);
519
520 MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
521 mseaCfmOpParam.mefCfm(mefCfm);
522
523 try {
Sean Condon3a1efef2018-02-24 13:16:03 +0000524 boolean result;
Sean Condon96b896d2017-12-11 12:44:29 -0800525 if (isCreate) {
526 result = mseaCfmService.setMseaCfm(mseaCfmOpParam, session, DatastoreId.RUNNING);
527 } else {
528 result = mseaCfmService.deleteMseaMaRMep(mseaCfmOpParam, session, DatastoreId.RUNNING);
529 }
530 log.info("{} Remote MEP {} in MA {} on device {}", isCreate ? "Created" : "Deleted",
531 remoteMep, mdId.mdName() + "/" + maId.maName(), handler().data().deviceId());
532 return result;
533 } catch (NetconfException e) {
534 log.error("Unable to {} RemoteMep {} in MA {} on device {}",
535 isCreate ? "create" : "delete", remoteMep, mdId.mdName() + "/" + maId.maName(),
Sean Condon3a1efef2018-02-24 13:16:03 +0000536 handler().data().deviceId(), e);
Sean Condon96b896d2017-12-11 12:44:29 -0800537 throw new CfmConfigException("Unable to " + (isCreate ? "create" : "delete")
Sean Condon3a1efef2018-02-24 13:16:03 +0000538 + " Remote Mep:" + e.getMessage(), e);
Sean Condon96b896d2017-12-11 12:44:29 -0800539 }
540 }
541
542
543 @Override
Sean Condon0e89bda2017-03-21 14:23:19 +0000544 public void transmitLoopback(MdId mdName, MaIdShort maName, MepId mepId,
545 MepLbCreate lbCreate) throws CfmConfigException {
546 NetconfController controller =
547 checkNotNull(handler().get(NetconfController.class));
548 NetconfSession session = controller.getDevicesMap()
549 .get(handler().data().deviceId()).getSession();
550 MseaCfmNetconfService mseaCfmService =
551 checkNotNull(handler().get(MseaCfmNetconfService.class));
552 CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
553
554 Short mdNumericId = mdService.getMaintenanceDomain(mdName).get().mdNumericId();
555 Short maNumericId =
556 mdService.getMaintenanceAssociation(mdName, maName).get().maNumericId();
557
558 TransmitLoopbackInput lb = new DefaultTransmitLoopbackInput();
559 lb.maintenanceDomain(mdNumericId);
560 lb.maintenanceAssociation(maNumericId);
561 lb.maintenanceAssociationEndPoint(mepId.id());
562 if (lbCreate.numberMessages() != null) {
563 lb.numberOfMessages(lbCreate.numberMessages());
564 }
565 if (lbCreate.vlanDropEligible() != null) {
566 lb.vlanDropEligible(lbCreate.vlanDropEligible());
567 }
568
569 if (lbCreate.remoteMepId() != null) {
570 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype
571 .MepId yangMepId = new DefaultMepId();
572 yangMepId.mepId(MepIdType.of(lbCreate.remoteMepId().id()));
573 TargetAddress ta = new DefaultTargetAddress();
574 ta.addressType(yangMepId);
575 lb.targetAddress(ta);
576 } else if (lbCreate.remoteMepAddress() != null) {
577 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype
578 .MacAddress yangMacAddress = new DefaultMacAddress();
579 yangMacAddress.macAddress(
580 org.onosproject.yang.gen.v1.ietfyangtypes.rev20130715.ietfyangtypes
581 .MacAddress.of(lbCreate.remoteMepAddress().toString()));
582 TargetAddress ta = new DefaultTargetAddress();
583 ta.addressType(yangMacAddress);
584 lb.targetAddress(ta);
585 } else {
586 throw new CfmConfigException("Either a remote MEP ID or Remote MEP "
587 + "MacAddress must be specified when calling Transmit Loopback");
588 }
589
590 if (lbCreate.dataTlvHex() != null && !lbCreate.dataTlvHex().isEmpty()) {
591 lb.dataTlv(HexString.fromHexString(lbCreate.dataTlvHex()));
592 }
593 if (lbCreate.vlanPriority() != null) {
594 lb.vlanPriority(PriorityType.of((short) lbCreate.vlanPriority().ordinal()));
595 }
596
597 try {
598 mseaCfmService.transmitLoopback(lb, session);
599 log.info("Transmit Loopback called on MEP {} on device {}",
600 mdName + "/" + maName + "/" + mepId,
601 handler().data().deviceId());
602 } catch (NetconfException e) {
603 throw new CfmConfigException(e);
604 }
605 }
606
607 @Override
608 public void abortLoopback(MdId mdName, MaIdShort maName, MepId mepId)
609 throws CfmConfigException {
610 NetconfController controller =
611 checkNotNull(handler().get(NetconfController.class));
612 NetconfSession session = controller.getDevicesMap()
613 .get(handler().data().deviceId()).getSession();
614 MseaCfmNetconfService mseaCfmService =
615 checkNotNull(handler().get(MseaCfmNetconfService.class));
616 CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
617
618 Short mdNumericId = mdService.getMaintenanceDomain(mdName).get().mdNumericId();
619 Short maNumericId =
620 mdService.getMaintenanceAssociation(mdName, maName).get().maNumericId();
621
622 AbortLoopbackInput lbAbort = new DefaultAbortLoopbackInput();
623 lbAbort.maintenanceDomain(mdNumericId);
624 lbAbort.maintenanceAssociation(maNumericId);
625 lbAbort.maintenanceAssociationEndPoint(mepId.id());
626
627 try {
628 mseaCfmService.abortLoopback(lbAbort, session);
629 log.info("Loopback on MEP {} on device {} aborted",
630 mdName + "/" + maName + "/" + mepId,
631 handler().data().deviceId());
632 } catch (NetconfException e) {
633 throw new CfmConfigException(e);
634 }
635 }
636
637 @Override
638 public void transmitLinktrace(MdId mdName, MaIdShort maName, MepId mepId,
639 MepLtCreate ltCreate) {
640 throw new UnsupportedOperationException("Not yet implemented");
641 }
642
Sean Condon96b896d2017-12-11 12:44:29 -0800643 private static org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
Sean Condon0e89bda2017-03-21 14:23:19 +0000644 .MaintenanceDomain buildYangMdFromApiMd(MaintenanceDomain md)
645 throws CfmConfigException {
646 MdNameAndTypeCombo mdName = getYangMdNameFromApiMdId(md.mdId());
647
648 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
649 .MaintenanceDomain mdYang = new DefaultMaintenanceDomain();
650 mdYang.id(md.mdNumericId());
651 mdYang.mdNameAndTypeCombo(mdName);
652 mdYang.mdLevel(MdLevelType.of((short) md.mdLevel().ordinal()));
653
654 return mdYang;
655 }
656
Sean Condon96b896d2017-12-11 12:44:29 -0800657 private static org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
Sean Condon0e89bda2017-03-21 14:23:19 +0000658 .maintenancedomain.MaintenanceAssociation buildYangMaFromApiMa(
659 MaintenanceAssociation apiMa) throws CfmConfigException {
660
661 MaNameAndTypeCombo maName = MaNameUtil.getYangMaNameFromApiMaId(apiMa.maId());
662
663 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
664 .MaintenanceAssociation yamgMa = new DefaultMaintenanceAssociation();
665 yamgMa.maNameAndTypeCombo(maName);
666
Sean Condon0e89bda2017-03-21 14:23:19 +0000667 for (MepId rmep:apiMa.remoteMepIdList()) {
668 yamgMa.addToRemoteMeps(MepIdType.of(rmep.id()));
669 }
670
671 if (apiMa.ccmInterval() != null) {
Sean Condon3a1efef2018-02-24 13:16:03 +0000672 yamgMa.ccmInterval(getYangCcmIntervalFromApi(apiMa.ccmInterval()));
Sean Condon0e89bda2017-03-21 14:23:19 +0000673 }
Sean Condon3a1efef2018-02-24 13:16:03 +0000674
Sean Condon0e89bda2017-03-21 14:23:19 +0000675 if (apiMa.componentList() == null || apiMa.componentList().size() != COMPONENT_LIST_SIZE) {
676 throw new CfmConfigException("EA1000 supports only 1 Component in an MA");
677 }
678
679 Component maComponent = apiMa.componentList().iterator().next();
680 if (maComponent.vidList() == null || maComponent.vidList().size() < VIDLIST_SIZE_MIN) {
681 throw new CfmConfigException("EA1000 requires at least 1 VID in "
682 + "the Component of an MA");
683 }
684 ComponentList compList = new DefaultComponentList();
685 for (VlanId vid:maComponent.vidList()) {
686 compList.addToVid(VlanIdType.of(vid.toShort()));
687 }
688
689 if (maComponent.tagType() != null) {
690 switch (maComponent.tagType()) {
691 case VLAN_STAG:
692 compList.tagType(TagTypeEnum.VLAN_STAG);
693 break;
694 case VLAN_CTAG:
695 compList.tagType(TagTypeEnum.VLAN_CTAG);
696 break;
697 case VLAN_NONE:
698 default:
699 compList.tagType(TagTypeEnum.VLAN_NONE);
700 break;
701 }
702 }
703
704 yamgMa.componentList(compList);
705 yamgMa.id(apiMa.maNumericId());
706 return yamgMa;
707 }
708
Sean Condon3a1efef2018-02-24 13:16:03 +0000709 private static CcmIntervalEnum getYangCcmIntervalFromApi(
710 MaintenanceAssociation.CcmInterval cci) throws CfmConfigException {
711 switch (cci) {
712 case INTERVAL_3MS:
713 return CcmIntervalEnum.YANGAUTOPREFIX3_3MS;
714 case INTERVAL_10MS:
715 return CcmIntervalEnum.YANGAUTOPREFIX10MS;
716 case INTERVAL_100MS:
717 return CcmIntervalEnum.YANGAUTOPREFIX100MS;
718 case INTERVAL_1S:
719 return CcmIntervalEnum.YANGAUTOPREFIX1S;
720 default:
721 throw new CfmConfigException("EA1000 only supports "
722 + "3ms, 10ms, 100ms and 1s for CCM Interval. Rejecting: "
723 + cci.name());
724 }
725 }
726
Sean Condon96b896d2017-12-11 12:44:29 -0800727 private static MaintenanceAssociationEndPoint buildYangMepFromApiMep(Mep mep)
Sean Condon0e89bda2017-03-21 14:23:19 +0000728 throws CfmConfigException {
729 MaintenanceAssociationEndPoint mepBuilder =
730 new DefaultMaintenanceAssociationEndPoint();
731 mepBuilder.mepIdentifier(MepIdType.of(mep.mepId().id()));
732 ContinuityCheck cc = new DefaultContinuityCheck();
733 cc.cciEnabled(mep.cciEnabled());
734 mepBuilder.continuityCheck(cc);
735 mepBuilder.ccmLtmPriority(
736 PriorityType.of((short) mep.ccmLtmPriority().ordinal()));
737 mepBuilder.administrativeState(mep.administrativeState());
738
739 if (mep.direction() == MepDirection.UP_MEP) {
740 throw new CfmConfigException("EA1000 only supports DOWN Meps");
741 }
742
743 if (mep.port() == null || mep.port().toLong() < MEP_PORT_MIN
744 || mep.port().toLong() > MEP_PORT_MAX) {
745 throw new CfmConfigException("EA1000 has only ports 0 and 1. "
746 + "Rejecting Port: " + mep.port());
747 }
748 mepBuilder.yangAutoPrefixInterface(
749 (mep.port().toLong() == 0) ? InterfaceEnum.ETH0 : InterfaceEnum.ETH1);
750
751 return mepBuilder;
752 }
753
754 private MepEntry buildApiMepEntryFromYangMep(
755 MaintenanceAssociationEndPoint yangMep, DeviceId deviceId,
Sean Condon96b896d2017-12-11 12:44:29 -0800756 org.onosproject.yang.gen.v1.mseacfm.rev20160229.
757 mseacfm.mefcfm.MaintenanceDomain replyMd,
758 org.onosproject.yang.gen.v1.mseacfm.rev20160229.
759 mseacfm.mefcfm.maintenancedomain.MaintenanceAssociation replyMa)
760 throws CfmConfigException {
Sean Condon0e89bda2017-03-21 14:23:19 +0000761 MepId mepId = MepId.valueOf((short) yangMep.mepIdentifier().uint16());
762 MepEntry.MepEntryBuilder builder = DefaultMepEntry.builder(mepId,
763 deviceId,
764 (yangMep.yangAutoPrefixInterface() == InterfaceEnum.ETH0) ?
765 PortNumber.portNumber(0) : PortNumber.portNumber(1),
766 MepDirection.DOWN_MEP, //Always down for EA1000
Sean Condon96b896d2017-12-11 12:44:29 -0800767 getApiMdIdFromYangMdName(replyMd.mdNameAndTypeCombo()),
768 getApiMaIdFromYangMaName(replyMa.maNameAndTypeCombo()));
Sean Condon0e89bda2017-03-21 14:23:19 +0000769
770 if (yangMep.loopback() != null) {
771 MepLbEntryBuilder lbEntryBuilder = DefaultMepLbEntry.builder();
772 if (yangMep.loopback().repliesReceived() != null) {
773 lbEntryBuilder = lbEntryBuilder.countLbrReceived(
774 yangMep.loopback().repliesReceived().uint32());
775 }
776 if (yangMep.loopback().repliesTransmitted() != null) {
777 lbEntryBuilder = lbEntryBuilder.countLbrTransmitted(
778 yangMep.loopback().repliesTransmitted().uint32());
779 }
780 builder.loopbackAttributes(lbEntryBuilder.build());
781 }
782
783 if (yangMep.remoteMepDatabase() != null &&
784 yangMep.remoteMepDatabase().remoteMep() != null) {
785 for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
786 .maintenancedomain.maintenanceassociation
787 .maintenanceassociationendpoint.remotemepdatabase.RemoteMep
788 rmep:yangMep.remoteMepDatabase().remoteMep()) {
Sean Condon3a1efef2018-02-24 13:16:03 +0000789 builder = builder.addToActiveRemoteMepList(
Sean Condon0e89bda2017-03-21 14:23:19 +0000790 getApiRemoteMepFromYangRemoteMep(rmep));
791 }
792 }
793
794 if (yangMep.ccmLtmPriority() != null) {
795 builder = (MepEntry.MepEntryBuilder) builder.ccmLtmPriority(
796 Priority.values()[yangMep.ccmLtmPriority().uint8()]);
797 }
798
799 //And the the state attributes
800 builder = (MepEntry.MepEntryBuilder) builder
801 .macAddress(MacAddress.valueOf(yangMep.macAddress().toString()))
802 .administrativeState(yangMep.administrativeState())
803 .cciEnabled(yangMep.continuityCheck().cciEnabled());
804
805 AugmentedMseaCfmMaintenanceAssociationEndPoint augmentedyangMep = yangMep
806 .augmentation(DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint.class);
807
Sean Condon3a1efef2018-02-24 13:16:03 +0000808 if (augmentedyangMep != null && augmentedyangMep.lastDefectSent() != null) {
809 builder = builder
Sean Condon0e89bda2017-03-21 14:23:19 +0000810 .activeXconCcmDefect(augmentedyangMep.lastDefectSent().bits()
811 .get(Bits.CROSS_CONNECT_CCM.bits()))
812 .activeErrorCcmDefect(augmentedyangMep.lastDefectSent().bits()
813 .get(Bits.INVALID_CCM.bits()))
814 .activeMacStatusDefect(augmentedyangMep.lastDefectSent().bits()
815 .get(Bits.REMOTE_MAC_ERROR.bits()))
816 .activeRdiCcmDefect(augmentedyangMep.lastDefectSent().bits()
817 .get(Bits.REMOTE_RDI.bits()))
818 .activeRemoteCcmDefect(augmentedyangMep.lastDefectSent().bits()
819 .get(Bits.REMOTE_INVALID_CCM.bits()));
Sean Condon0e89bda2017-03-21 14:23:19 +0000820 }
821
822 return builder.buildEntry();
823 }
824
825 private RemoteMepEntry getApiRemoteMepFromYangRemoteMep(
826 org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.
827 maintenanceassociation.maintenanceassociationendpoint.remotemepdatabase.
828 RemoteMep yangRemoteMep) throws CfmConfigException {
829
830 MepId remoteMepId = MepId.valueOf((short) yangRemoteMep.remoteMepId().uint16());
831 RemoteMepStateTypeEnum state = RemoteMepStateTypeEnum.FAILED;
832 if (yangRemoteMep.remoteMepState() != null) {
833 state = yangRemoteMep.remoteMepState().enumeration();
834 }
835 RemoteMepEntryBuilder rmepBuilder = DefaultRemoteMepEntry.builder(
836 remoteMepId, RemoteMepState.valueOf("RMEP_" + state.name()))
837 .rdi(yangRemoteMep.rdi());
838 if (yangRemoteMep.macAddress() != null) {
839 rmepBuilder = rmepBuilder.macAddress(
840 MacAddress.valueOf(yangRemoteMep.macAddress().toString()));
841 }
842 if (yangRemoteMep.failedOkTime() != null) {
843 //Currently EA1000 is reporting this as 1/1000s even though yang type
844 // is time ticks 1/100s - to be fixed
845 rmepBuilder = rmepBuilder.failedOrOkTime(Duration.ofMillis(
846 yangRemoteMep.failedOkTime().uint32()));
847 }
848 if (yangRemoteMep.portStatusTlv() != null) {
849 rmepBuilder = rmepBuilder.portStatusTlvType(PortStatusTlvType.valueOf(
850 "PS_" + yangRemoteMep.portStatusTlv().enumeration().name()));
851 }
852 if (yangRemoteMep.interfaceStatusTlv() != null) {
853 rmepBuilder = rmepBuilder.interfaceStatusTlvType(InterfaceStatusTlvType.valueOf(
854 "IS_" + yangRemoteMep.interfaceStatusTlv().enumeration().name()));
855 }
856 return rmepBuilder.build();
857 }
Sean Condon96b896d2017-12-11 12:44:29 -0800858
859 private static short getMaNumericId(MaintenanceDomain md, MaIdShort maId) {
860 return md.maintenanceAssociationList().stream()
861 .filter(ma -> maId.equals(ma.maId()))
862 .findFirst().get().maNumericId();
863 }
Sean Condon0e89bda2017-03-21 14:23:19 +0000864}