blob: 2ecc70fe3e435e64576147a7c81661dceeb47a36 [file] [log] [blame]
Sean Condonfae8e662016-12-15 10:25:13 +00001/*
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
17package org.onosproject.drivers.microsemi;
18
19
20import static org.slf4j.LoggerFactory.getLogger;
21
22import java.util.concurrent.atomic.AtomicInteger;
23
24import org.apache.felix.scr.annotations.Activate;
25import org.apache.felix.scr.annotations.Component;
26import org.apache.felix.scr.annotations.Deactivate;
27import org.apache.felix.scr.annotations.Reference;
28import org.apache.felix.scr.annotations.ReferenceCardinality;
29import org.onosproject.core.CoreService;
30import org.onosproject.drivers.microsemi.yang.MseaUniEvcServiceNetconfService;
31import org.onosproject.net.DeviceId;
32import org.onosproject.net.meter.Band;
33import org.onosproject.net.meter.Meter.Unit;
34import org.onosproject.net.meter.MeterOperation;
35import org.onosproject.net.meter.MeterOperations;
36import org.onosproject.net.meter.MeterProvider;
37import org.onosproject.net.meter.MeterProviderRegistry;
38import org.onosproject.net.meter.MeterProviderService;
39import org.onosproject.net.provider.AbstractProvider;
40import org.onosproject.net.provider.ProviderId;
41import org.onosproject.netconf.NetconfController;
42import org.onosproject.netconf.NetconfException;
43import org.onosproject.netconf.NetconfSession;
44import org.onosproject.netconf.TargetConfig;
45import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.types.rev20160229.mseatypes.CosColorType;
46import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.types.rev20160229.mseatypes.PriorityType;
47import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.types.rev20160229.mseatypes.coscolortype.CosColorTypeEnum;
48import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.MseaUniEvcService;
49import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.MseaUniEvcService.OnosYangOpType;
50import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.MseaUniEvcServiceOpParam;
51import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.DefaultMefServices;
52import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.MefServices;
53import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.DefaultProfiles;
54import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.DefaultProfiles.ProfilesBuilder;
55import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.profiles.BwpGroup;
56import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.profiles.Cos;
57import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.profiles.DefaultBwpGroup;
58import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.profiles.DefaultCos;
59import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.profiles.bwpgroup.Bwp;
60import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.profiles.bwpgroup.DefaultBwp;
61import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.profiles.cos.costypechoice.DefaultEvcCosTypeEvcColorId;
62import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.profiles.cos.costypechoice.evccostypeevccolorid.DefaultEvcCosTypeAll8PrioTo1EvcColor;
63import org.onosproject.yang.gen.v1.http.www.microsemi.com.microsemi.edge.assure.msea.uni.evc.service.rev20160317.mseaunievcservice.mefservices.profiles.cos.costypechoice.evccostypeevccolorid.EvcCosTypeAll8PrioTo1EvcColor;
64import org.slf4j.Logger;
65
66/**
67 * Provider which uses an NETCONF controller to handle meters.
68 */
69@Component(immediate = true, enabled = true)
70public class EA1000MeterProvider extends AbstractProvider implements MeterProvider {
71
72 private final Logger log = getLogger(getClass());
73
74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 protected NetconfController controller;
76
77 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
78 protected MeterProviderRegistry providerRegistry;
79
80 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
81 protected CoreService coreService;
82
83 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
84 protected MseaUniEvcServiceNetconfService mseaUniEvcServiceSvc;
85
86 private MeterProviderService providerService;
87
88 private static final int COS_INDEX_1 = 1;
89 private static final short DEFAULT_OUTGOING_PRIO = 3;
90
91 /**
92 * Creates a OpenFlow meter provider.
93 */
94 public EA1000MeterProvider() {
95 super(new ProviderId("netconf", "org.onosproject.provider.meter.microsemi"));
96 }
97
98 @Activate
99 public void activate() {
100 providerService = providerRegistry.register(this);
101
102 }
103
104 @Deactivate
105 public void deactivate() {
106 providerRegistry.unregister(this);
107
108 providerService = null;
109 }
110
111 @Override
112 public void performMeterOperation(DeviceId deviceId, MeterOperations meterOps) {
113 log.debug("Adding meterOps to Microsemi Meter Store");
114 }
115
116 @Override
117 public void performMeterOperation(DeviceId deviceId, MeterOperation meterOp) {
118 if (meterOp == null || deviceId == null) {
119 log.warn("Missing argument for performMeterOperation()");
120 return;
121 }
122 log.debug("{} meterOp {} to Microsemi Meter Store", meterOp.type(), meterOp);
123
124 long meterId = meterOp.meter().id().id();
125 String deviceName = deviceId.uri().getSchemeSpecificPart();
126 Unit unit = meterOp.meter().unit();
127
128 ProfilesBuilder profilesBuilder = DefaultProfiles.builder();
129 if (meterOp.type() == MeterOperation.Type.ADD || meterOp.type() == MeterOperation.Type.MODIFY) {
130 Bwp.BwpBuilder bwpBuilder = DefaultBwp.builder()
131 .cosIndex(COS_INDEX_1)
132 .name("BWP-" + String.valueOf(meterId) + "-" + deviceName);
133
134 long cirRateKbps = 0L;
135 long cbsRateKbps = 0L;
136 long eirRateKbps = 0L;
137 long ebsRateKbps = 0L;
138 for (Band band:meterOp.meter().bands()) {
139 if (band.type() == Band.Type.REMARK) {
140 //This relates to CIR/CBS
141 cirRateKbps = toBitsPerSec(band.rate(), unit);
142 cbsRateKbps = band.burst(); //Already in kbps
143 } else if (band.type() == Band.Type.DROP) {
144 //This relates to EIR/EBS
145 eirRateKbps = toBitsPerSec(band.rate(), unit);
146 ebsRateKbps = band.burst(); //Already in kbps
147 }
148 }
149 bwpBuilder.committedInformationRate(cirRateKbps).excessInformationRate(eirRateKbps - cirRateKbps);
150 if (meterOp.meter().isBurst()) {
151 bwpBuilder.committedBurstSize(cbsRateKbps).excessBurstSize(ebsRateKbps - cbsRateKbps);
152 }
153
154 BwpGroup.BwpGroupBuilder bwpgBuilder =
155 DefaultBwpGroup.builder()
156 .groupIndex((short) meterId)
157 .addToBwp(bwpBuilder.build());
158
159 //Create cos-1 as referenced above - we only support 1 at the moment
160 Cos.CosBuilder cosBuilder = DefaultCos.builder()
161 .cosIndex(COS_INDEX_1)
162 .name("COS-1")
163 .outgoingCosValue(PriorityType.of(DEFAULT_OUTGOING_PRIO))
164 .colorAware(true)
165 .colorForward(true);
166 EvcCosTypeAll8PrioTo1EvcColor ect =
167 DefaultEvcCosTypeAll8PrioTo1EvcColor.builder()
168 .evcAll8ColorTo(CosColorType.of(CosColorTypeEnum.GREEN)).build();
169 profilesBuilder
170 .addToBwpGroup(bwpgBuilder.build())
171 .addToCos(cosBuilder.cosTypeChoice(
172 DefaultEvcCosTypeEvcColorId.builder()
173 .evcCosTypeAll8PrioTo1EvcColor(ect).build()).build())
174 .build();
175 } else if (meterOp.type() == MeterOperation.Type.REMOVE) {
176 BwpGroup.BwpGroupBuilder bwpgBuilder =
177 DefaultBwpGroup.builder()
178 .groupIndex((short) meterId)
179 .yangBwpGroupOpType(OnosYangOpType.DELETE);
180
181 profilesBuilder.addToBwpGroup(bwpgBuilder.build()).build();
182 }
183
184 MefServices mefServices = DefaultMefServices.builder().profiles(profilesBuilder.build()).build();
185
186 MseaUniEvcService.MseaUniEvcServiceBuilder evcUniBuilder =
187 new MseaUniEvcServiceOpParam.MseaUniEvcServiceBuilder();
188
189 MseaUniEvcServiceOpParam mseaUniEvcServiceFilter =
190 (MseaUniEvcServiceOpParam) evcUniBuilder.mefServices(mefServices).build();
191 NetconfSession session = controller.getDevicesMap().get(deviceId).getSession();
192 try {
193 mseaUniEvcServiceSvc.setMseaUniEvcService(mseaUniEvcServiceFilter, session, TargetConfig.RUNNING);
194 } catch (NetconfException e) {
195 //This can fail if the BWP Group is deleted before the EVC that is dependent on it
196 //The delete of the EVC will be called on a separate thread to that should proceed
197 //within a few seconds after which we should try again
198 AtomicInteger retry = new AtomicInteger(4);
199 if (meterOp.type() == MeterOperation.Type.REMOVE &&
200 e.getMessage().startsWith("Failed to run edit-config through NETCONF")) {
201 while (retry.getAndDecrement() > 0) {
202 try {
203 Thread.sleep(1000L);
204 log.debug("Retrying deletion of Bandwith Profile Group {}", String.valueOf(meterId));
205 mseaUniEvcServiceSvc.setMseaUniEvcService(mseaUniEvcServiceFilter,
206 session, TargetConfig.RUNNING);
207 return; //If it did not throw an exception
208 } catch (InterruptedException e1) {
209 // TODO Auto-generated catch block
210 e1.printStackTrace();
211 } catch (NetconfException e1) {
212 log.debug("NETCONF failed to delete profile - trying again in 1 sec");
213 e1.printStackTrace();
214 }
215 }
216 log.error("Error deleting BWPGroup {} from {} after 4 tries: {}", meterId, deviceId, e.getMessage());
217 } else {
218 log.error("Error adding BWPGroup {} from {}: {}", meterId, deviceId, e.getMessage());
219 throw new UnsupportedOperationException(e);
220 }
221 e.printStackTrace();
222 }
223 }
224
225 private static long toBitsPerSec(long rate, Unit unit) {
226 if (unit == Unit.KB_PER_SEC) {
227 return rate * 8;
228 } else {
229 return -1;
230 }
231 }
232}