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.beans.RouteTarget;
69 import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
70 import org.openecomp.mso.properties.MsoPropertiesFactory;
73 public class NetworkAdapterRest {
74 private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
75 private static final String TESTING_KEYWORD = "___TESTING___";
76 private final CloudConfigFactory cloudConfigFactory = new CloudConfigFactory();
77 private final MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
78 private final MsoNetworkAdapterImpl adapter = new MsoNetworkAdapterImpl(msoPropertiesFactory, cloudConfigFactory);
82 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
83 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
84 public Response createNetwork(CreateNetworkRequest req) {
85 LOGGER.debug("createNetwork enter: " + req.toJsonString());
86 CreateNetworkTask task = new CreateNetworkTask(req);
87 if (req.isSynchronous()) {
88 // This is a synchronous request
91 .status(task.getStatusCode())
92 .entity(task.getGenericEntityResponse())
95 // This is an asynchronous request
97 Thread t1 = new Thread(task);
99 } catch (Exception e) {
100 // problem handling create, send generic failure as sync resp to caller
101 LOGGER.error (MessageEnum.RA_CREATE_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while create network", e);
102 return Response.serverError().build();
104 // send sync response (ACK) to caller
105 LOGGER.debug ("createNetwork exit");
106 return Response.status(HttpStatus.SC_ACCEPTED).build();
110 public class CreateNetworkTask implements Runnable {
111 private final CreateNetworkRequest req;
112 private CreateNetworkResponse response = null;
113 private CreateNetworkError eresp = null;
114 private boolean sendxml;
116 public CreateNetworkTask(CreateNetworkRequest req) {
118 this.sendxml = true; // can be set with a field or header later
120 public int getStatusCode() {
121 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
123 public Object getGenericEntityResponse() {
124 return (response != null)
125 ? new GenericEntity<CreateNetworkResponse>(response) {}
126 : new GenericEntity<CreateNetworkError>(eresp) {};
128 private String getResponse() {
129 if (response != null) {
130 return sendxml ? response.toXmlString() : response.toJsonString();
132 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
137 LOGGER.debug ("CreateNetworkTask start");
139 // Synchronous Web Service Outputs
140 Holder<String> networkId = new Holder<>();
141 Holder<String> neutronNetworkId = new Holder<>();
142 Holder<String> networkFqdn = new Holder<>();
143 Holder<Map<String, String>> subnetIdMap = new Holder<>();
144 Holder<NetworkRollback> rollback = new Holder<>();
146 String cloudsite = req.getCloudSiteId();
147 if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
148 String tenant = req.getTenantId();
149 if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
150 throw new NetworkException("testing.");
152 networkId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
153 neutronNetworkId.value = "55e55884-28fa-11e6-8971-0017f20fe1b8";
154 networkFqdn.value = "086f70b6-28fb-11e6-8260-0017f20fe1b8";
155 subnetIdMap.value = testMap();
156 rollback.value = new NetworkRollback();
157 } else if (req.isContrailRequest()) {
158 ContrailNetwork ctn = req.getContrailNetwork();
160 ctn = new ContrailNetwork();
161 req.setContrailNetwork(ctn);
163 adapter.createNetworkContrail(
164 req.getCloudSiteId(),
166 req.getNetworkType(),
167 req.getModelCustomizationUuid(),
168 req.getNetworkName(),
169 req.getContrailNetwork().getRouteTargets(),
170 req.getContrailNetwork().getShared(),
171 req.getContrailNetwork().getExternal(),
172 req.getFailIfExists(),
175 req.getContrailNetwork().getPolicyFqdns(),
176 req.getContrailNetwork().getRouteTableFqdns(),
184 ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
186 pvn = new ProviderVlanNetwork();
187 req.setProviderVlanNetwork(pvn);
189 adapter.createNetwork(
190 req.getCloudSiteId(),
192 req.getNetworkType(),
193 req.getModelCustomizationUuid(),
194 req.getNetworkName(),
195 req.getProviderVlanNetwork().getPhysicalNetworkName(),
196 req.getProviderVlanNetwork().getVlans(),
197 req.getFailIfExists(),
206 response = new CreateNetworkResponse(
208 neutronNetworkId.value,
209 rollback.value.getNetworkStackId(),
211 rollback.value.getNetworkCreated(),
215 } catch (NetworkException e) {
216 LOGGER.debug ("Exception:", e);
217 eresp = new CreateNetworkError(
218 e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
220 if (!req.isSynchronous()) {
221 // This is asynch, so POST response back to caller
222 BpelRestClient bpelClient = new BpelRestClient();
223 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
225 LOGGER.debug ("CreateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
230 @Path("{aaiNetworkId}")
231 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
232 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
233 public Response deleteNetwork(
234 @PathParam("aaiNetworkId") String aaiNetworkId,
235 DeleteNetworkRequest req)
237 LOGGER.debug("deleteNetwork enter: " + req.toJsonString());
238 if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
240 .status(HttpStatus.SC_BAD_REQUEST)
241 .type(MediaType.TEXT_PLAIN)
242 .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
245 DeleteNetworkTask task = new DeleteNetworkTask(req);
246 if (req.isSynchronous()) {
247 // This is a synchronous request
250 .status(task.getStatusCode())
251 .entity(task.getGenericEntityResponse())
254 // This is an asynchronous request
256 Thread t1 = new Thread(task);
258 } catch (Exception e) {
259 // problem handling create, send generic failure as sync resp to caller
260 LOGGER.error (MessageEnum.RA_DELETE_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while delete network", e);
261 return Response.serverError().build();
263 // send sync response (ACK) to caller
264 LOGGER.debug ("deleteNetwork exit");
265 return Response.status(HttpStatus.SC_ACCEPTED).build();
269 public class DeleteNetworkTask implements Runnable {
270 private final DeleteNetworkRequest req;
271 private DeleteNetworkResponse response = null;
272 private DeleteNetworkError eresp = null;
273 private boolean sendxml;
275 public DeleteNetworkTask(DeleteNetworkRequest req) {
277 this.sendxml = true; // can be set with a field or header later
279 public int getStatusCode() {
280 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
282 public Object getGenericEntityResponse() {
283 return (response != null)
284 ? new GenericEntity<DeleteNetworkResponse>(response) {}
285 : new GenericEntity<DeleteNetworkError>(eresp) {};
287 private String getResponse() {
288 if (response != null) {
289 return sendxml ? response.toXmlString() : response.toJsonString();
291 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
296 LOGGER.debug("DeleteNetworkTask start");
298 Holder<Boolean> networkDeleted = new Holder<>();
299 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
300 networkDeleted.value = true;
302 adapter.deleteNetwork(
303 req.getCloudSiteId(),
305 req.getNetworkType(),
306 req.getModelCustomizationUuid(),
307 req.getNetworkStackId(),
311 response = new DeleteNetworkResponse(req.getNetworkId(), networkDeleted.value, req.getMessageId());
312 } catch (NetworkException e) {
313 LOGGER.debug ("Exception:", e);
314 eresp = new DeleteNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
316 if (!req.isSynchronous()) {
317 // This is asynch, so POST response back to caller
318 BpelRestClient bpelClient = new BpelRestClient();
319 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
321 LOGGER.debug("DeleteNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
326 @Path("{aaiNetworkId}")
327 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
328 public Response queryNetwork(
329 @QueryParam("cloudSiteId") String cloudSiteId,
330 @QueryParam("tenantId") String tenantId,
331 @QueryParam("networkStackId") String networkStackId,
332 @QueryParam("skipAAI") String skipAAI,
333 @QueryParam("msoRequest.requestId") String requestId,
334 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId,
335 @PathParam("aaiNetworkId") String aaiNetworkId)
337 //This request responds synchronously only
338 LOGGER.debug ("Query network enter:" + aaiNetworkId);
339 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
342 int respStatus = HttpStatus.SC_OK;
343 QueryNetworkResponse resp = new QueryNetworkResponse(networkStackId, null, networkStackId, null, null);
344 Holder<Boolean> networkExists = new Holder<>();
345 Holder<String> networkId = new Holder<>();
346 Holder<String> neutronNetworkId = new Holder<>();
347 Holder<NetworkStatus> status = new Holder<>();
348 Holder<List<RouteTarget>> routeTargets = new Holder<>();
349 Holder<Map<String, String>> subnetIdMap = new Holder<>();
351 adapter.queryNetworkContrail(cloudSiteId, tenantId, aaiNetworkId, msoRequest,
352 networkExists, networkId, neutronNetworkId, status, routeTargets, subnetIdMap);
354 if (!networkExists.value) {
355 LOGGER.debug ("network not found");
356 respStatus = HttpStatus.SC_NOT_FOUND;
358 LOGGER.debug ("network found" + networkId.value + ", status=" + status.value);
359 resp.setNetworkExists(networkExists.value);
360 resp.setNetworkId(networkId.value);
361 resp.setNeutronNetworkId(neutronNetworkId.value);
362 resp.setNetworkStatus(status.value);
363 resp.setRouteTargets(routeTargets.value);
364 resp.setSubnetIdMap(subnetIdMap.value);
366 LOGGER.debug ("Query network exit");
369 .entity(new GenericEntity<QueryNetworkResponse>(resp) {})
371 } catch (NetworkException e) {
372 LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, aaiNetworkId, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception when query VNF", e);
373 QueryNetworkError err = new QueryNetworkError();
374 err.setMessage(e.getMessage());
375 err.setCategory(MsoExceptionCategory.INTERNAL);
377 .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
378 .entity(new GenericEntity<QueryNetworkError>(err) {})
384 @Path("{aaiNetworkId}/rollback")
385 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
386 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
387 public Response rollbackNetwork(
388 RollbackNetworkRequest req)
390 LOGGER.debug("rollbackNetwork enter: " + req.toJsonString());
391 RollbackNetworkTask task = new RollbackNetworkTask(req);
392 if (req.isSynchronous()) {
393 // This is a synchronous request
396 .status(task.getStatusCode())
397 .entity(task.getGenericEntityResponse())
400 // This is an asynchronous request
402 Thread t1 = new Thread(task);
404 } catch (Exception e) {
405 // problem handling create, send generic failure as sync resp to caller
406 LOGGER.error (MessageEnum.RA_ROLLBACK_NULL, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in rollbackNetwork", e);
407 return Response.serverError().build();
409 // send sync response (ACK) to caller
410 LOGGER.debug("rollbackNetwork exit");
411 return Response.status(HttpStatus.SC_ACCEPTED).build();
415 public class RollbackNetworkTask implements Runnable {
416 private final RollbackNetworkRequest req;
417 private RollbackNetworkResponse response = null;
418 private RollbackNetworkError eresp = null;
419 private boolean sendxml;
421 public RollbackNetworkTask(RollbackNetworkRequest req) {
423 this.sendxml = true; // can be set with a field or header later
425 public int getStatusCode() {
426 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
428 public Object getGenericEntityResponse() {
429 return (response != null)
430 ? new GenericEntity<RollbackNetworkResponse>(response) {}
431 : new GenericEntity<RollbackNetworkError>(eresp) {};
433 private String getResponse() {
434 if (response != null) {
435 return sendxml ? response.toXmlString() : response.toJsonString();
437 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
442 LOGGER.debug("RollbackNetworkTask start");
444 NetworkRollback nwr = req.getNetworkRollback();
445 adapter.rollbackNetwork(nwr);
446 response = new RollbackNetworkResponse(true, req.getMessageId());
447 } catch (NetworkException e) {
448 LOGGER.debug ("Exception:", e);
449 eresp = new RollbackNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
451 if (!req.isSynchronous()) {
452 // This is asynch, so POST response back to caller
453 BpelRestClient bpelClient = new BpelRestClient();
454 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
456 LOGGER.debug("RollbackNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
461 @Path("{aaiNetworkId}")
462 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
463 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
464 public Response updateNetwork(
465 @PathParam("aaiNetworkId") String aaiNetworkId,
466 UpdateNetworkRequest req)
468 LOGGER.debug("updateNetwork enter: " + req.toJsonString());
469 if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
471 .status(HttpStatus.SC_BAD_REQUEST)
472 .type(MediaType.TEXT_PLAIN)
473 .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
476 UpdateNetworkTask task = new UpdateNetworkTask(req);
477 if (req.isSynchronous()) {
478 // This is a synchronous request
481 .status(task.getStatusCode())
482 .entity(task.getGenericEntityResponse())
485 // This is an asynchronous request
487 Thread t1 = new Thread(task);
489 } catch (Exception e) {
490 // problem handling create, send generic failure as sync resp to caller
491 LOGGER.error (MessageEnum.RA_UPDATE_NETWORK_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in updateNetwork", e);
492 return Response.serverError().build();
494 // send sync response (ACK) to caller
495 LOGGER.debug ("updateNetwork exit");
496 return Response.status(HttpStatus.SC_ACCEPTED).build();
500 public class UpdateNetworkTask implements Runnable {
501 private final UpdateNetworkRequest req;
502 private UpdateNetworkResponse response = null;
503 private UpdateNetworkError eresp = null;
504 private boolean sendxml;
506 public UpdateNetworkTask(UpdateNetworkRequest req) {
508 this.sendxml = true; // can be set with a field or header later
510 public int getStatusCode() {
511 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
513 public Object getGenericEntityResponse() {
514 return (response != null)
515 ? new GenericEntity<UpdateNetworkResponse>(response) {}
516 : new GenericEntity<UpdateNetworkError>(eresp) {};
518 private String getResponse() {
519 if (response != null) {
520 return sendxml ? response.toXmlString() : response.toJsonString();
522 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
527 LOGGER.debug("UpdateNetworkTask start");
529 Holder<Map<String, String>> subnetIdMap = new Holder<>();
530 Holder<NetworkRollback> rollback = new Holder<> ();
532 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
533 subnetIdMap.value = testMap();
534 NetworkRollback rb = new NetworkRollback ();
535 rb.setCloudId(req.getCloudSiteId());
536 rb.setTenantId(req.getTenantId());
537 rb.setMsoRequest(req.getMsoRequest());
539 } else if (req.isContrailRequest()) {
540 ContrailNetwork ctn = req.getContrailNetwork();
542 ctn = new ContrailNetwork();
543 req.setContrailNetwork(ctn);
545 adapter.updateNetworkContrail(
546 req.getCloudSiteId(),
548 req.getNetworkType(),
549 req.getModelCustomizationUuid(),
550 req.getNetworkStackId(),
551 req.getNetworkName(),
552 req.getContrailNetwork().getRouteTargets(),
553 req.getContrailNetwork().getShared(),
554 req.getContrailNetwork().getExternal(),
556 req.getContrailNetwork().getPolicyFqdns(),
557 req.getContrailNetwork().getRouteTableFqdns(),
562 ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
564 pvn = new ProviderVlanNetwork();
565 req.setProviderVlanNetwork(pvn);
567 adapter.updateNetwork(
568 req.getCloudSiteId(),
570 req.getNetworkType(),
571 req.getModelCustomizationUuid(),
572 req.getNetworkStackId(),
573 req.getNetworkName(),
574 req.getProviderVlanNetwork().getPhysicalNetworkName(),
575 req.getProviderVlanNetwork().getVlans(),
581 response = new UpdateNetworkResponse(
583 null, // NeutronNetworkId is not available from an update
586 } catch (NetworkException e) {
587 LOGGER.debug ("Exception:", e);
588 eresp = new UpdateNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
590 if (!req.isSynchronous()) {
591 // This is asynch, so POST response back to caller
592 BpelRestClient bpelClient = new BpelRestClient();
593 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
595 LOGGER.debug("UpdateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
599 public static Map<String, String> testMap() {
600 Map<String, String> m = new HashMap<>();
601 m.put("mickey", "7");
602 m.put("clyde", "10");
603 m.put("wayne", "99");