blob: 0bc35457e91de2e430917a84075d9dac872409a7 [file] [log] [blame]
Andrea Campanella945ded22016-01-07 13:17:43 -08001/*
2 * Copyright 2015 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.protocol.rest.ctl;
18
19import com.sun.jersey.api.client.Client;
20import com.sun.jersey.api.client.ClientResponse;
21import com.sun.jersey.api.client.WebResource;
22import org.apache.commons.io.IOUtils;
23import org.apache.felix.scr.annotations.Activate;
24import org.apache.felix.scr.annotations.Component;
25import org.apache.felix.scr.annotations.Deactivate;
26import org.apache.felix.scr.annotations.Service;
Andrea Campanellace279ee2016-01-25 10:21:45 -080027import org.apache.http.client.methods.HttpPatch;
28import org.apache.http.entity.StringEntity;
29import org.apache.http.impl.client.HttpClients;
Andrea Campanella945ded22016-01-07 13:17:43 -080030import org.onlab.packet.IpAddress;
31import org.onosproject.net.DeviceId;
32import org.onosproject.protocol.rest.RestSBController;
33import org.onosproject.protocol.rest.RestSBDevice;
Andrea Campanella945ded22016-01-07 13:17:43 -080034import org.slf4j.Logger;
35import org.slf4j.LoggerFactory;
36
37import javax.ws.rs.core.MediaType;
38import javax.ws.rs.core.Response;
39import java.io.ByteArrayInputStream;
40import java.io.IOException;
41import java.io.InputStream;
42import java.nio.charset.StandardCharsets;
43import java.util.Map;
44import java.util.concurrent.ConcurrentHashMap;
45
46/**
47 * The implementation of RestSBController.
48 */
49@Component(immediate = true)
50@Service
51public class RestSBControllerImpl implements RestSBController {
52
53 private static final Logger log =
54 LoggerFactory.getLogger(RestSBControllerImpl.class);
Andrea Campanella945ded22016-01-07 13:17:43 -080055 private static final String XML = "xml";
56 private static final String JSON = "json";
57 private static final String DOUBLESLASH = "//";
58 private static final String COLON = ":";
59 private static final int STATUS_OK = Response.Status.OK.getStatusCode();
60 private static final int STATUS_CREATED = Response.Status.CREATED.getStatusCode();
61 private static final int STATUS_ACCEPTED = Response.Status.ACCEPTED.getStatusCode();
62 private static final String SLASH = "/";
63
64 private final Map<DeviceId, RestSBDevice> deviceMap = new ConcurrentHashMap<>();
65 Client client;
66
67 @Activate
Andrea Campanellace279ee2016-01-25 10:21:45 -080068 public void activate() {
Andrea Campanella945ded22016-01-07 13:17:43 -080069 client = Client.create();
70 log.info("Started");
71 }
72
73 @Deactivate
74 public void deactivate() {
75 deviceMap.clear();
76 log.info("Stopped");
77 }
78
79 @Override
80 public Map<DeviceId, RestSBDevice> getDevices() {
81 return deviceMap;
82 }
83
84 @Override
85 public RestSBDevice getDevice(DeviceId deviceInfo) {
86 return deviceMap.get(deviceInfo);
87 }
88
89 @Override
90 public RestSBDevice getDevice(IpAddress ip, int port) {
Andrea Campanellace279ee2016-01-25 10:21:45 -080091 for (RestSBDevice device : deviceMap.values()) {
92 if (device.ip().equals(ip) &&
93 device.port() == port) {
94 return device;
Andrea Campanella945ded22016-01-07 13:17:43 -080095 }
96 }
97 return null;
98 }
99
100 @Override
101 public void addDevice(RestSBDevice device) {
102 deviceMap.put(device.deviceId(), device);
103 }
104
105 @Override
106 public void removeDevice(RestSBDevice device) {
107 deviceMap.remove(device.deviceId());
108 }
109
110 @Override
111 public boolean post(DeviceId device, String request, InputStream payload, String mediaType) {
112 WebResource webResource = getWebResource(device, request);
113
114 ClientResponse response = null;
115 if (payload != null) {
116 try {
117 response = webResource.accept(mediaType)
118 .post(ClientResponse.class, IOUtils.toString(payload, StandardCharsets.UTF_8));
119 } catch (IOException e) {
120 log.error("Cannot do POST {} request on device {} because can't read payload",
121 request, device);
122 }
123 } else {
124 response = webResource.accept(mediaType)
125 .post(ClientResponse.class);
126 }
127 return checkReply(response);
128 }
129
130 @Override
131 public boolean put(DeviceId device, String request, InputStream payload, String mediaType) {
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800132
Andrea Campanella945ded22016-01-07 13:17:43 -0800133 WebResource webResource = getWebResource(device, request);
134 ClientResponse response = null;
135 if (payload != null) {
136 try {
137 response = webResource.accept(mediaType)
138 .put(ClientResponse.class, IOUtils.toString(payload, StandardCharsets.UTF_8));
139 } catch (IOException e) {
140 log.error("Cannot do PUT {} request on device {} because can't read payload",
141 request, device);
142 }
143 } else {
144 response = webResource.accept(mediaType)
145 .put(ClientResponse.class);
146 }
147 return checkReply(response);
148 }
149
150 @Override
151 public InputStream get(DeviceId device, String request, String mediaType) {
152 WebResource webResource = getWebResource(device, request);
153 String type;
154 switch (mediaType) {
155 case XML:
156 type = MediaType.APPLICATION_XML;
157 break;
158 case JSON:
159 type = MediaType.APPLICATION_JSON;
160 break;
161 default:
162 throw new IllegalArgumentException("Unsupported media type " + mediaType);
163
164 }
165 return new ByteArrayInputStream(webResource.accept(type).get(ClientResponse.class)
166 .getEntity(String.class)
167 .getBytes(StandardCharsets.UTF_8));
168 }
169
170 @Override
Andrea Campanellace279ee2016-01-25 10:21:45 -0800171 public boolean patch(DeviceId device, String request, InputStream payload, String mediaType) {
172 String url = deviceMap.get(device).protocol() + COLON +
173 DOUBLESLASH +
174 deviceMap.get(device).ip().toString() +
175 COLON + deviceMap.get(device).port() +
176 SLASH + request;
177 try {
178 HttpPatch httprequest = new HttpPatch(url);
179 if (payload != null) {
180 StringEntity input = new StringEntity(IOUtils.toString(payload, StandardCharsets.UTF_8));
181 input.setContentType(mediaType);
182 httprequest.setEntity(input);
183 }
184 int responseStatusCode = HttpClients.createDefault().execute(httprequest)
185 .getStatusLine()
186 .getStatusCode();
187 return checkStatusCode(responseStatusCode);
188 } catch (IOException e) {
189 log.error("Cannot do PATCH {} request on device {} because can't read payload",
190 request, device);
191 }
192 return false;
193 }
194
195 @Override
Andrea Campanella945ded22016-01-07 13:17:43 -0800196 public boolean delete(DeviceId device, String request, InputStream payload, String mediaType) {
197 WebResource webResource = getWebResource(device, request);
198 ClientResponse response = null;
199 if (payload != null) {
200 try {
201 response = webResource.accept(mediaType)
202 .delete(ClientResponse.class, IOUtils.toString(payload, StandardCharsets.UTF_8));
203 } catch (IOException e) {
204 log.error("Cannot do PUT {} request on device {} because can't read payload",
205 request, device);
206 }
207 } else {
208 response = webResource.accept(mediaType)
209 .delete(ClientResponse.class);
210 }
211 return checkReply(response);
212 }
213
214 private WebResource getWebResource(DeviceId device, String request) {
215 return Client.create().resource(deviceMap.get(device).protocol() + COLON +
216 DOUBLESLASH +
217 deviceMap.get(device).ip().toString() +
218 COLON + deviceMap.get(device).port() +
219 SLASH + request);
220 }
221
222 private boolean checkReply(ClientResponse response) {
223 if (response != null) {
Andrea Campanellace279ee2016-01-25 10:21:45 -0800224 return checkStatusCode(response.getStatus());
Andrea Campanella945ded22016-01-07 13:17:43 -0800225 }
226 log.error("Null reply from device");
227 return false;
228 }
Andrea Campanellace279ee2016-01-25 10:21:45 -0800229
230 private boolean checkStatusCode(int statusCode) {
231 if (statusCode == STATUS_OK ||
232 statusCode == STATUS_CREATED ||
233 statusCode == STATUS_ACCEPTED) {
234 return true;
235 } else {
236 log.error("Failed request: HTTP error code : "
237 + statusCode);
238 return false;
239 }
240 }
Andrea Campanella945ded22016-01-07 13:17:43 -0800241}