blob: b07780b85384a240bcbfbedc2edac7439d0890fb [file] [log] [blame]
Ayaka Koshibee39c23a2015-08-03 18:17:43 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Ayaka Koshibee39c23a2015-08-03 18:17:43 -07003 *
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.net.device.impl;
17
HIGUCHI Yuta34a3f692016-01-09 21:08:57 -080018import static org.onosproject.net.optical.device.OchPortHelper.ochPortDescription;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -070019import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription;
HIGUCHI Yuta95d83e82016-04-26 12:13:48 -070020import static org.onosproject.net.optical.device.OmsPortHelper.omsPortDescription;
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -070021import static org.onosproject.net.optical.device.OtuPortHelper.otuPortDescription;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070022import static org.slf4j.LoggerFactory.getLogger;
Ray Milkeya4122362015-08-18 15:19:08 -070023import org.onosproject.net.config.ConfigOperator;
Thomas Vachuska4998caa2015-08-26 13:28:38 -070024import org.onosproject.net.config.basics.OpticalPortConfig;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070025import org.onosproject.net.AnnotationKeys;
26import org.onosproject.net.DefaultAnnotations;
27import org.onosproject.net.PortNumber;
28import org.onosproject.net.SparseAnnotations;
29import org.onosproject.net.device.DefaultPortDescription;
30import org.onosproject.net.device.OchPortDescription;
31import org.onosproject.net.device.OduCltPortDescription;
32import org.onosproject.net.device.OmsPortDescription;
Rimon Ashkenazy8ebfff02016-02-01 11:56:36 +020033import org.onosproject.net.device.OtuPortDescription;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070034import org.onosproject.net.device.PortDescription;
35import org.slf4j.Logger;
36
37/**
38 * Implementations of merge policies for various sources of optical port
39 * configuration information. This includes applications, provides, and network
40 * configurations.
41 */
42public final class OpticalPortOperator implements ConfigOperator {
43
44 private static final Logger log = getLogger(OpticalPortOperator.class);
45
46 private OpticalPortOperator() {
47 }
48
49 /**
50 * Generates a PortDescription containing fields from a PortDescription and
51 * an OpticalPortConfig.
52 *
53 * @param opc the port config entity from network config
54 * @param descr a PortDescription
55 * @return PortDescription based on both sources
56 */
57 public static PortDescription combine(OpticalPortConfig opc, PortDescription descr) {
58 if (opc == null) {
59 return descr;
60 }
61
62 PortNumber port = descr.portNumber();
63 final String name = opc.name();
64 final String numName = opc.numberName();
65 // if the description is null, or the current description port name != config name,
66 // create a new PortNumber.
67 PortNumber newPort = null;
68 if (port == null) {
69 // try to get the portNumber from the numName.
70 if (!numName.isEmpty()) {
HIGUCHI Yuta4a6a70a2015-09-04 14:42:10 -070071 final long pn = Long.parseLong(numName);
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070072 newPort = (!name.isEmpty()) ? PortNumber.portNumber(pn, name) : PortNumber.portNumber(pn);
73 } else {
74 // we don't have defining info (a port number value)
75 throw new RuntimeException("Possible misconfig, bailing on handling for: \n\t" + descr);
76 }
77 } else if ((!name.isEmpty()) && !name.equals(port.name())) {
HIGUCHI Yuta4a6a70a2015-09-04 14:42:10 -070078 final long pn = (numName.isEmpty()) ? port.toLong() : Long.parseLong(numName);
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070079 newPort = PortNumber.portNumber(pn, name);
80 }
81
82 // Port type won't change unless we're overwriting a port completely.
83 // Watch out for overwrites to avoid class cast craziness.
Sho SHIMIZUb89d4912015-09-09 14:37:59 -070084 boolean noOwrite = opc.type() == descr.type();
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070085
86 SparseAnnotations sa = combine(opc, descr.annotations());
87 if (noOwrite) {
88 return updateDescription((newPort == null) ? port : newPort, sa, descr);
89 } else {
90 // TODO: must reconstruct a different type of PortDescription.
91 log.info("Type rewrite from {} to {} required", descr.type(), opc.type());
92 }
93 return descr;
94 }
95
96 // updates a port description whose port type has not changed.
HIGUCHI Yutacc10558d2016-06-03 14:27:05 -070097 /**
98 * Updates {@link PortDescription} using specified number and annotations.
99 *
100 * @param port {@link PortNumber} to use in updated description
101 * @param sa annotations to use in updated description
102 * @param descr base {@link PortDescription}
103 * @return updated {@link PortDescription}
104 */
105 private static PortDescription updateDescription(PortNumber port,
106 SparseAnnotations sa,
107 PortDescription descr) {
108
109 // TODO This switch can go away once deprecation is complete.
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700110 switch (descr.type()) {
111 case OMS:
HIGUCHI Yuta95d83e82016-04-26 12:13:48 -0700112 if (descr instanceof OmsPortDescription) {
HIGUCHI Yuta95d83e82016-04-26 12:13:48 -0700113 OmsPortDescription oms = (OmsPortDescription) descr;
114 return omsPortDescription(port, oms.isEnabled(), oms.minFrequency(),
115 oms.maxFrequency(), oms.grid(), sa);
116 }
HIGUCHI Yutacc10558d2016-06-03 14:27:05 -0700117 break;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700118 case OCH:
HIGUCHI Yuta34a3f692016-01-09 21:08:57 -0800119 // We might need to update lambda below with STATIC_LAMBDA.
120 if (descr instanceof OchPortDescription) {
HIGUCHI Yuta34a3f692016-01-09 21:08:57 -0800121 OchPortDescription och = (OchPortDescription) descr;
122 return ochPortDescription(port, och.isEnabled(), och.signalType(),
123 och.isTunable(), och.lambda(), sa);
124 }
HIGUCHI Yutacc10558d2016-06-03 14:27:05 -0700125 break;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700126 case ODUCLT:
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700127 if (descr instanceof OduCltPortDescription) {
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700128 OduCltPortDescription odu = (OduCltPortDescription) descr;
129 return oduCltPortDescription(port, odu.isEnabled(), odu.signalType(), sa);
130 }
HIGUCHI Yutacc10558d2016-06-03 14:27:05 -0700131 break;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700132 case PACKET:
133 case FIBER:
Ayaka Koshibe144bab02015-10-22 12:56:59 -0700134 case COPPER:
HIGUCHI Yutacc10558d2016-06-03 14:27:05 -0700135 break;
Rimon Ashkenazy8ebfff02016-02-01 11:56:36 +0200136 case OTU:
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -0700137 if (descr instanceof OtuPortDescription) {
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -0700138 OtuPortDescription otu = (OtuPortDescription) descr;
139 return otuPortDescription(port, otu.isEnabled(), otu.signalType(), sa);
140 }
HIGUCHI Yutacc10558d2016-06-03 14:27:05 -0700141 break;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700142 default:
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700143 log.warn("Unsupported optical port type {} - can't update", descr.type());
144 return descr;
145 }
HIGUCHI Yutacc10558d2016-06-03 14:27:05 -0700146 if (port.exactlyEquals(descr.portNumber()) && sa.equals(descr.annotations())) {
147 // result is no-op
148 return descr;
149 }
150 return new DefaultPortDescription(port,
151 descr.isEnabled(),
152 descr.type(),
153 descr.portSpeed(),
154 sa);
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700155 }
156
157 /**
158 * Generates an annotation from an existing annotation and OptcalPortConfig.
159 *
160 * @param opc the port config entity from network config
161 * @param an the annotation
162 * @return annotation combining both sources
163 */
164 public static SparseAnnotations combine(OpticalPortConfig opc, SparseAnnotations an) {
165 DefaultAnnotations.Builder b = DefaultAnnotations.builder();
166 if (!opc.staticPort().isEmpty()) {
167 b.set(AnnotationKeys.STATIC_PORT, opc.staticPort());
168 }
169 if (opc.staticLambda().isPresent()) {
170 b.set(AnnotationKeys.STATIC_LAMBDA, String.valueOf(opc.staticLambda().get()));
171 }
172 // The following may not need to be carried.
173 if (!opc.name().isEmpty()) {
174 b.set(AnnotationKeys.PORT_NAME, opc.name());
175 }
176 return DefaultAnnotations.union(an, b.build());
177 }
Ayaka Koshibed0ab3c02015-09-04 15:43:46 -0700178
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700179}