blob: 756c25e2f23cebb758007658a936649fbda89c20 [file] [log] [blame]
Ayaka Koshibee39c23a2015-08-03 18:17:43 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
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 */
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070016package org.onosproject.net.optical.config;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070017
18import static org.slf4j.LoggerFactory.getLogger;
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070019
debmaiti9553ed72019-03-18 14:27:42 +053020import java.util.Optional;
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070021import java.util.Set;
22
23import static com.google.common.base.MoreObjects.firstNonNull;
24import static com.google.common.base.Preconditions.checkNotNull;
25
debmaiti9553ed72019-03-18 14:27:42 +053026import org.onosproject.net.config.Config;
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070027import org.onosproject.net.config.NetworkConfigService;
28import org.onosproject.net.config.PortConfigOperator;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070029import org.onosproject.net.AnnotationKeys;
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070030import org.onosproject.net.ConnectPoint;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070031import org.onosproject.net.DefaultAnnotations;
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070032import org.onosproject.net.Port;
33import org.onosproject.net.Port.Type;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070034import org.onosproject.net.PortNumber;
35import org.onosproject.net.SparseAnnotations;
36import org.onosproject.net.device.DefaultPortDescription;
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070037import org.onosproject.net.device.PortDescription;
38import org.slf4j.Logger;
39
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070040import com.google.common.collect.Sets;
41
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070042/**
43 * Implementations of merge policies for various sources of optical port
44 * configuration information. This includes applications, provides, and network
45 * configurations.
46 */
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070047public final class OpticalPortOperator implements PortConfigOperator {
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070048
49 private static final Logger log = getLogger(OpticalPortOperator.class);
50
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070051 /**
52 * Port.Type this PortConfigOperator reacts on.
53 */
54 private final Set<Port.Type> optical = Sets.immutableEnumSet(Port.Type.ODUCLT,
55 Port.Type.OMS,
56 Port.Type.OCH,
57 Port.Type.OTU,
58 Port.Type.FIBER,
59 Port.Type.PACKET);
60
61 private NetworkConfigService networkConfigService;
62
63
64 public OpticalPortOperator() {
65 }
66
67 @Override
68 public void bindService(NetworkConfigService networkConfigService) {
69 this.networkConfigService = networkConfigService;
70 }
71
72 private OpticalPortConfig lookupConfig(ConnectPoint cp) {
73 if (networkConfigService == null) {
74 return null;
75 }
76 return networkConfigService.getConfig(cp, OpticalPortConfig.class);
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070077 }
78
79 /**
80 * Generates a PortDescription containing fields from a PortDescription and
81 * an OpticalPortConfig.
82 *
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070083 * @param cp {@link ConnectPoint} representing the port.
84 * @param descr input {@link PortDescription}
85 * @return Combined {@link PortDescription}
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070086 */
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -070087 @Override
88 public PortDescription combine(ConnectPoint cp, PortDescription descr) {
89 checkNotNull(cp);
90
91 // short-circuit for non-optical ports
92 // must be removed if we need type override
93 if (descr != null && !optical.contains(descr.type())) {
94 return descr;
95 }
96
97 OpticalPortConfig opc = lookupConfig(cp);
Ray Milkey74e59132018-01-17 15:24:52 -080098 if (descr == null || opc == null) {
Ayaka Koshibee39c23a2015-08-03 18:17:43 -070099 return descr;
100 }
101
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -0700102 PortNumber number = descr.portNumber();
103 // handle PortNumber "name" portion
104 if (!opc.name().isEmpty()) {
105 number = PortNumber.portNumber(descr.portNumber().toLong(), opc.name());
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700106 }
107
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -0700108 // handle additional annotations
109 SparseAnnotations annotations = combine(opc, descr.annotations());
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700110
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -0700111 // (Future work) handle type overwrite?
112 Type type = firstNonNull(opc.type(), descr.type());
113 if (type != descr.type()) {
114 // TODO: Do we need to be able to overwrite Port.Type?
115 log.warn("Port type overwrite requested for {}. Ignoring.", cp);
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700116 }
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -0700117
118 return updateDescription(number, annotations, descr);
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700119 }
120
debmaiti9553ed72019-03-18 14:27:42 +0530121 @Override
122 public PortDescription combine(ConnectPoint cp, PortDescription descr, Optional<Config> prevConf) {
123 return combine(cp, descr);
124 }
125
126
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700127 // updates a port description whose port type has not changed.
HIGUCHI Yutacc10558d2016-06-03 14:27:05 -0700128 /**
129 * Updates {@link PortDescription} using specified number and annotations.
130 *
131 * @param port {@link PortNumber} to use in updated description
132 * @param sa annotations to use in updated description
133 * @param descr base {@link PortDescription}
134 * @return updated {@link PortDescription}
135 */
136 private static PortDescription updateDescription(PortNumber port,
137 SparseAnnotations sa,
138 PortDescription descr) {
139
HIGUCHI Yutacc10558d2016-06-03 14:27:05 -0700140 if (port.exactlyEquals(descr.portNumber()) && sa.equals(descr.annotations())) {
141 // result is no-op
142 return descr;
143 }
Yuta HIGUCHI2b1935d2018-03-01 21:41:06 -0800144 return DefaultPortDescription.builder(descr)
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800145 .withPortNumber(port)
Yuta HIGUCHI2b1935d2018-03-01 21:41:06 -0800146 .annotations(sa)
147 .build();
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700148 }
149
150 /**
151 * Generates an annotation from an existing annotation and OptcalPortConfig.
152 *
153 * @param opc the port config entity from network config
154 * @param an the annotation
155 * @return annotation combining both sources
156 */
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -0700157 private static SparseAnnotations combine(OpticalPortConfig opc, SparseAnnotations an) {
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700158 DefaultAnnotations.Builder b = DefaultAnnotations.builder();
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -0700159 b.putAll(an);
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700160 if (!opc.staticPort().isEmpty()) {
161 b.set(AnnotationKeys.STATIC_PORT, opc.staticPort());
162 }
163 if (opc.staticLambda().isPresent()) {
164 b.set(AnnotationKeys.STATIC_LAMBDA, String.valueOf(opc.staticLambda().get()));
165 }
166 // The following may not need to be carried.
167 if (!opc.name().isEmpty()) {
168 b.set(AnnotationKeys.PORT_NAME, opc.name());
169 }
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -0700170 return b.build();
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700171 }
Ayaka Koshibed0ab3c02015-09-04 15:43:46 -0700172
Yuta HIGUCHIb9af6b72016-06-10 10:52:58 -0700173
Ayaka Koshibee39c23a2015-08-03 18:17:43 -0700174}