blob: 568df72866c097d871d670cd57b29ce97983e564 [file] [log] [blame]
adibrastegarnia025da382019-07-24 12:18:18 -07001/*
2 * Copyright 2019-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 */
16
17
adibrastegarnia025da382019-07-24 12:18:18 -070018package org.onosproject.net.optical.cli;
19
20import com.google.common.collect.ImmutableMap;
21import org.apache.karaf.shell.api.action.Argument;
22import org.apache.karaf.shell.api.action.Command;
23import org.apache.karaf.shell.api.action.Completion;
24import org.apache.karaf.shell.api.action.lifecycle.Service;
25import org.onosproject.cli.AbstractShellCommand;
Andrea Campanella3a361452019-08-02 10:17:53 +020026import org.onosproject.cli.net.NetconfOperationCompleter;
adibrastegarnia025da382019-07-24 12:18:18 -070027import org.onosproject.cli.net.OpticalConnectPointCompleter;
28import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreService;
Andrea Campanella3a361452019-08-02 10:17:53 +020030import org.onosproject.net.ChannelSpacing;
adibrastegarnia025da382019-07-24 12:18:18 -070031import org.onosproject.net.ConnectPoint;
Andrea Campanella3a361452019-08-02 10:17:53 +020032import org.onosproject.net.Device;
adibrastegarnia025da382019-07-24 12:18:18 -070033import org.onosproject.net.GridType;
34import org.onosproject.net.OchSignal;
Andrea Campanella7ebfe322019-08-29 11:46:57 -070035import org.onosproject.net.Port;
adibrastegarnia025da382019-07-24 12:18:18 -070036import org.onosproject.net.device.DeviceService;
Andrea Campanella3a361452019-08-02 10:17:53 +020037import org.onosproject.net.flow.DefaultFlowRule;
38import org.onosproject.net.flow.DefaultTrafficSelector;
39import org.onosproject.net.flow.DefaultTrafficTreatment;
40import org.onosproject.net.flow.FlowRule;
41import org.onosproject.net.flow.FlowRuleService;
adibrastegarnia025da382019-07-24 12:18:18 -070042import org.onosproject.net.flow.TrafficSelector;
43import org.onosproject.net.flow.TrafficTreatment;
adibrastegarnia025da382019-07-24 12:18:18 -070044import org.onosproject.net.flow.instructions.Instructions;
Andrea Campanella7ebfe322019-08-29 11:46:57 -070045import org.onosproject.net.optical.OchPort;
46import org.onosproject.net.optical.device.OchPortHelper;
adibrastegarnia025da382019-07-24 12:18:18 -070047
48import java.util.Map;
Andrea Campanella7ebfe322019-08-29 11:46:57 -070049import java.util.Optional;
adibrastegarnia025da382019-07-24 12:18:18 -070050
51import static com.google.common.base.Preconditions.checkArgument;
52import static com.google.common.base.Preconditions.checkNotNull;
53
54/**
55 * Enable the optical channel and tune the wavelength via a flow rule based on a given Signal.
56 */
57@Service
Andrea Campanella3a361452019-08-02 10:17:53 +020058@Command(scope = "onos", name = "wavelength-config",
adibrastegarnia025da382019-07-24 12:18:18 -070059 description = "Enable the optical channel and tune the wavelength via a flow rule ")
60public class PortWaveLengthCommand extends AbstractShellCommand {
61
62 private static final String SIGNAL_FORMAT = "slotGranularity/channelSpacing(in GHz e.g 6.25,12.5,25,50,100)/" +
63 "spaceMultiplier/gridType(cwdm, flex, dwdm) " + "e.g 1/6.25/1/flex";
64
65 private static final String CH_6P25 = "6.25";
66 private static final String CH_12P5 = "12.5";
67 private static final String CH_25 = "25";
68 private static final String CH_50 = "50";
69 private static final String CH_100 = "100";
Andrea Campanella7ebfe322019-08-29 11:46:57 -070070 public static final long BASE_FREQUENCY = 193100000; //Working in Mhz
adibrastegarnia025da382019-07-24 12:18:18 -070071
72 private static final Map<String, ChannelSpacing> CHANNEL_SPACING_MAP = ImmutableMap
73 .<String, ChannelSpacing>builder()
74 .put(CH_6P25, ChannelSpacing.CHL_6P25GHZ)
75 .put(CH_12P5, ChannelSpacing.CHL_12P5GHZ)
76 .put(CH_25, ChannelSpacing.CHL_25GHZ)
77 .put(CH_50, ChannelSpacing.CHL_50GHZ)
78 .put(CH_100, ChannelSpacing.CHL_100GHZ)
79 .build();
Andrea Campanella3a361452019-08-02 10:17:53 +020080 @Argument(index = 0, name = "operation", description = "Netconf Operation including get, edit-config, etc.",
81 required = true, multiValued = false)
82 @Completion(NetconfOperationCompleter.class)
83 private String operation = null;
adibrastegarnia025da382019-07-24 12:18:18 -070084
Andrea Campanella3a361452019-08-02 10:17:53 +020085 @Argument(index = 1, name = "connectPoint",
adibrastegarnia025da382019-07-24 12:18:18 -070086 description = "Device/Port Description",
87 required = true, multiValued = false)
88 @Completion(OpticalConnectPointCompleter.class)
89 String connectPointString = "";
90
Andrea Campanella7ebfe322019-08-29 11:46:57 -070091 @Argument(index = 2, name = "value",
92 description = "Optical Signal or wavelength. Provide wavelenght in MHz, while Och Format = "
93 + SIGNAL_FORMAT, required = false, multiValued = false)
94 String parameter = "";
adibrastegarnia025da382019-07-24 12:18:18 -070095
adibrastegarnia025da382019-07-24 12:18:18 -070096
97 private OchSignal createOchSignal() throws IllegalArgumentException {
Andrea Campanella7ebfe322019-08-29 11:46:57 -070098 if (parameter == null) {
adibrastegarnia025da382019-07-24 12:18:18 -070099 return null;
100 }
101 try {
Andrea Campanella7ebfe322019-08-29 11:46:57 -0700102 String[] splitted = parameter.split("/");
adibrastegarnia025da382019-07-24 12:18:18 -0700103 checkArgument(splitted.length == 4,
104 "signal requires 4 parameters: " + SIGNAL_FORMAT);
105 int slotGranularity = Integer.parseInt(splitted[0]);
106 String chSpacing = splitted[1];
107 ChannelSpacing channelSpacing = checkNotNull(CHANNEL_SPACING_MAP.get(chSpacing),
108 String.format("invalid channel spacing: %s", chSpacing));
109 int multiplier = Integer.parseInt(splitted[2]);
110 String gdType = splitted[3].toUpperCase();
111 GridType gridType = GridType.valueOf(gdType);
112 return new OchSignal(gridType, channelSpacing, multiplier, slotGranularity);
113 } catch (RuntimeException e) {
114 /* catching RuntimeException as both NullPointerException (thrown by
115 * checkNotNull) and IllegalArgumentException (thrown by checkArgument)
116 * are subclasses of RuntimeException.
117 */
118 String msg = String.format("Invalid signal format: %s, expected format is %s.",
Andrea Campanella7ebfe322019-08-29 11:46:57 -0700119 parameter, SIGNAL_FORMAT);
adibrastegarnia025da382019-07-24 12:18:18 -0700120 print(msg);
121 throw new IllegalArgumentException(msg, e);
122 }
123 }
124
Andrea Campanella7ebfe322019-08-29 11:46:57 -0700125 private OchSignal createOchSignalFromWavelength(DeviceService deviceService, ConnectPoint cp) {
126 long wavelength = Long.parseLong(parameter);
127 if (wavelength == 0L) {
128 return null;
129 }
130 Port port = deviceService.getPort(cp);
131 Optional<OchPort> ochPortOpt = OchPortHelper.asOchPort(port);
132
133 if (ochPortOpt.isPresent()) {
134 OchPort ochPort = ochPortOpt.get();
135 GridType gridType = ochPort.lambda().gridType();
136 ChannelSpacing channelSpacing = ochPort.lambda().channelSpacing();
137 int slotGranularity = ochPort.lambda().slotGranularity();
138 int multiplier = getMultplier(wavelength, gridType, channelSpacing, slotGranularity);
139 return new OchSignal(gridType, channelSpacing, multiplier, slotGranularity);
140 } else {
141 print("Connect point %s is not OChPort", cp);
142 return null;
143 }
144
145 }
146
147 private int getMultplier(long wavelength, GridType gridType, ChannelSpacing channelSpacing, int slotGranularity) {
148 long baseFreq;
149 switch (gridType) {
150 case DWDM:
151 baseFreq = BASE_FREQUENCY;
152 break;
153 case CWDM:
154 case FLEX:
155 case UNKNOWN:
156 default:
157 baseFreq = 0L;
158 break;
159 }
160 if (wavelength > baseFreq) {
161 return (int) ((wavelength - baseFreq) / (channelSpacing.frequency().asMHz()));
162 } else {
163 return (int) ((baseFreq - wavelength) / (channelSpacing.frequency().asMHz()));
164 }
165 }
166
adibrastegarnia025da382019-07-24 12:18:18 -0700167
168 @Override
169 protected void doExecute() throws Exception {
Andrea Campanella3a361452019-08-02 10:17:53 +0200170 if (operation.equals("edit-config")) {
171 FlowRuleService flowService = get(FlowRuleService.class);
172 DeviceService deviceService = get(DeviceService.class);
173 CoreService coreService = get(CoreService.class);
174 ConnectPoint cp = ConnectPoint.deviceConnectPoint(connectPointString);
adibrastegarnia025da382019-07-24 12:18:18 -0700175
Andrea Campanella3a361452019-08-02 10:17:53 +0200176 TrafficSelector.Builder trafficSelectorBuilder = DefaultTrafficSelector.builder();
177 TrafficTreatment.Builder trafficTreatmentBuilder = DefaultTrafficTreatment.builder();
178 FlowRule.Builder flowRuleBuilder = DefaultFlowRule.builder();
adibrastegarnia025da382019-07-24 12:18:18 -0700179
180
Andrea Campanella3a361452019-08-02 10:17:53 +0200181 // an empty traffic selector
182 TrafficSelector trafficSelector = trafficSelectorBuilder.matchInPort(cp.port()).build();
Andrea Campanella7ebfe322019-08-29 11:46:57 -0700183 OchSignal ochSignal;
184 if (parameter.contains("/")) {
185 ochSignal = createOchSignal();
186 } else if (parameter.matches("-?\\d+(\\.\\d+)?")) {
187 ochSignal = createOchSignalFromWavelength(deviceService, cp);
188 } else {
189 print("Signal or wavelength %s are in uncorrect format");
190 return;
191 }
192 if (ochSignal == null) {
193 print("Error in creating OchSignal");
194 return;
195 }
Andrea Campanella3a361452019-08-02 10:17:53 +0200196 TrafficTreatment trafficTreatment = trafficTreatmentBuilder
197 .add(Instructions.modL0Lambda(ochSignal))
198 .add(Instructions.createOutput(deviceService.getPort(cp).number()))
199 .build();
adibrastegarnia025da382019-07-24 12:18:18 -0700200
Andrea Campanella3a361452019-08-02 10:17:53 +0200201 Device device = deviceService.getDevice(cp.deviceId());
202 int priority = 100;
203 ApplicationId appId = coreService.registerApplication("org.onosproject.optical-model");
204 log.info(appId.name());
205 FlowRule addFlow = flowRuleBuilder
206 .withPriority(priority)
207 .fromApp(appId)
208 .withTreatment(trafficTreatment)
209 .withSelector(trafficSelector)
210 .forDevice(device.id())
211 .makePermanent()
212 .build();
213 flowService.applyFlowRules(addFlow);
214 String msg = String.format("Setting wavelength %s", ochSignal.centralFrequency().asGHz());
215 print(msg);
216 } else {
217 print("Operation %s are not supported now.", operation);
218 }
adibrastegarnia025da382019-07-24 12:18:18 -0700219
220 }
221}