blob: 184b8b7d828a3c43abfa0a6dd7ccbc59fb605fdb [file] [log] [blame]
Georgios Katsikas83600982017-05-28 20:41:45 +02001/*
2 * Copyright 2018-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
17package org.onosproject.drivers.server;
18
19import org.onosproject.net.DeviceId;
20import org.onosproject.net.behaviour.ControllerConfig;
21import org.onosproject.net.behaviour.ControllerInfo;
22import org.onosproject.mastership.MastershipService;
23
24import org.onlab.packet.IpAddress;
25import org.onlab.packet.TpPort;
26import org.slf4j.Logger;
27
28import com.google.common.collect.Lists;
29import com.fasterxml.jackson.databind.JsonNode;
30import com.fasterxml.jackson.databind.ObjectMapper;
31import com.fasterxml.jackson.databind.node.ArrayNode;
32import com.fasterxml.jackson.databind.node.ObjectNode;
33
34import java.io.ByteArrayInputStream;
35import java.io.IOException;
36import java.io.InputStream;
37import java.util.List;
38import java.util.Map;
39import javax.ws.rs.ProcessingException;
40
41import static com.google.common.base.Preconditions.checkNotNull;
Georgios Katsikas740d3282020-03-18 12:05:03 +010042import static org.onosproject.drivers.server.Constants.JSON;
43import static org.onosproject.drivers.server.Constants.MSG_DEVICE_ID_NULL;
44import static org.onosproject.drivers.server.Constants.MSG_MASTERSHIP_NULL;
45import static org.onosproject.drivers.server.Constants.PARAM_CTRL;
46import static org.onosproject.drivers.server.Constants.PARAM_CTRL_IP;
47import static org.onosproject.drivers.server.Constants.PARAM_CTRL_PORT;
48import static org.onosproject.drivers.server.Constants.PARAM_CTRL_TYPE;
49import static org.onosproject.drivers.server.Constants.SLASH;
50import static org.onosproject.drivers.server.Constants.URL_CONTROLLERS_GET;
51import static org.onosproject.drivers.server.Constants.URL_CONTROLLERS_DEL;
52import static org.onosproject.drivers.server.Constants.URL_CONTROLLERS_SET;
Georgios Katsikas83600982017-05-28 20:41:45 +020053import static org.slf4j.LoggerFactory.getLogger;
54
55/**
Georgios Katsikas740d3282020-03-18 12:05:03 +010056 * Implementation of controller configuration behaviour for server devices.
Georgios Katsikas83600982017-05-28 20:41:45 +020057 */
Georgios Katsikas740d3282020-03-18 12:05:03 +010058public class ServerControllerConfig
59 extends BasicServerDriver
Georgios Katsikas83600982017-05-28 20:41:45 +020060 implements ControllerConfig {
61
62 private final Logger log = getLogger(getClass());
63
64 /**
Georgios Katsikas83600982017-05-28 20:41:45 +020065 * Constructs controller configuration for server.
66 */
67 public ServerControllerConfig() {
68 super();
69 log.debug("Started");
70 }
71
72 @Override
73 public List<ControllerInfo> getControllers() {
74 List<ControllerInfo> controllers = Lists.newArrayList();
75
Georgios Katsikas740d3282020-03-18 12:05:03 +010076 DeviceId deviceId = getDeviceId();
77 checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
Georgios Katsikas83600982017-05-28 20:41:45 +020078
79 MastershipService mastershipService = getHandler().get(MastershipService.class);
Georgios Katsikas740d3282020-03-18 12:05:03 +010080 checkNotNull(deviceId, MSG_MASTERSHIP_NULL);
Georgios Katsikas83600982017-05-28 20:41:45 +020081
82 if (!mastershipService.isLocalMaster(deviceId)) {
83 log.warn(
84 "I am not master for {}. " +
85 "Please use master {} to get controllers for this device",
Georgios Katsikas9a5ed3a2018-06-26 19:07:22 +020086 deviceId, mastershipService.getMasterFor(deviceId));
Georgios Katsikas83600982017-05-28 20:41:45 +020087 return controllers;
88 }
89
90 // Hit the path that provides the server's controllers
91 InputStream response = null;
92 try {
Georgios Katsikas740d3282020-03-18 12:05:03 +010093 response = getController().get(deviceId, URL_CONTROLLERS_GET, JSON);
Georgios Katsikas83600982017-05-28 20:41:45 +020094 } catch (ProcessingException pEx) {
95 log.error("Failed to get controllers of device: {}", deviceId);
96 return controllers;
97 }
98
99 // Load the JSON into objects
100 ObjectMapper mapper = new ObjectMapper();
101 Map<String, Object> jsonMap = null;
102 JsonNode jsonNode = null;
103 ObjectNode objNode = null;
104 try {
105 jsonMap = mapper.readValue(response, Map.class);
106 jsonNode = mapper.convertValue(jsonMap, JsonNode.class);
107 objNode = (ObjectNode) jsonNode;
108 } catch (IOException ioEx) {
109 log.error("Failed to get controllers of device: {}", deviceId);
110 return controllers;
111 }
112
113 if (jsonMap == null) {
114 log.error("Failed to get controllers of device: {}", deviceId);
115 return controllers;
116 }
117
Georgios Katsikas740d3282020-03-18 12:05:03 +0100118 // Fetch controllers' array
Georgios Katsikas83600982017-05-28 20:41:45 +0200119 JsonNode ctrlNode = objNode.path(PARAM_CTRL);
120
Georgios Katsikas83600982017-05-28 20:41:45 +0200121 for (JsonNode cn : ctrlNode) {
122 ObjectNode ctrlObjNode = (ObjectNode) cn;
123
124 // Get the attributes of a controller
125 String ctrlIpStr = get(cn, PARAM_CTRL_IP);
126 int ctrlPort = ctrlObjNode.path(PARAM_CTRL_PORT).asInt();
127 String ctrlType = get(cn, PARAM_CTRL_TYPE);
128
Georgios Katsikas9a5ed3a2018-06-26 19:07:22 +0200129 // Implies no controller
130 if (ctrlIpStr.isEmpty()) {
131 continue;
132 }
133
Georgios Katsikas83600982017-05-28 20:41:45 +0200134 // Check data format and range
135 IpAddress ctrlIp = null;
136 try {
137 ctrlIp = IpAddress.valueOf(ctrlIpStr);
138 } catch (IllegalArgumentException e) {
139 throw new IllegalArgumentException(e);
140 }
141
142 if ((ctrlPort < 0) || (ctrlPort > TpPort.MAX_PORT)) {
143 final String msg = "Invalid controller port: " + ctrlPort;
144 throw new IllegalArgumentException(msg);
145 }
146
147 controllers.add(
148 new ControllerInfo(ctrlIp, ctrlPort, ctrlType)
149 );
150 }
151
152 return controllers;
153 }
154
155 @Override
156 public void setControllers(List<ControllerInfo> controllers) {
Georgios Katsikas740d3282020-03-18 12:05:03 +0100157 DeviceId deviceId = getDeviceId();
158 checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
Georgios Katsikas83600982017-05-28 20:41:45 +0200159
160 MastershipService mastershipService = getHandler().get(MastershipService.class);
Georgios Katsikas740d3282020-03-18 12:05:03 +0100161 checkNotNull(deviceId, MSG_MASTERSHIP_NULL);
Georgios Katsikas83600982017-05-28 20:41:45 +0200162
163 if (!mastershipService.isLocalMaster(deviceId)) {
164 log.warn(
165 "I am not master for {}. " +
166 "Please use master {} to set controllers for this device",
Georgios Katsikas9a5ed3a2018-06-26 19:07:22 +0200167 deviceId, mastershipService.getMasterFor(deviceId));
Georgios Katsikas83600982017-05-28 20:41:45 +0200168 return;
169 }
170
171 ObjectMapper mapper = new ObjectMapper();
172
173 // Create the object node to host the data
174 ObjectNode sendObjNode = mapper.createObjectNode();
175
176 // Insert header
177 ArrayNode ctrlsArrayNode = sendObjNode.putArray(PARAM_CTRL);
178
179 // Add each controller's information object
180 for (ControllerInfo ctrl : controllers) {
181 ObjectNode ctrlObjNode = mapper.createObjectNode();
182 ctrlObjNode.put(PARAM_CTRL_IP, ctrl.ip().toString());
183 ctrlObjNode.put(PARAM_CTRL_PORT, ctrl.port());
184 ctrlObjNode.put(PARAM_CTRL_TYPE, ctrl.type());
185 ctrlsArrayNode.add(ctrlObjNode);
186 }
187
188 // Post the controllers to the device
189 int response = getController().post(
Georgios Katsikas740d3282020-03-18 12:05:03 +0100190 deviceId, URL_CONTROLLERS_SET,
Georgios Katsikas9a5ed3a2018-06-26 19:07:22 +0200191 new ByteArrayInputStream(sendObjNode.toString().getBytes()), JSON);
Georgios Katsikas83600982017-05-28 20:41:45 +0200192
193 if (!checkStatusCode(response)) {
194 log.error("Failed to set controllers on device {}", deviceId);
195 }
196
197 return;
198 }
199
200 @Override
201 public void removeControllers(List<ControllerInfo> controllers) {
Georgios Katsikas740d3282020-03-18 12:05:03 +0100202 DeviceId deviceId = getDeviceId();
203 checkNotNull(deviceId, MSG_DEVICE_ID_NULL);
Georgios Katsikas83600982017-05-28 20:41:45 +0200204
205 MastershipService mastershipService = getHandler().get(MastershipService.class);
Georgios Katsikas740d3282020-03-18 12:05:03 +0100206 checkNotNull(deviceId, MSG_MASTERSHIP_NULL);
Georgios Katsikas83600982017-05-28 20:41:45 +0200207
208 if (!mastershipService.isLocalMaster(deviceId)) {
209 log.warn(
210 "I am not master for {}. " +
211 "Please use master {} to remove controllers from this device",
Georgios Katsikas9a5ed3a2018-06-26 19:07:22 +0200212 deviceId, mastershipService.getMasterFor(deviceId));
Georgios Katsikas83600982017-05-28 20:41:45 +0200213 return;
214 }
215
Georgios Katsikas9a5ed3a2018-06-26 19:07:22 +0200216 for (ControllerInfo ctrl : controllers) {
217 log.info("Remove controller with {}:{}:{}",
218 ctrl.type(), ctrl.ip().toString(), ctrl.port());
Georgios Katsikas83600982017-05-28 20:41:45 +0200219
Georgios Katsikas740d3282020-03-18 12:05:03 +0100220 String remCtrlUrl = URL_CONTROLLERS_DEL + SLASH + ctrl.ip().toString();
Georgios Katsikas83600982017-05-28 20:41:45 +0200221
Georgios Katsikas9a5ed3a2018-06-26 19:07:22 +0200222 // Remove this controller
223 int response = getController().delete(deviceId, remCtrlUrl, null, JSON);
224
225 if (!checkStatusCode(response)) {
226 log.error("Failed to remove controller {}:{}:{} from device {}",
227 ctrl.type(), ctrl.ip().toString(), ctrl.port(), deviceId);
228 }
Georgios Katsikas83600982017-05-28 20:41:45 +0200229 }
230
231 return;
232 }
233
234}