2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.openecomp.mso.adapters.network;
25 import java.util.HashMap;
26 import java.util.List;
29 import javax.ws.rs.Consumes;
30 import javax.ws.rs.DELETE;
31 import javax.ws.rs.GET;
32 import javax.ws.rs.POST;
33 import javax.ws.rs.PUT;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.PathParam;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.QueryParam;
38 import javax.ws.rs.core.GenericEntity;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.Response;
41 import javax.xml.ws.Holder;
43 import org.apache.http.HttpStatus;
45 import org.openecomp.mso.adapters.network.exceptions.NetworkException;
46 import org.openecomp.mso.adapters.nwrest.ContrailNetwork;
47 import org.openecomp.mso.adapters.nwrest.CreateNetworkError;
48 import org.openecomp.mso.adapters.nwrest.CreateNetworkRequest;
49 import org.openecomp.mso.adapters.nwrest.CreateNetworkResponse;
50 import org.openecomp.mso.adapters.nwrest.DeleteNetworkError;
51 import org.openecomp.mso.adapters.nwrest.DeleteNetworkRequest;
52 import org.openecomp.mso.adapters.nwrest.DeleteNetworkResponse;
53 import org.openecomp.mso.adapters.nwrest.ProviderVlanNetwork;
54 import org.openecomp.mso.adapters.nwrest.QueryNetworkError;
55 import org.openecomp.mso.adapters.nwrest.QueryNetworkResponse;
56 import org.openecomp.mso.adapters.nwrest.RollbackNetworkError;
57 import org.openecomp.mso.adapters.nwrest.RollbackNetworkRequest;
58 import org.openecomp.mso.adapters.nwrest.RollbackNetworkResponse;
59 import org.openecomp.mso.adapters.nwrest.UpdateNetworkError;
60 import org.openecomp.mso.adapters.nwrest.UpdateNetworkRequest;
61 import org.openecomp.mso.adapters.nwrest.UpdateNetworkResponse;
62 import org.openecomp.mso.cloud.CloudConfigFactory;
63 import org.openecomp.mso.entity.MsoRequest;
64 import org.openecomp.mso.logger.MessageEnum;
65 import org.openecomp.mso.logger.MsoLogger;
66 import org.openecomp.mso.openstack.beans.NetworkRollback;
67 import org.openecomp.mso.openstack.beans.NetworkStatus;
68 import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
69 import org.openecomp.mso.properties.MsoPropertiesFactory;
72 public class NetworkAdapterRest {
73 private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
74 private static final String TESTING_KEYWORD = "___TESTING___";
75 private final CloudConfigFactory cloudConfigFactory = new CloudConfigFactory();
76 private final MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
77 private final MsoNetworkAdapterImpl adapter = new MsoNetworkAdapterImpl(msoPropertiesFactory, cloudConfigFactory);
81 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
82 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
83 public Response createNetwork(CreateNetworkRequest req) {
84 LOGGER.debug("createNetwork enter: " + req.toJsonString());
85 CreateNetworkTask task = new CreateNetworkTask(req);
86 if (req.isSynchronous()) {
87 // This is a synchronous request
90 .status(task.getStatusCode())
91 .entity(task.getGenericEntityResponse())
94 // This is an asynchronous request
96 Thread t1 = new Thread(task);
98 } catch (Exception e) {
99 // problem handling create, send generic failure as sync resp to caller
100 LOGGER.error (MessageEnum.RA_CREATE_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while create network", e);
101 return Response.serverError().build();
103 // send sync response (ACK) to caller
104 LOGGER.debug ("createNetwork exit");
105 return Response.status(HttpStatus.SC_ACCEPTED).build();
109 public class CreateNetworkTask implements Runnable {
110 private final CreateNetworkRequest req;
111 private CreateNetworkResponse response = null;
112 private CreateNetworkError eresp = null;
113 private boolean sendxml;
115 public CreateNetworkTask(CreateNetworkRequest req) {
117 this.sendxml = true; // can be set with a field or header later
119 public int getStatusCode() {
120 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
122 public Object getGenericEntityResponse() {
123 return (response != null)
124 ? new GenericEntity<CreateNetworkResponse>(response) {}
125 : new GenericEntity<CreateNetworkError>(eresp) {};
127 private String getResponse() {
128 if (response != null) {
129 return sendxml ? response.toXmlString() : response.toJsonString();
131 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
136 LOGGER.debug ("CreateNetworkTask start");
138 // Synchronous Web Service Outputs
139 Holder<String> networkId = new Holder<>();
140 Holder<String> neutronNetworkId = new Holder<>();
141 Holder<String> networkFqdn = new Holder<>();
142 Holder<Map<String, String>> subnetIdMap = new Holder<>();
143 Holder<NetworkRollback> rollback = new Holder<>();
145 String cloudsite = req.getCloudSiteId();
146 if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
147 String tenant = req.getTenantId();
148 if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
149 throw new NetworkException("testing.");
151 networkId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
152 neutronNetworkId.value = "55e55884-28fa-11e6-8971-0017f20fe1b8";
153 networkFqdn.value = "086f70b6-28fb-11e6-8260-0017f20fe1b8";
154 subnetIdMap.value = testMap();
155 rollback.value = new NetworkRollback();
156 } else if (req.isContrailRequest()) {
157 ContrailNetwork ctn = req.getContrailNetwork();
159 ctn = new ContrailNetwork();
160 req.setContrailNetwork(ctn);
162 adapter.createNetworkContrail(
163 req.getCloudSiteId(),
165 req.getNetworkType(),
166 req.getModelCustomizationUuid(),
167 req.getNetworkName(),
168 req.getContrailNetwork().getRouteTargets(),
169 req.getContrailNetwork().getShared(),
170 req.getContrailNetwork().getExternal(),
171 req.getFailIfExists(),
174 req.getContrailNetwork().getPolicyFqdns(),
175 req.getContrailNetwork().getRouteTableFqdns(),
183 ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
185 pvn = new ProviderVlanNetwork();
186 req.setProviderVlanNetwork(pvn);
188 adapter.createNetwork(
189 req.getCloudSiteId(),
191 req.getNetworkType(),
192 req.getModelCustomizationUuid(),
193 req.getNetworkName(),
194 req.getProviderVlanNetwork().getPhysicalNetworkName(),
195 req.getProviderVlanNetwork().getVlans(),
196 req.getFailIfExists(),
205 response = new CreateNetworkResponse(
207 neutronNetworkId.value,
208 rollback.value.getNetworkStackId(),
210 rollback.value.getNetworkCreated(),
214 } catch (NetworkException e) {
215 LOGGER.debug ("Exception:", e);
216 eresp = new CreateNetworkError(
217 e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
219 if (!req.isSynchronous()) {
220 // This is asynch, so POST response back to caller
221 BpelRestClient bpelClient = new BpelRestClient();
222 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
224 LOGGER.debug ("CreateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
229 @Path("{aaiNetworkId}")
230 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
231 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
232 public Response deleteNetwork(
233 @PathParam("aaiNetworkId") String aaiNetworkId,
234 DeleteNetworkRequest req)
236 LOGGER.debug("deleteNetwork enter: " + req.toJsonString());
237 if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
239 .status(HttpStatus.SC_BAD_REQUEST)
240 .type(MediaType.TEXT_PLAIN)
241 .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
244 DeleteNetworkTask task = new DeleteNetworkTask(req);
245 if (req.isSynchronous()) {
246 // This is a synchronous request
249 .status(task.getStatusCode())
250 .entity(task.getGenericEntityResponse())
253 // This is an asynchronous request
255 Thread t1 = new Thread(task);
257 } catch (Exception e) {
258 // problem handling create, send generic failure as sync resp to caller
259 LOGGER.error (MessageEnum.RA_DELETE_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while delete network", e);
260 return Response.serverError().build();
262 // send sync response (ACK) to caller
263 LOGGER.debug ("deleteNetwork exit");
264 return Response.status(HttpStatus.SC_ACCEPTED).build();
268 public class DeleteNetworkTask implements Runnable {
269 private final DeleteNetworkRequest req;
270 private DeleteNetworkResponse response = null;
271 private DeleteNetworkError eresp = null;
272 private boolean sendxml;
274 public DeleteNetworkTask(DeleteNetworkRequest req) {
276 this.sendxml = true; // can be set with a field or header later
278 public int getStatusCode() {
279 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
281 public Object getGenericEntityResponse() {
282 return (response != null)
283 ? new GenericEntity<DeleteNetworkResponse>(response) {}
284 : new GenericEntity<DeleteNetworkError>(eresp) {};
286 private String getResponse() {
287 if (response != null) {
288 return sendxml ? response.toXmlString() : response.toJsonString();
290 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
295 LOGGER.debug("DeleteNetworkTask start");
297 Holder<Boolean> networkDeleted = new Holder<>();
298 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
299 networkDeleted.value = true;
301 adapter.deleteNetwork(
302 req.getCloudSiteId(),
304 req.getNetworkType(),
305 req.getModelCustomizationUuid(),
306 req.getNetworkStackId(),
310 response = new DeleteNetworkResponse(req.getNetworkId(), networkDeleted.value, req.getMessageId());
311 } catch (NetworkException e) {
312 LOGGER.debug ("Exception:", e);
313 eresp = new DeleteNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
315 if (!req.isSynchronous()) {
316 // This is asynch, so POST response back to caller
317 BpelRestClient bpelClient = new BpelRestClient();
318 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
320 LOGGER.debug("DeleteNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
325 @Path("{aaiNetworkId}")
326 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
327 public Response queryNetwork(
328 @QueryParam("cloudSiteId") String cloudSiteId,
329 @QueryParam("tenantId") String tenantId,
330 @QueryParam("networkStackId") String networkStackId,
331 @QueryParam("skipAAI") String skipAAI,
332 @QueryParam("msoRequest.requestId") String requestId,
333 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId,
334 @PathParam("aaiNetworkId") String aaiNetworkId)
336 //This request responds synchronously only
337 LOGGER.debug ("Query network enter:" + aaiNetworkId);
338 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
341 int respStatus = HttpStatus.SC_OK;
342 QueryNetworkResponse resp = new QueryNetworkResponse(networkStackId, null, networkStackId, null, null);
343 Holder<Boolean> networkExists = new Holder<>();
344 Holder<String> networkId = new Holder<>();
345 Holder<String> neutronNetworkId = new Holder<>();
346 Holder<NetworkStatus> status = new Holder<>();
347 Holder<List<String>> routeTargets = new Holder<>();
348 Holder<Map<String, String>> subnetIdMap = new Holder<>();
350 adapter.queryNetworkContrail(cloudSiteId, tenantId, aaiNetworkId, msoRequest,
351 networkExists, networkId, neutronNetworkId, status, routeTargets, subnetIdMap);
353 if (!networkExists.value) {
354 LOGGER.debug ("network not found");
355 respStatus = HttpStatus.SC_NOT_FOUND;
357 LOGGER.debug ("network found" + networkId.value + ", status=" + status.value);
358 resp.setNetworkExists(networkExists.value);
359 resp.setNetworkId(networkId.value);
360 resp.setNeutronNetworkId(neutronNetworkId.value);
361 resp.setNetworkStatus(status.value);
362 resp.setRouteTargets(routeTargets.value);
363 resp.setSubnetIdMap(subnetIdMap.value);
365 LOGGER.debug ("Query network exit");
368 .entity(new GenericEntity<QueryNetworkResponse>(resp) {})
370 } catch (NetworkException e) {
371 LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, aaiNetworkId, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception when query VNF", e);
372 QueryNetworkError err = new QueryNetworkError();
373 err.setMessage(e.getMessage());
374 err.setCategory(MsoExceptionCategory.INTERNAL);
376 .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
377 .entity(new GenericEntity<QueryNetworkError>(err) {})
383 @Path("{aaiNetworkId}/rollback")
384 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
385 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
386 public Response rollbackNetwork(
387 RollbackNetworkRequest req)
389 LOGGER.debug("rollbackNetwork enter: " + req.toJsonString());
390 RollbackNetworkTask task = new RollbackNetworkTask(req);
391 if (req.isSynchronous()) {
392 // This is a synchronous request
395 .status(task.getStatusCode())
396 .entity(task.getGenericEntityResponse())
399 // This is an asynchronous request
401 Thread t1 = new Thread(task);
403 } catch (Exception e) {
404 // problem handling create, send generic failure as sync resp to caller
405 LOGGER.error (MessageEnum.RA_ROLLBACK_NULL, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in rollbackNetwork", e);
406 return Response.serverError().build();
408 // send sync response (ACK) to caller
409 LOGGER.debug("rollbackNetwork exit");
410 return Response.status(HttpStatus.SC_ACCEPTED).build();
414 public class RollbackNetworkTask implements Runnable {
415 private final RollbackNetworkRequest req;
416 private RollbackNetworkResponse response = null;
417 private RollbackNetworkError eresp = null;
418 private boolean sendxml;
420 public RollbackNetworkTask(RollbackNetworkRequest req) {
422 this.sendxml = true; // can be set with a field or header later
424 public int getStatusCode() {
425 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
427 public Object getGenericEntityResponse() {
428 return (response != null)
429 ? new GenericEntity<RollbackNetworkResponse>(response) {}
430 : new GenericEntity<RollbackNetworkError>(eresp) {};
432 private String getResponse() {
433 if (response != null) {
434 return sendxml ? response.toXmlString() : response.toJsonString();
436 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
441 LOGGER.debug("RollbackNetworkTask start");
443 NetworkRollback nwr = req.getNetworkRollback();
444 adapter.rollbackNetwork(nwr);
445 response = new RollbackNetworkResponse(true, req.getMessageId());
446 } catch (NetworkException e) {
447 LOGGER.debug ("Exception:", e);
448 eresp = new RollbackNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
450 if (!req.isSynchronous()) {
451 // This is asynch, so POST response back to caller
452 BpelRestClient bpelClient = new BpelRestClient();
453 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
455 LOGGER.debug("RollbackNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
460 @Path("{aaiNetworkId}")
461 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
462 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
463 public Response updateNetwork(
464 @PathParam("aaiNetworkId") String aaiNetworkId,
465 UpdateNetworkRequest req)
467 LOGGER.debug("updateNetwork enter: " + req.toJsonString());
468 if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
470 .status(HttpStatus.SC_BAD_REQUEST)
471 .type(MediaType.TEXT_PLAIN)
472 .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
475 UpdateNetworkTask task = new UpdateNetworkTask(req);
476 if (req.isSynchronous()) {
477 // This is a synchronous request
480 .status(task.getStatusCode())
481 .entity(task.getGenericEntityResponse())
484 // This is an asynchronous request
486 Thread t1 = new Thread(task);
488 } catch (Exception e) {
489 // problem handling create, send generic failure as sync resp to caller
490 LOGGER.error (MessageEnum.RA_UPDATE_NETWORK_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in updateNetwork", e);
491 return Response.serverError().build();
493 // send sync response (ACK) to caller
494 LOGGER.debug ("updateNetwork exit");
495 return Response.status(HttpStatus.SC_ACCEPTED).build();
499 public class UpdateNetworkTask implements Runnable {
500 private final UpdateNetworkRequest req;
501 private UpdateNetworkResponse response = null;
502 private UpdateNetworkError eresp = null;
503 private boolean sendxml;
505 public UpdateNetworkTask(UpdateNetworkRequest req) {
507 this.sendxml = true; // can be set with a field or header later
509 public int getStatusCode() {
510 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
512 public Object getGenericEntityResponse() {
513 return (response != null)
514 ? new GenericEntity<UpdateNetworkResponse>(response) {}
515 : new GenericEntity<UpdateNetworkError>(eresp) {};
517 private String getResponse() {
518 if (response != null) {
519 return sendxml ? response.toXmlString() : response.toJsonString();
521 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
526 LOGGER.debug("UpdateNetworkTask start");
528 Holder<Map<String, String>> subnetIdMap = new Holder<>();
529 Holder<NetworkRollback> rollback = new Holder<> ();
531 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
532 subnetIdMap.value = testMap();
533 NetworkRollback rb = new NetworkRollback ();
534 rb.setCloudId(req.getCloudSiteId());
535 rb.setTenantId(req.getTenantId());
536 rb.setMsoRequest(req.getMsoRequest());
538 } else if (req.isContrailRequest()) {
539 ContrailNetwork ctn = req.getContrailNetwork();
541 ctn = new ContrailNetwork();
542 req.setContrailNetwork(ctn);
544 adapter.updateNetworkContrail(
545 req.getCloudSiteId(),
547 req.getNetworkType(),
548 req.getModelCustomizationUuid(),
549 req.getNetworkStackId(),
550 req.getNetworkName(),
551 req.getContrailNetwork().getRouteTargets(),
552 req.getContrailNetwork().getShared(),
553 req.getContrailNetwork().getExternal(),
555 req.getContrailNetwork().getPolicyFqdns(),
556 req.getContrailNetwork().getRouteTableFqdns(),
561 ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
563 pvn = new ProviderVlanNetwork();
564 req.setProviderVlanNetwork(pvn);
566 adapter.updateNetwork(
567 req.getCloudSiteId(),
569 req.getNetworkType(),
570 req.getModelCustomizationUuid(),
571 req.getNetworkStackId(),
572 req.getNetworkName(),
573 req.getProviderVlanNetwork().getPhysicalNetworkName(),
574 req.getProviderVlanNetwork().getVlans(),
580 response = new UpdateNetworkResponse(
582 null, // NeutronNetworkId is not available from an update
585 } catch (NetworkException e) {
586 LOGGER.debug ("Exception:", e);
587 eresp = new UpdateNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
589 if (!req.isSynchronous()) {
590 // This is asynch, so POST response back to caller
591 BpelRestClient bpelClient = new BpelRestClient();
592 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
594 LOGGER.debug("UpdateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
598 public static Map<String, String> testMap() {
599 Map<String, String> m = new HashMap<>();
600 m.put("mickey", "7");
601 m.put("clyde", "10");
602 m.put("wayne", "99");