blob: 34ad685e564e117206cd02472f59a747a7591d08 [file] [log] [blame]
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -07001/*
2 * Copyright 2016-present 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 */
Hyunsun Moon187bf532017-01-19 10:57:40 +090016package org.opencord.cordvtn.rest;
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070017
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.SerializationFeature;
20import com.fasterxml.jackson.databind.node.ObjectNode;
21import com.google.common.base.Strings;
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070022import org.glassfish.jersey.client.ClientProperties;
Jonathan Hart19dcbae2017-07-12 09:52:59 -070023import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070024import org.onosproject.rest.AbstractWebResource;
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070025import org.slf4j.Logger;
26
27import javax.ws.rs.client.Client;
28import javax.ws.rs.client.ClientBuilder;
Jonathan Hart19dcbae2017-07-12 09:52:59 -070029import javax.ws.rs.client.Entity;
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070030import javax.ws.rs.client.Invocation;
31import javax.ws.rs.client.WebTarget;
Jonathan Hart19dcbae2017-07-12 09:52:59 -070032import javax.ws.rs.core.MediaType;
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070033import javax.ws.rs.core.Response;
34import java.io.IOException;
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070035
36import static com.google.common.base.Preconditions.checkArgument;
37import static com.google.common.net.MediaType.JSON_UTF_8;
38import static java.net.HttpURLConnection.HTTP_OK;
39import static org.slf4j.LoggerFactory.getLogger;
40
41/**
Hyunsun Moon187bf532017-01-19 10:57:40 +090042 * Implementation of REST client for XOS VTN networking service.
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070043 */
Hyunsun Moon187bf532017-01-19 10:57:40 +090044public final class XosVtnNetworkingClient extends AbstractWebResource {
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070045
46 protected final Logger log = getLogger(getClass());
47
Jonathan Hart19dcbae2017-07-12 09:52:59 -070048 private static final String URL_BASE = "/xosapi/v1/vtn/";
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070049
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070050 private static final String EMPTY_JSON_STRING = "{}";
51
Jonathan Hart19dcbae2017-07-12 09:52:59 -070052 private static final String VTN_ID = "id";
53 private static final String VTN_RESYNC = "resync";
54 private static final String VTN_SERVICES = "vtnservices";
55
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070056 private static final String ERR_LOG = "Received %s result with wrong format: %s";
57
58 private static final int DEFAULT_TIMEOUT_MS = 2000;
59
60 private final String endpoint;
61 private final String user;
62 private final String password;
63 private final Client client = ClientBuilder.newClient();
64
Hyunsun Moon187bf532017-01-19 10:57:40 +090065 private XosVtnNetworkingClient(String endpoint, String user, String password) {
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070066 this.endpoint = endpoint;
67 this.user = user;
68 this.password = password;
69
Jonathan Hart19dcbae2017-07-12 09:52:59 -070070 client.register(HttpAuthenticationFeature.basic(user, password));
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070071 client.property(ClientProperties.CONNECT_TIMEOUT, DEFAULT_TIMEOUT_MS);
72 client.property(ClientProperties.READ_TIMEOUT, DEFAULT_TIMEOUT_MS);
73 mapper().enable(SerializationFeature.INDENT_OUTPUT);
74 }
75
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070076 private String restGet(String path) {
Jonathan Hart19dcbae2017-07-12 09:52:59 -070077 WebTarget wt = client.target("http://" + endpoint + URL_BASE).path(path);
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070078 Invocation.Builder builder = wt.request(JSON_UTF_8.toString());
79 try {
80 Response response = builder.get();
81 if (response.getStatus() != HTTP_OK) {
Hyunsun Moone72adf52017-02-22 08:30:25 +090082 log.warn("Failed to get resource {}", endpoint + URL_BASE + path);
Jonathan Hart19dcbae2017-07-12 09:52:59 -070083 log.warn("reason {}", response.readEntity(String.class));
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -070084 return EMPTY_JSON_STRING;
85 }
86 } catch (javax.ws.rs.ProcessingException e) {
87 return EMPTY_JSON_STRING;
88 }
89 return builder.get(String.class);
90 }
91
Jonathan Hart19dcbae2017-07-12 09:52:59 -070092 private String restPut(String path, JsonNode request) {
93 WebTarget wt = client.target("http://" + endpoint + URL_BASE).path(path);
94 Invocation.Builder builder = wt.request(MediaType.APPLICATION_JSON)
95 .accept(JSON_UTF_8.toString());
96
97 try {
98 Response response = builder.put(Entity.entity(request.toString(),
99 MediaType.APPLICATION_JSON_TYPE));
100 String strResponse = response.readEntity(String.class);
101 if (response.getStatus() != HTTP_OK) {
102 throw new IllegalArgumentException("Failed to put resource "
103 + response.getStatus() + ": " + strResponse);
104 }
105 return strResponse;
106 } catch (javax.ws.rs.ProcessingException e) {
107 return EMPTY_JSON_STRING;
108 }
109 }
110
111 public void requestSync() {
112 String response = restGet(VTN_SERVICES);
113 final String error = String.format(ERR_LOG, VTN_SERVICES, response);
114 try {
115 JsonNode jsonTree = mapper().readTree(response).path("items");
116 if (!jsonTree.isArray() || jsonTree.size() < 1) {
117 throw new IllegalArgumentException(error);
118 }
119 JsonNode vtnService = jsonTree.get(0);
120 String vtnServiceId = vtnService.path(VTN_ID).asText();
121 if (vtnServiceId == null || vtnServiceId.equals("")) {
122 throw new IllegalArgumentException(error);
123 }
124 log.info("Requesting sync for VTN service {}", vtnServiceId);
125
126 ObjectNode request = mapper().createObjectNode()
127 .put(VTN_RESYNC, true);
128
129 restPut(VTN_SERVICES + "/" + vtnServiceId, request);
130 } catch (IOException e) {
131 throw new IllegalArgumentException(error);
132 }
133 }
134
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -0700135 /**
136 * Returns endpoint url for the XOS service API access.
137 *
138 * @return endpoint url as a string
139 */
140 public String endpoint() {
141 return endpoint;
142 }
143
144 /**
145 * Returns user name for the XOS service API access.
146 *
147 * @return user name as a string
148 */
149 public String user() {
150 return user;
151 }
152
153 /**
154 * Returns password for the XOS service API access.
155 *
156 * @return password as a string
157 */
158 public String password() {
159 return password;
160 }
161
162 /**
163 * Returns new XOS service networking builder instance.
164 *
165 * @return xos service networking builder
166 */
167 public static Builder builder() {
168 return new Builder();
169 }
170
171 /**
172 * Builder of the XOS service networking entities.
173 */
174 public static final class Builder {
175
176 private String endpoint;
177 private String user;
178 private String password;
179
180 private Builder() {
181 }
182
183 /**
184 * Builds immutable XOS service networking instance.
185 *
186 * @return xos service networking instance
187 */
Hyunsun Moon187bf532017-01-19 10:57:40 +0900188 public XosVtnNetworkingClient build() {
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -0700189 checkArgument(!Strings.isNullOrEmpty(endpoint));
190 checkArgument(!Strings.isNullOrEmpty(user));
191 checkArgument(!Strings.isNullOrEmpty(password));
192
Hyunsun Moon187bf532017-01-19 10:57:40 +0900193 return new XosVtnNetworkingClient(endpoint, user, password);
Hyunsun Moon4a94c2e2016-10-21 17:37:05 -0700194 }
195
196 /**
197 * Returns XOS service networking builder with the supplied endpoint.
198 *
199 * @param endpoint endpoint url
200 * @return xos service networking builder
201 */
202 public Builder endpoint(String endpoint) {
203 this.endpoint = endpoint;
204 return this;
205 }
206
207 /**
208 * Returns XOS service networking builder with the supplied user
209 * credential.
210 *
211 * @param user user
212 * @return xos service networking builder
213 */
214 public Builder user(String user) {
215 this.user = user;
216 return this;
217 }
218
219 /**
220 * Returns XOS service networking builder with the supplied password
221 * credential.
222 *
223 * @param password password
224 * @return xos service networking builder
225 */
226 public Builder password(String password) {
227 this.password = password;
228 return this;
229 }
230 }
231}