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.getModelCustomizationUuid(),
166 req.getNetworkName(),
167 req.getContrailNetwork().getRouteTargets(),
168 req.getContrailNetwork().getShared(),
169 req.getContrailNetwork().getExternal(),
170 req.getFailIfExists(),
173 req.getContrailNetwork().getPolicyFqdns(),
174 req.getContrailNetwork().getRouteTableFqdns(),
182 ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
184 pvn = new ProviderVlanNetwork();
185 req.setProviderVlanNetwork(pvn);
187 adapter.createNetwork(
188 req.getCloudSiteId(),
190 req.getNetworkType(),
191 req.getModelCustomizationUuid(),
192 req.getNetworkName(),
193 req.getProviderVlanNetwork().getPhysicalNetworkName(),
194 req.getProviderVlanNetwork().getVlans(),
195 req.getFailIfExists(),
204 response = new CreateNetworkResponse(
206 neutronNetworkId.value,
207 rollback.value.getNetworkStackId(),
209 rollback.value.getNetworkCreated(),
213 } catch (NetworkException e) {
214 eresp = new CreateNetworkError(
215 e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
217 if (!req.isSynchronous()) {
218 // This is asynch, so POST response back to caller
219 BpelRestClient bpelClient = new BpelRestClient();
220 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
222 LOGGER.debug ("CreateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
227 @Path("{aaiNetworkId}")
228 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
229 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
230 public Response deleteNetwork(
231 @PathParam("aaiNetworkId") String aaiNetworkId,
232 DeleteNetworkRequest req)
234 LOGGER.debug("deleteNetwork enter: " + req.toJsonString());
235 if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
237 .status(HttpStatus.SC_BAD_REQUEST)
238 .type(MediaType.TEXT_PLAIN)
239 .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
242 DeleteNetworkTask task = new DeleteNetworkTask(req);
243 if (req.isSynchronous()) {
244 // This is a synchronous request
247 .status(task.getStatusCode())
248 .entity(task.getGenericEntityResponse())
251 // This is an asynchronous request
253 Thread t1 = new Thread(task);
255 } catch (Exception e) {
256 // problem handling create, send generic failure as sync resp to caller
257 LOGGER.error (MessageEnum.RA_DELETE_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while delete network", e);
258 return Response.serverError().build();
260 // send sync response (ACK) to caller
261 LOGGER.debug ("deleteNetwork exit");
262 return Response.status(HttpStatus.SC_ACCEPTED).build();
266 public class DeleteNetworkTask implements Runnable {
267 private final DeleteNetworkRequest req;
268 private DeleteNetworkResponse response = null;
269 private DeleteNetworkError eresp = null;
270 private boolean sendxml;
272 public DeleteNetworkTask(DeleteNetworkRequest req) {
274 this.sendxml = true; // can be set with a field or header later
276 public int getStatusCode() {
277 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
279 public Object getGenericEntityResponse() {
280 return (response != null)
281 ? new GenericEntity<DeleteNetworkResponse>(response) {}
282 : new GenericEntity<DeleteNetworkError>(eresp) {};
284 private String getResponse() {
285 if (response != null) {
286 return sendxml ? response.toXmlString() : response.toJsonString();
288 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
293 LOGGER.debug("DeleteNetworkTask start");
295 Holder<Boolean> networkDeleted = new Holder<Boolean>();
296 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
297 networkDeleted.value = true;
299 adapter.deleteNetwork(
300 req.getCloudSiteId(),
302 req.getNetworkType(),
303 req.getModelCustomizationUuid(),
304 req.getNetworkStackId(),
308 response = new DeleteNetworkResponse(req.getNetworkId(), networkDeleted.value, req.getMessageId());
309 } catch (NetworkException e) {
310 eresp = new DeleteNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
312 if (!req.isSynchronous()) {
313 // This is asynch, so POST response back to caller
314 BpelRestClient bpelClient = new BpelRestClient();
315 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
317 LOGGER.debug("DeleteNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
322 @Path("{aaiNetworkId}")
323 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
324 public Response queryNetwork(
325 @QueryParam("cloudSiteId") String cloudSiteId,
326 @QueryParam("tenantId") String tenantId,
327 @QueryParam("networkStackId") String networkStackId,
328 @QueryParam("skipAAI") String skipAAI,
329 @QueryParam("msoRequest.requestId") String requestId,
330 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId,
331 @PathParam("aaiNetworkId") String aaiNetworkId)
333 //This request responds synchronously only
334 LOGGER.debug ("Query network enter:" + aaiNetworkId);
335 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
338 int respStatus = HttpStatus.SC_OK;
339 QueryNetworkResponse resp = new QueryNetworkResponse(networkStackId, null, networkStackId, null, null);
340 Holder<Boolean> networkExists = new Holder<Boolean>();
341 Holder<String> networkId = new Holder<String>();
342 Holder<String> neutronNetworkId = new Holder<String>();
343 Holder<NetworkStatus> status = new Holder<NetworkStatus>();
344 Holder<List<String>> routeTargets = new Holder<List<String>>();
345 Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>();
347 adapter.queryNetworkContrail(cloudSiteId, tenantId, aaiNetworkId, msoRequest,
348 networkExists, networkId, neutronNetworkId, status, routeTargets, subnetIdMap);
350 if (!networkExists.value) {
351 LOGGER.debug ("network not found");
352 respStatus = HttpStatus.SC_NOT_FOUND;
354 LOGGER.debug ("network found" + networkId.value + ", status=" + status.value);
355 resp.setNetworkExists(networkExists.value);
356 resp.setNetworkId(networkId.value);
357 resp.setNeutronNetworkId(neutronNetworkId.value);
358 resp.setNetworkStatus(status.value);
359 resp.setRouteTargets(routeTargets.value);
360 resp.setSubnetIdMap(subnetIdMap.value);
362 LOGGER.debug ("Query network exit");
365 .entity(new GenericEntity<QueryNetworkResponse>(resp) {})
367 } catch (NetworkException e) {
368 LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, aaiNetworkId, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception when query VNF", e);
369 QueryNetworkError err = new QueryNetworkError();
370 err.setMessage(e.getMessage());
371 err.setCategory(MsoExceptionCategory.INTERNAL);
373 .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
374 .entity(new GenericEntity<QueryNetworkError>(err) {})
380 @Path("{aaiNetworkId}/rollback")
381 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
382 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
383 public Response rollbackNetwork(
384 RollbackNetworkRequest req)
386 LOGGER.debug("rollbackNetwork enter: " + req.toJsonString());
387 RollbackNetworkTask task = new RollbackNetworkTask(req);
388 if (req.isSynchronous()) {
389 // This is a synchronous request
392 .status(task.getStatusCode())
393 .entity(task.getGenericEntityResponse())
396 // This is an asynchronous request
398 Thread t1 = new Thread(task);
400 } catch (Exception e) {
401 // problem handling create, send generic failure as sync resp to caller
402 LOGGER.error (MessageEnum.RA_ROLLBACK_NULL, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in rollbackNetwork", e);
403 return Response.serverError().build();
405 // send sync response (ACK) to caller
406 LOGGER.debug("rollbackNetwork exit");
407 return Response.status(HttpStatus.SC_ACCEPTED).build();
411 public class RollbackNetworkTask implements Runnable {
412 private final RollbackNetworkRequest req;
413 private RollbackNetworkResponse response = null;
414 private RollbackNetworkError eresp = null;
415 private boolean sendxml;
417 public RollbackNetworkTask(RollbackNetworkRequest req) {
419 this.sendxml = true; // can be set with a field or header later
421 public int getStatusCode() {
422 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
424 public Object getGenericEntityResponse() {
425 return (response != null)
426 ? new GenericEntity<RollbackNetworkResponse>(response) {}
427 : new GenericEntity<RollbackNetworkError>(eresp) {};
429 private String getResponse() {
430 if (response != null) {
431 return sendxml ? response.toXmlString() : response.toJsonString();
433 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
438 LOGGER.debug("RollbackNetworkTask start");
440 NetworkRollback nwr = req.getNetworkRollback();
441 adapter.rollbackNetwork(nwr);
442 response = new RollbackNetworkResponse(true, req.getMessageId());
443 } catch (NetworkException e) {
444 eresp = new RollbackNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
446 if (!req.isSynchronous()) {
447 // This is asynch, so POST response back to caller
448 BpelRestClient bpelClient = new BpelRestClient();
449 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
451 LOGGER.debug("RollbackNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
456 @Path("{aaiNetworkId}")
457 @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
458 @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
459 public Response updateNetwork(
460 @PathParam("aaiNetworkId") String aaiNetworkId,
461 UpdateNetworkRequest req)
463 LOGGER.debug("updateNetwork enter: " + req.toJsonString());
464 if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
466 .status(HttpStatus.SC_BAD_REQUEST)
467 .type(MediaType.TEXT_PLAIN)
468 .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
471 UpdateNetworkTask task = new UpdateNetworkTask(req);
472 if (req.isSynchronous()) {
473 // This is a synchronous request
476 .status(task.getStatusCode())
477 .entity(task.getGenericEntityResponse())
480 // This is an asynchronous request
482 Thread t1 = new Thread(task);
484 } catch (Exception e) {
485 // problem handling create, send generic failure as sync resp to caller
486 LOGGER.error (MessageEnum.RA_UPDATE_NETWORK_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in updateNetwork", e);
487 return Response.serverError().build();
489 // send sync response (ACK) to caller
490 LOGGER.debug ("updateNetwork exit");
491 return Response.status(HttpStatus.SC_ACCEPTED).build();
495 public class UpdateNetworkTask implements Runnable {
496 private final UpdateNetworkRequest req;
497 private UpdateNetworkResponse response = null;
498 private UpdateNetworkError eresp = null;
499 private boolean sendxml;
501 public UpdateNetworkTask(UpdateNetworkRequest req) {
503 this.sendxml = true; // can be set with a field or header later
505 public int getStatusCode() {
506 return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
508 public Object getGenericEntityResponse() {
509 return (response != null)
510 ? new GenericEntity<UpdateNetworkResponse>(response) {}
511 : new GenericEntity<UpdateNetworkError>(eresp) {};
513 private String getResponse() {
514 if (response != null) {
515 return sendxml ? response.toXmlString() : response.toJsonString();
517 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
522 LOGGER.debug("UpdateNetworkTask start");
524 Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>();
525 Holder<NetworkRollback> rollback = new Holder<NetworkRollback> ();
527 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
528 subnetIdMap.value = testMap();
529 NetworkRollback rb = new NetworkRollback ();
530 rb.setCloudId(req.getCloudSiteId());
531 rb.setTenantId(req.getTenantId());
532 rb.setMsoRequest(req.getMsoRequest());
534 } else if (req.isContrailRequest()) {
535 ContrailNetwork ctn = req.getContrailNetwork();
537 ctn = new ContrailNetwork();
538 req.setContrailNetwork(ctn);
540 adapter.updateNetworkContrail(
541 req.getCloudSiteId(),
543 req.getNetworkType(),
544 req.getModelCustomizationUuid(),
545 req.getNetworkStackId(),
546 req.getNetworkName(),
547 req.getContrailNetwork().getRouteTargets(),
548 req.getContrailNetwork().getShared(),
549 req.getContrailNetwork().getExternal(),
551 req.getContrailNetwork().getPolicyFqdns(),
552 req.getContrailNetwork().getRouteTableFqdns(),
557 ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
559 pvn = new ProviderVlanNetwork();
560 req.setProviderVlanNetwork(pvn);
562 adapter.updateNetwork(
563 req.getCloudSiteId(),
565 req.getNetworkType(),
566 req.getModelCustomizationUuid(),
567 req.getNetworkStackId(),
568 req.getNetworkName(),
569 req.getProviderVlanNetwork().getPhysicalNetworkName(),
570 req.getProviderVlanNetwork().getVlans(),
576 response = new UpdateNetworkResponse(
578 null, // NeutronNetworkId is not available from an update
581 } catch (NetworkException e) {
582 eresp = new UpdateNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
584 if (!req.isSynchronous()) {
585 // This is asynch, so POST response back to caller
586 BpelRestClient bpelClient = new BpelRestClient();
587 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
589 LOGGER.debug("UpdateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
593 public static Map<String, String> testMap() {
594 Map<String, String> m = new HashMap<String, String>();
595 m.put("mickey", "7");
596 m.put("clyde", "10");
597 m.put("wayne", "99");