2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.mso.adapters.network;
24 import java.util.HashMap;
25 import java.util.List;
28 import javax.ws.rs.Consumes;
29 import javax.ws.rs.DELETE;
30 import javax.ws.rs.GET;
31 import javax.ws.rs.POST;
32 import javax.ws.rs.PUT;
33 import javax.ws.rs.Path;
34 import javax.ws.rs.PathParam;
35 import javax.ws.rs.Produces;
36 import javax.ws.rs.QueryParam;
37 import javax.ws.rs.core.GenericEntity;
38 import javax.ws.rs.core.MediaType;
39 import javax.ws.rs.core.Response;
40 import javax.xml.ws.Holder;
42 import org.apache.http.HttpStatus;
44 import org.openecomp.mso.adapters.network.exceptions.NetworkException;
45 import org.openecomp.mso.adapters.nwrest.ContrailNetwork;
46 import org.openecomp.mso.adapters.nwrest.CreateNetworkError;
47 import org.openecomp.mso.adapters.nwrest.CreateNetworkRequest;
48 import org.openecomp.mso.adapters.nwrest.CreateNetworkResponse;
49 import org.openecomp.mso.adapters.nwrest.DeleteNetworkError;
50 import org.openecomp.mso.adapters.nwrest.DeleteNetworkRequest;
51 import org.openecomp.mso.adapters.nwrest.DeleteNetworkResponse;
52 import org.openecomp.mso.adapters.nwrest.ProviderVlanNetwork;
53 import org.openecomp.mso.adapters.nwrest.QueryNetworkError;
54 import org.openecomp.mso.adapters.nwrest.QueryNetworkResponse;
55 import org.openecomp.mso.adapters.nwrest.RollbackNetworkError;
56 import org.openecomp.mso.adapters.nwrest.RollbackNetworkRequest;
57 import org.openecomp.mso.adapters.nwrest.RollbackNetworkResponse;
58 import org.openecomp.mso.adapters.nwrest.UpdateNetworkError;
59 import org.openecomp.mso.adapters.nwrest.UpdateNetworkRequest;
60 import org.openecomp.mso.adapters.nwrest.UpdateNetworkResponse;
61 import org.openecomp.mso.cloud.CloudConfigFactory;
62 import org.openecomp.mso.entity.MsoRequest;
63 import org.openecomp.mso.logger.MessageEnum;
64 import org.openecomp.mso.logger.MsoLogger;
65 import org.openecomp.mso.openstack.beans.NetworkRollback;
66 import org.openecomp.mso.openstack.beans.NetworkStatus;
67 import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
68 import org.openecomp.mso.properties.MsoPropertiesFactory;
71 public class NetworkAdapterRest {
72 private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
73 private static final String TESTING_KEYWORD = "___TESTING___";
74 private final CloudConfigFactory cloudConfigFactory = new CloudConfigFactory();
75 private final MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
76 private final MsoNetworkAdapterImpl adapter = new MsoNetworkAdapterImpl(msoPropertiesFactory, cloudConfigFactory);
80 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
81 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
82 public Response createNetwork(CreateNetworkRequest req) {
83 LOGGER.debug("createNetwork enter: " + req.toJsonString());
84 CreateNetworkTask task = new CreateNetworkTask(req);
85 if (req.isSynchronous()) {
86 // This is a synchronous request
89 .status(task.getStatusCode())
90 .entity(task.getGenericEntityResponse())
93 // This is an asynchronous request
95 Thread t1 = new Thread(task);
97 } catch (Exception e) {
98 // problem handling create, send generic failure as sync resp to caller
99 LOGGER.error (MessageEnum.RA_CREATE_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while create network", e);
100 return Response.serverError().build();
102 // send sync response (ACK) to caller
103 LOGGER.debug ("createNetwork exit");
104 return Response.status(HttpStatus.SC_ACCEPTED).build();
108 public class CreateNetworkTask implements Runnable {
109 private final CreateNetworkRequest req;
110 private CreateNetworkResponse response = null;
111 private CreateNetworkError eresp = null;
112 private boolean sendxml;
114 public CreateNetworkTask(CreateNetworkRequest req) {
116 this.sendxml = true; // can be set with a field or header later
118 public int getStatusCode() {
119 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
121 public Object getGenericEntityResponse() {
122 return (response != null)
123 ? new GenericEntity<CreateNetworkResponse>(response) {}
124 : new GenericEntity<CreateNetworkError>(eresp) {};
126 private String getResponse() {
127 if (response != null) {
128 return sendxml ? response.toXmlString() : response.toJsonString();
130 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
135 LOGGER.debug ("CreateNetworkTask start");
137 // Synchronous Web Service Outputs
138 Holder<String> networkId = new Holder<String>();
139 Holder<String> neutronNetworkId = new Holder<String>();
140 Holder<String> networkFqdn = new Holder<String>();
141 Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>();
142 Holder<NetworkRollback> rollback = new Holder<NetworkRollback>();
144 String cloudsite = req.getCloudSiteId();
145 if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
146 String tenant = req.getTenantId();
147 if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
148 throw new NetworkException("testing.");
150 networkId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
151 neutronNetworkId.value = "55e55884-28fa-11e6-8971-0017f20fe1b8";
152 networkFqdn.value = "086f70b6-28fb-11e6-8260-0017f20fe1b8";
153 subnetIdMap.value = testMap();
154 rollback.value = new NetworkRollback();
155 } else if (req.isContrailRequest()) {
156 ContrailNetwork ctn = req.getContrailNetwork();
158 ctn = new ContrailNetwork();
159 req.setContrailNetwork(ctn);
161 adapter.createNetworkContrail(
162 req.getCloudSiteId(),
164 req.getNetworkType(),
165 req.getNetworkName(),
166 req.getContrailNetwork().getRouteTargets(),
167 req.getContrailNetwork().getShared(),
168 req.getContrailNetwork().getExternal(),
169 req.getFailIfExists(),
172 req.getContrailNetwork().getPolicyFqdns(),
173 req.getContrailNetwork().getRouteTableFqdns(),
181 ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
183 pvn = new ProviderVlanNetwork();
184 req.setProviderVlanNetwork(pvn);
186 adapter.createNetwork(
187 req.getCloudSiteId(),
189 req.getNetworkType(),
190 req.getNetworkName(),
191 req.getProviderVlanNetwork().getPhysicalNetworkName(),
192 req.getProviderVlanNetwork().getVlans(),
193 req.getFailIfExists(),
202 response = new CreateNetworkResponse(
204 neutronNetworkId.value,
205 rollback.value.getNetworkStackId(),
207 rollback.value.getNetworkCreated(),
211 } catch (NetworkException e) {
212 eresp = new CreateNetworkError(
213 e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
215 if (!req.isSynchronous()) {
216 // This is asynch, so POST response back to caller
217 BpelRestClient bpelClient = new BpelRestClient();
218 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
220 LOGGER.debug ("CreateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
225 @Path("{aaiNetworkId}")
226 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
227 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
228 public Response deleteNetwork(
229 @PathParam("aaiNetworkId") String aaiNetworkId,
230 DeleteNetworkRequest req)
232 LOGGER.debug("deleteNetwork enter: " + req.toJsonString());
233 if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
235 .status(HttpStatus.SC_BAD_REQUEST)
236 .type(MediaType.TEXT_PLAIN)
237 .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
240 DeleteNetworkTask task = new DeleteNetworkTask(req);
241 if (req.isSynchronous()) {
242 // This is a synchronous request
245 .status(task.getStatusCode())
246 .entity(task.getGenericEntityResponse())
249 // This is an asynchronous request
251 Thread t1 = new Thread(task);
253 } catch (Exception e) {
254 // problem handling create, send generic failure as sync resp to caller
255 LOGGER.error (MessageEnum.RA_DELETE_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while delete network", e);
256 return Response.serverError().build();
258 // send sync response (ACK) to caller
259 LOGGER.debug ("deleteNetwork exit");
260 return Response.status(HttpStatus.SC_ACCEPTED).build();
264 public class DeleteNetworkTask implements Runnable {
265 private final DeleteNetworkRequest req;
266 private DeleteNetworkResponse response = null;
267 private DeleteNetworkError eresp = null;
268 private boolean sendxml;
270 public DeleteNetworkTask(DeleteNetworkRequest req) {
272 this.sendxml = true; // can be set with a field or header later
274 public int getStatusCode() {
275 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
277 public Object getGenericEntityResponse() {
278 return (response != null)
279 ? new GenericEntity<DeleteNetworkResponse>(response) {}
280 : new GenericEntity<DeleteNetworkError>(eresp) {};
282 private String getResponse() {
283 if (response != null) {
284 return sendxml ? response.toXmlString() : response.toJsonString();
286 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
291 LOGGER.debug("DeleteNetworkTask start");
293 Holder<Boolean> networkDeleted = new Holder<Boolean>();
294 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
295 networkDeleted.value = true;
297 adapter.deleteNetwork(
298 req.getCloudSiteId(),
300 req.getNetworkType(),
301 req.getNetworkStackId(),
305 response = new DeleteNetworkResponse(req.getNetworkId(), networkDeleted.value, req.getMessageId());
306 } catch (NetworkException e) {
307 eresp = new DeleteNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
309 if (!req.isSynchronous()) {
310 // This is asynch, so POST response back to caller
311 BpelRestClient bpelClient = new BpelRestClient();
312 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
314 LOGGER.debug("DeleteNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
319 @Path("{aaiNetworkId}")
320 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
321 public Response queryNetwork(
322 @QueryParam("cloudSiteId") String cloudSiteId,
323 @QueryParam("tenantId") String tenantId,
324 @QueryParam("networkStackId") String networkStackId,
325 @QueryParam("skipAAI") String skipAAI,
326 @QueryParam("msoRequest.requestId") String requestId,
327 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId,
328 @PathParam("aaiNetworkId") String aaiNetworkId)
330 //This request responds synchronously only
331 LOGGER.debug ("Query network enter:" + aaiNetworkId);
332 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
335 int respStatus = HttpStatus.SC_OK;
336 QueryNetworkResponse resp = new QueryNetworkResponse(networkStackId, null, networkStackId, null, null);
337 Holder<Boolean> networkExists = new Holder<Boolean>();
338 Holder<String> networkId = new Holder<String>();
339 Holder<String> neutronNetworkId = new Holder<String>();
340 Holder<NetworkStatus> status = new Holder<NetworkStatus>();
341 Holder<List<String>> routeTargets = new Holder<List<String>>();
342 Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>();
344 adapter.queryNetworkContrail(cloudSiteId, tenantId, aaiNetworkId, msoRequest,
345 networkExists, networkId, neutronNetworkId, status, routeTargets, subnetIdMap);
347 if (!networkExists.value) {
348 LOGGER.debug ("network not found");
349 respStatus = HttpStatus.SC_NOT_FOUND;
351 LOGGER.debug ("network found" + networkId.value + ", status=" + status.value);
352 resp.setNetworkExists(networkExists.value);
353 resp.setNetworkId(networkId.value);
354 resp.setNeutronNetworkId(neutronNetworkId.value);
355 resp.setNetworkStatus(status.value);
356 resp.setRouteTargets(routeTargets.value);
357 resp.setSubnetIdMap(subnetIdMap.value);
359 LOGGER.debug ("Query network exit");
362 .entity(new GenericEntity<QueryNetworkResponse>(resp) {})
364 } catch (NetworkException e) {
365 LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, aaiNetworkId, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception when query VNF", e);
366 QueryNetworkError err = new QueryNetworkError();
367 err.setMessage(e.getMessage());
368 err.setCategory(MsoExceptionCategory.INTERNAL);
370 .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
371 .entity(new GenericEntity<QueryNetworkError>(err) {})
377 @Path("{aaiNetworkId}/rollback")
378 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
379 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
380 public Response rollbackNetwork(
381 RollbackNetworkRequest req)
383 LOGGER.debug("rollbackNetwork enter: " + req.toJsonString());
384 RollbackNetworkTask task = new RollbackNetworkTask(req);
385 if (req.isSynchronous()) {
386 // This is a synchronous request
389 .status(task.getStatusCode())
390 .entity(task.getGenericEntityResponse())
393 // This is an asynchronous request
395 Thread t1 = new Thread(task);
397 } catch (Exception e) {
398 // problem handling create, send generic failure as sync resp to caller
399 LOGGER.error (MessageEnum.RA_ROLLBACK_NULL, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in rollbackNetwork", e);
400 return Response.serverError().build();
402 // send sync response (ACK) to caller
403 LOGGER.debug("rollbackNetwork exit");
404 return Response.status(HttpStatus.SC_ACCEPTED).build();
408 public class RollbackNetworkTask implements Runnable {
409 private final RollbackNetworkRequest req;
410 private RollbackNetworkResponse response = null;
411 private RollbackNetworkError eresp = null;
412 private boolean sendxml;
414 public RollbackNetworkTask(RollbackNetworkRequest req) {
416 this.sendxml = true; // can be set with a field or header later
418 public int getStatusCode() {
419 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
421 public Object getGenericEntityResponse() {
422 return (response != null)
423 ? new GenericEntity<RollbackNetworkResponse>(response) {}
424 : new GenericEntity<RollbackNetworkError>(eresp) {};
426 private String getResponse() {
427 if (response != null) {
428 return sendxml ? response.toXmlString() : response.toJsonString();
430 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
435 LOGGER.debug("RollbackNetworkTask start");
437 NetworkRollback nwr = req.getNetworkRollback();
438 adapter.rollbackNetwork(nwr);
439 response = new RollbackNetworkResponse(true, req.getMessageId());
440 } catch (NetworkException e) {
441 eresp = new RollbackNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
443 if (!req.isSynchronous()) {
444 // This is asynch, so POST response back to caller
445 BpelRestClient bpelClient = new BpelRestClient();
446 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
448 LOGGER.debug("RollbackNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
453 @Path("{aaiNetworkId}")
454 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
455 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
456 public Response updateNetwork(
457 @PathParam("aaiNetworkId") String aaiNetworkId,
458 UpdateNetworkRequest req)
460 LOGGER.debug("updateNetwork enter: " + req.toJsonString());
461 if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
463 .status(HttpStatus.SC_BAD_REQUEST)
464 .type(MediaType.TEXT_PLAIN)
465 .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
468 UpdateNetworkTask task = new UpdateNetworkTask(req);
469 if (req.isSynchronous()) {
470 // This is a synchronous request
473 .status(task.getStatusCode())
474 .entity(task.getGenericEntityResponse())
477 // This is an asynchronous request
479 Thread t1 = new Thread(task);
481 } catch (Exception e) {
482 // problem handling create, send generic failure as sync resp to caller
483 LOGGER.error (MessageEnum.RA_UPDATE_NETWORK_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in updateNetwork", e);
484 return Response.serverError().build();
486 // send sync response (ACK) to caller
487 LOGGER.debug ("updateNetwork exit");
488 return Response.status(HttpStatus.SC_ACCEPTED).build();
492 public class UpdateNetworkTask implements Runnable {
493 private final UpdateNetworkRequest req;
494 private UpdateNetworkResponse response = null;
495 private UpdateNetworkError eresp = null;
496 private boolean sendxml;
498 public UpdateNetworkTask(UpdateNetworkRequest req) {
500 this.sendxml = true; // can be set with a field or header later
502 public int getStatusCode() {
503 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
505 public Object getGenericEntityResponse() {
506 return (response != null)
507 ? new GenericEntity<UpdateNetworkResponse>(response) {}
508 : new GenericEntity<UpdateNetworkError>(eresp) {};
510 private String getResponse() {
511 if (response != null) {
512 return sendxml ? response.toXmlString() : response.toJsonString();
514 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
519 LOGGER.debug("UpdateNetworkTask start");
521 Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>();
522 Holder<NetworkRollback> rollback = new Holder<NetworkRollback> ();
524 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
525 subnetIdMap.value = testMap();
526 NetworkRollback rb = new NetworkRollback ();
527 rb.setCloudId(req.getCloudSiteId());
528 rb.setTenantId(req.getTenantId());
529 rb.setMsoRequest(req.getMsoRequest());
531 } else if (req.isContrailRequest()) {
532 ContrailNetwork ctn = req.getContrailNetwork();
534 ctn = new ContrailNetwork();
535 req.setContrailNetwork(ctn);
537 adapter.updateNetworkContrail(
538 req.getCloudSiteId(),
540 req.getNetworkType(),
541 req.getNetworkStackId(),
542 req.getNetworkName(),
543 req.getContrailNetwork().getRouteTargets(),
544 req.getContrailNetwork().getShared(),
545 req.getContrailNetwork().getExternal(),
547 req.getContrailNetwork().getPolicyFqdns(),
548 req.getContrailNetwork().getRouteTableFqdns(),
553 ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
555 pvn = new ProviderVlanNetwork();
556 req.setProviderVlanNetwork(pvn);
558 adapter.updateNetwork(
559 req.getCloudSiteId(),
561 req.getNetworkType(),
562 req.getNetworkStackId(),
563 req.getNetworkName(),
564 req.getProviderVlanNetwork().getPhysicalNetworkName(),
565 req.getProviderVlanNetwork().getVlans(),
571 response = new UpdateNetworkResponse(
573 null, // NeutronNetworkId is not available from an update
576 } catch (NetworkException e) {
577 eresp = new UpdateNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
579 if (!req.isSynchronous()) {
580 // This is asynch, so POST response back to caller
581 BpelRestClient bpelClient = new BpelRestClient();
582 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
584 LOGGER.debug("UpdateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
588 public static Map<String, String> testMap() {
589 Map<String, String> m = new HashMap<String, String>();
590 m.put("mickey", "7");
591 m.put("clyde", "10");
592 m.put("wayne", "99");