Removed MsoLogger class
[so.git] / adapters / mso-openstack-adapters / src / main / java / org / onap / so / adapters / network / NetworkAdapterRest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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  * Modifications Copyright (c) 2019 Samsung
9  * ================================================================================
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  * 
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  * 
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.so.adapters.network;
25
26
27 import io.swagger.annotations.Api;
28 import io.swagger.annotations.ApiOperation;
29 import io.swagger.annotations.ApiParam;
30 import io.swagger.annotations.ApiResponse;
31 import io.swagger.annotations.ApiResponses;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35 import javax.inject.Provider;
36 import javax.ws.rs.Consumes;
37 import javax.ws.rs.DELETE;
38 import javax.ws.rs.GET;
39 import javax.ws.rs.POST;
40 import javax.ws.rs.PUT;
41 import javax.ws.rs.Path;
42 import javax.ws.rs.PathParam;
43 import javax.ws.rs.Produces;
44 import javax.ws.rs.QueryParam;
45 import javax.ws.rs.core.GenericEntity;
46 import javax.ws.rs.core.MediaType;
47 import javax.ws.rs.core.Response;
48 import javax.xml.ws.Holder;
49 import org.apache.http.HttpStatus;
50 import org.onap.so.adapters.network.exceptions.NetworkException;
51 import org.onap.so.adapters.nwrest.ContrailNetwork;
52 import org.onap.so.adapters.nwrest.CreateNetworkError;
53 import org.onap.so.adapters.nwrest.CreateNetworkRequest;
54 import org.onap.so.adapters.nwrest.CreateNetworkResponse;
55 import org.onap.so.adapters.nwrest.DeleteNetworkError;
56 import org.onap.so.adapters.nwrest.DeleteNetworkRequest;
57 import org.onap.so.adapters.nwrest.DeleteNetworkResponse;
58 import org.onap.so.adapters.nwrest.ProviderVlanNetwork;
59 import org.onap.so.adapters.nwrest.QueryNetworkError;
60 import org.onap.so.adapters.nwrest.QueryNetworkResponse;
61 import org.onap.so.adapters.nwrest.RollbackNetworkError;
62 import org.onap.so.adapters.nwrest.RollbackNetworkRequest;
63 import org.onap.so.adapters.nwrest.RollbackNetworkResponse;
64 import org.onap.so.adapters.nwrest.UpdateNetworkError;
65 import org.onap.so.adapters.nwrest.UpdateNetworkRequest;
66 import org.onap.so.adapters.nwrest.UpdateNetworkResponse;
67 import org.onap.so.adapters.vnf.BpelRestClient;
68 import org.onap.so.entity.MsoRequest;
69 import org.onap.so.logger.ErrorCode;
70 import org.onap.so.logger.MessageEnum;
71 import org.onap.so.openstack.beans.NetworkRollback;
72 import org.onap.so.openstack.beans.NetworkStatus;
73 import org.onap.so.openstack.beans.RouteTarget;
74 import org.onap.so.openstack.exceptions.MsoExceptionCategory;
75 import org.slf4j.Logger;
76 import org.slf4j.LoggerFactory;
77 import org.springframework.beans.factory.annotation.Autowired;
78 import org.springframework.stereotype.Component;
79 import org.springframework.transaction.annotation.Transactional;
80
81 @Path("/v1/networks")
82 @Api(value = "/v1/networks", description = "root of network adapters restful web service")
83 @Component
84 @Transactional
85 public class NetworkAdapterRest {
86
87     private static final Logger logger = LoggerFactory.getLogger(NetworkAdapterRest.class);
88         private static final String TESTING_KEYWORD = "___TESTING___";
89         private String EXCEPTION = "Exception:";
90
91         @Autowired
92         private MsoNetworkAdapterImpl adapter;
93         
94         @Autowired
95         private Provider<BpelRestClient> bpelRestClientProvider;
96         
97
98         @POST
99         @Path("")
100         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
101         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
102         @ApiOperation(value = "CreateNetwork", 
103                                         response = Response.class,
104                                         notes = "Creates a new network, CreateNetworkRquest JSON is required")
105         @ApiResponses({
106                 @ApiResponse(code = 200, message = "network has been successfully created"),
107                 @ApiResponse(code = 202, message = "create network request has been accepted (async only)"),
108                 @ApiResponse(code = 500, message = "create network failed, examine entity object for details") })
109         public Response createNetwork(
110                                 @ApiParam(value = "details of network being created", required = true) 
111                                 CreateNetworkRequest req) {
112       logger.debug("createNetwork enter: {}", req.toJsonString());
113                 CreateNetworkTask task = new CreateNetworkTask(req);
114                 if (req.isSynchronous()) {
115                         // This is a synchronous request
116                         task.run();
117                         return Response
118                                 .status(task.getStatusCode())
119                                 .entity(task.getGenericEntityResponse())
120                                 .build();
121                 } else {
122                         // This is an asynchronous request
123                         try {
124                                 Thread t1 = new Thread(task);
125                                 t1.start();
126                         } catch (Exception e) {
127                                 // problem handling create, send generic failure as sync resp to caller
128           logger.error("{} {} Exception while create network ", MessageEnum.RA_CREATE_NETWORK_EXC,
129               ErrorCode.BusinessProcesssError.getValue(), e);
130                                 return Response.serverError().build();
131                         }
132                         // send sync response (ACK) to caller
133         logger.debug("createNetwork exit");
134                         return Response.status(HttpStatus.SC_ACCEPTED).build();
135                 }
136         }
137
138         public class CreateNetworkTask implements Runnable {
139                 private final CreateNetworkRequest req;
140                 private CreateNetworkResponse response = null;
141                 private CreateNetworkError eresp = null;
142                 private boolean sendxml;
143
144                 public CreateNetworkTask(CreateNetworkRequest req) {
145                         this.req = req;
146                         this.sendxml = true; // can be set with a field or header later
147                 }
148                 public int getStatusCode() {
149                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
150                 }
151                 public Object getGenericEntityResponse() {
152                         return (response != null)
153                                 ? new GenericEntity<CreateNetworkResponse>(response) {}
154                                 : new GenericEntity<CreateNetworkError>(eresp) {};
155                 }
156                 private String getResponse() {
157                         if (response != null) {
158                                 return sendxml ? response.toXmlString() : response.toJsonString();
159                         } else {
160                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
161                         }
162                 }
163                 @Override
164                 public void run() {
165         logger.debug("CreateNetworkTask start");
166                         try {
167                                 // Synchronous Web Service Outputs
168                                 Holder<String> networkId = new Holder<>();
169                                 Holder<String> neutronNetworkId = new Holder<>();
170                                 Holder<String> networkFqdn = new Holder<>();
171                                 Holder<Map<String, String>> subnetIdMap = new Holder<>();
172                                 Holder<NetworkRollback> rollback = new Holder<>();
173                                 
174                                 HashMap<String, String> params = (HashMap<String, String>) req.getNetworkParams();
175                                 if (params == null) {
176                                         params = new HashMap<String,String>();
177                                 }
178                                 String shared = null;
179                                 String external = null;
180
181                                 String cloudsite = req.getCloudSiteId();
182                                 if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
183                                         String tenant = req.getTenantId();
184                                         if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
185                                                 throw new NetworkException("testing.");
186                                         }
187                                         networkId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
188                                         neutronNetworkId.value = "55e55884-28fa-11e6-8971-0017f20fe1b8";
189                                         networkFqdn.value = "086f70b6-28fb-11e6-8260-0017f20fe1b8";
190                                         subnetIdMap.value = testMap();
191                                         rollback.value = new NetworkRollback();
192                                 } else if (req.isContrailRequest()) {
193                                         ContrailNetwork ctn = req.getContrailNetwork();
194                                         if (ctn == null) {
195                                                 ctn = new ContrailNetwork();
196                                                 req.setContrailNetwork(ctn);
197                                         }
198                                         if (params.containsKey("shared")) {
199                                                 shared = params.get("shared");
200                                         } else {
201                                                 if (ctn.getShared() != null) {
202                                                         shared = ctn.getShared();
203                                                 }
204                                         }
205                                         if (params.containsKey("external")) {
206                                                 external = params.get("external");
207                                         } else {
208                                                 if (ctn.getExternal() != null) {
209                                                         external = ctn.getExternal();
210                                                 }
211                                         }
212                                         adapter.createNetworkContrail(
213                                                 req.getCloudSiteId(),
214                                                 req.getTenantId(),
215                                                 req.getNetworkType(),
216                                                 req.getModelCustomizationUuid(),
217                                                 req.getNetworkName(),
218                         req.getContrailNetwork().getRouteTargets(),
219                         shared,
220                         external,
221                         req.getFailIfExists(),
222                         req.getBackout(),
223                         req.getSubnets(),
224                         params,
225                         req.getContrailNetwork().getPolicyFqdns(),
226                         req.getContrailNetwork().getRouteTableFqdns(),
227                                 req.getMsoRequest(),
228                                         networkId,
229                                                 neutronNetworkId,
230                                                 networkFqdn,
231                                                 subnetIdMap,
232                                                 rollback);
233                                 } else {
234                                         ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
235                                         if (pvn == null) {
236                                                 pvn = new ProviderVlanNetwork();
237                                                 req.setProviderVlanNetwork(pvn);
238                                         }
239                                         if (params.containsKey("shared"))
240                                                 shared = params.get("shared");
241                                         if (params.containsKey("external"))
242                                                 external = params.get("external");
243                                         adapter.createNetwork(
244                                                 req.getCloudSiteId(),
245                                                 req.getTenantId(),
246                                                 req.getNetworkType(),
247                                                 req.getModelCustomizationUuid(),
248                                                 req.getNetworkName(),
249                                                 req.getProviderVlanNetwork().getPhysicalNetworkName(),
250                                                 req.getProviderVlanNetwork().getVlans(),
251                                                 shared,
252                                                 external,
253                         req.getFailIfExists(),
254                         req.getBackout(),
255                         req.getSubnets(),
256                         params,
257                         req.getMsoRequest(),
258                                         networkId,
259                                         neutronNetworkId,
260                                         subnetIdMap,
261                                         rollback);
262                                 }
263                                 response = new CreateNetworkResponse(
264                                                 req.getNetworkId(),
265                                                 neutronNetworkId.value,
266                                                 rollback.value.getNetworkStackId(),
267                                                 networkFqdn.value,
268                                                 rollback.value.getNetworkCreated(),
269                                                 subnetIdMap.value,
270                                                 rollback.value,
271                                                 req.getMessageId());
272                         } catch (NetworkException e) {
273           logger.debug(EXCEPTION, e);
274                                 eresp = new CreateNetworkError(
275                                         e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
276                         }
277                         if (!req.isSynchronous()) {
278                                 // This is asynch, so POST response back to caller
279                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
280                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
281                         }
282         logger.debug("CreateNetworkTask exit: code={}, resp={}", getStatusCode(), getResponse());
283                 }
284         }
285
286         @DELETE
287         @Path("{aaiNetworkId}")
288         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
289         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
290         @ApiOperation(value = "DeleteNetwork", 
291                                         response = Response.class,
292                                         notes = "Deletes an existing network, aaiNetworkId and DeleteNetworkRequest JSON are required")
293         @ApiResponses({
294                                 @ApiResponse(code = 200, message = "network has been successfully deleted"),
295                                 @ApiResponse(code = 202, message = "request to delete network has been accepted (async only)"),
296                                 @ApiResponse(code = 500, message = "delete network failed, examine entity object for details") })       
297         public Response deleteNetwork(
298                 @ApiParam(value = "aaiNetworkId to be deleted ", required = true) 
299                 @PathParam("aaiNetworkId") String aaiNetworkId,
300                 @ApiParam(value = "details of network being deleted", required = true) 
301                 DeleteNetworkRequest req)
302         {
303       logger.debug("deleteNetwork enter: {}", req.toJsonString());
304                 if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
305                         return Response
306                                 .status(HttpStatus.SC_BAD_REQUEST)
307                                 .type(MediaType.TEXT_PLAIN)
308                                 .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
309                                 .build();
310                 }
311                 DeleteNetworkTask task = new DeleteNetworkTask(req);
312                 if (req.isSynchronous()) {
313                         // This is a synchronous request
314                         task.run();
315                         return Response
316                                 .status(task.getStatusCode())
317                                 .entity(task.getGenericEntityResponse())
318                                 .build();
319                 } else {
320                         // This is an asynchronous request
321                         try {
322                                 Thread t1 = new Thread(task);
323                                 t1.start();
324                         } catch (Exception e) {
325                                 // problem handling create, send generic failure as sync resp to caller
326           logger.error("{} {} Exception while delete network ", MessageEnum.RA_DELETE_NETWORK_EXC,
327               ErrorCode.BusinessProcesssError.getValue(), e);
328                                 return Response.serverError().build();
329                         }
330                         // send sync response (ACK) to caller
331         logger.debug("deleteNetwork exit");
332                         return Response.status(HttpStatus.SC_ACCEPTED).build();
333                 }
334         }
335
336         public class DeleteNetworkTask implements Runnable {
337                 private final DeleteNetworkRequest req;
338                 private DeleteNetworkResponse response = null;
339                 private DeleteNetworkError eresp = null;
340                 private boolean sendxml;
341
342                 public DeleteNetworkTask(DeleteNetworkRequest req) {
343                         this.req = req;
344                         this.sendxml = true; // can be set with a field or header later
345                 }
346                 public int getStatusCode() {
347                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
348                 }
349                 public Object getGenericEntityResponse() {
350                         return (response != null)
351                                 ? new GenericEntity<DeleteNetworkResponse>(response) {}
352                                 : new GenericEntity<DeleteNetworkError>(eresp) {};
353                 }
354                 private String getResponse() {
355                         if (response != null) {
356                                 return sendxml ? response.toXmlString() : response.toJsonString();
357                         } else {
358                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
359                         }
360                 }
361                 @Override
362                 public void run() {
363         logger.debug("DeleteNetworkTask start");
364                         try {
365                                 Holder<Boolean> networkDeleted = new Holder<>();
366                                 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
367                                         networkDeleted.value = true;
368                                 } else {
369                                         adapter.deleteNetwork(
370                                                 req.getCloudSiteId(),
371                                                 req.getTenantId(),
372                                                 req.getNetworkType(),
373                                                 req.getModelCustomizationUuid(),
374                                                 req.getNetworkStackId(),
375                                                 req.getMsoRequest(),
376                                                 networkDeleted);
377                                 }
378                                 response = new DeleteNetworkResponse(req.getNetworkId(), networkDeleted.value, req.getMessageId());
379                         } catch (NetworkException e) {
380           logger.debug(EXCEPTION, e);
381                                 eresp = new DeleteNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
382                         }
383                         if (!req.isSynchronous()) {
384                                 // This is asynch, so POST response back to caller
385                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
386                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
387                         }
388         logger.debug("DeleteNetworkTask exit: code={}, resp={}", getStatusCode(), getResponse());
389                 }
390         }
391
392         @GET
393         @Path("{aaiNetworkId}")
394         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
395         @ApiOperation(value = "QueryNetwork", 
396                         response = Response.class,
397                         notes = "Queries an existing network")
398         @ApiResponses({
399                         @ApiResponse(code = 200, message = "Query network successful"),
400                         @ApiResponse(code = 500, message = "Query network failed, examine entity object for details") })                
401         public Response queryNetwork(
402                 @ApiParam(value = "cloudSiteId", required = false)
403                 @QueryParam("cloudSiteId") String cloudSiteId,
404                 @ApiParam(value = "tenantId", required = false)
405                 @QueryParam("tenantId") String tenantId,
406                 @ApiParam(value = "networkStackId", required = false)
407                 @QueryParam("networkStackId") String networkStackId,
408                 @ApiParam(value = "skipAAI", required = false)
409                 @QueryParam("skipAAI") String skipAAI,
410                 @ApiParam(value = "msoRequest.requestId", required = false)
411                 @QueryParam("msoRequest.requestId") String requestId,
412                 @ApiParam(value = "msoRequest.serviceInstanceId", required = false)
413                 @QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId,
414                 @ApiParam(value = "aaiNetworkId", required = false)
415                 @PathParam("aaiNetworkId") String aaiNetworkId)
416         {
417                 //This request responds synchronously only
418       logger.debug("Query network enter:{}" + aaiNetworkId);
419                 MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
420
421                 try {
422                         int respStatus = HttpStatus.SC_OK;
423                         QueryNetworkResponse resp = new QueryNetworkResponse(networkStackId, null, networkStackId, null, null);
424                         Holder<Boolean> networkExists = new Holder<>();
425             Holder<String> networkId = new Holder<>();
426             Holder<String> neutronNetworkId = new Holder<>();
427             Holder<NetworkStatus> status = new Holder<>();
428             Holder<List<RouteTarget>> routeTargets = new Holder<>();
429             Holder<Map<String, String>> subnetIdMap = new Holder<>();
430
431                         adapter.queryNetworkContrail(cloudSiteId,  tenantId, aaiNetworkId,  msoRequest,
432                                 networkExists, networkId, neutronNetworkId, status, routeTargets, subnetIdMap);
433
434                         if (!networkExists.value) {
435           logger.debug("network not found");
436                                 respStatus = HttpStatus.SC_NOT_FOUND;
437                         } else {
438           logger.debug("network found {}, status={}", networkId.value, status.value);
439                                 resp.setNetworkExists(networkExists.value);
440                                 resp.setNetworkId(networkId.value);
441                                 resp.setNeutronNetworkId(neutronNetworkId.value);
442                                 resp.setNetworkStatus(status.value);
443                                 resp.setRouteTargets(routeTargets.value);
444                                 resp.setSubnetIdMap(subnetIdMap.value);
445                         }
446         logger.debug("Query network exit");
447                         return Response
448                                 .status(respStatus)
449                                 .entity(new GenericEntity<QueryNetworkResponse>(resp) {})
450                                 .build();
451                 } catch (NetworkException e) {
452         logger.error("{} {} Exception when query VNF ", MessageEnum.RA_QUERY_VNF_ERR,
453             ErrorCode.BusinessProcesssError.getValue(), e);
454                         QueryNetworkError err = new QueryNetworkError();
455                         err.setMessage(e.getMessage());
456                         err.setCategory(MsoExceptionCategory.INTERNAL);
457                         return Response
458                                 .status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
459                                 .entity(new GenericEntity<QueryNetworkError>(err) {})
460                                 .build();
461                 }
462         }
463
464         @DELETE
465         @Path("{aaiNetworkId}/rollback")
466         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
467         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
468         @ApiOperation(value = "RollbackNetwork", 
469                 response = Response.class,
470                 notes = "Rollback an existing network")
471         @ApiResponses({
472                         @ApiResponse(code = 200, message = "Rollback network successful"),
473                         @ApiResponse(code = 202, message = "Rollback network request has been accepted (async only)"),
474                         @ApiResponse(code = 500, message = "Rollback network failed, examine entity object for details") })
475         public Response rollbackNetwork(
476                 @ApiParam(value = "RollbackNetworkRequest in JSON format", required = true)
477                 RollbackNetworkRequest req)
478         {
479       logger.debug("rollbackNetwork enter: {}", req.toJsonString());
480                 RollbackNetworkTask task = new RollbackNetworkTask(req);
481                 if (req.isSynchronous()) {
482                         // This is a synchronous request
483                         task.run();
484                         return Response
485                                 .status(task.getStatusCode())
486                                 .entity(task.getGenericEntityResponse())
487                                 .build();
488                 } else {
489                         // This is an asynchronous request
490                         try {
491                                 Thread t1 = new Thread(task);
492                                 t1.start();
493                         } catch (Exception e) {
494                                 // problem handling create, send generic failure as sync resp to caller
495           logger.error("{} {} Exception in rollbackNetwork ", MessageEnum.RA_ROLLBACK_NULL,
496               ErrorCode.BusinessProcesssError.getValue(), e);
497                                 return Response.serverError().build();
498                         }
499                         // send sync response (ACK) to caller
500         logger.debug("rollbackNetwork exit");
501                         return Response.status(HttpStatus.SC_ACCEPTED).build();
502                 }
503         }
504
505         public class RollbackNetworkTask implements Runnable {
506                 private final RollbackNetworkRequest req;
507                 private RollbackNetworkResponse response = null;
508                 private RollbackNetworkError eresp = null;
509                 private boolean sendxml;
510
511                 public RollbackNetworkTask(RollbackNetworkRequest req) {
512                         this.req = req;
513                         this.sendxml = true; // can be set with a field or header later
514                 }
515                 public int getStatusCode() {
516                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
517                 }
518                 public Object getGenericEntityResponse() {
519                         return (response != null)
520                                 ? new GenericEntity<RollbackNetworkResponse>(response) {}
521                                 : new GenericEntity<RollbackNetworkError>(eresp) {};
522                 }
523                 private String getResponse() {
524                         if (response != null) {
525                                 return sendxml ? response.toXmlString() : response.toJsonString();
526                         } else {
527                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
528                         }
529                 }
530                 @Override
531                 public void run() {
532         logger.debug("RollbackNetworkTask start");
533                         try {
534                                 NetworkRollback nwr = req.getNetworkRollback();
535                                 adapter.rollbackNetwork(nwr);
536                                 response = new RollbackNetworkResponse(true, req.getMessageId());
537                         } catch (NetworkException e) {
538           logger.debug(EXCEPTION, e);
539                                 eresp = new RollbackNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
540                         }
541                         if (!req.isSynchronous()) {
542                                 // This is asynch, so POST response back to caller
543                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
544                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
545                         }
546         logger.debug("RollbackNetworkTask exit: code={}, resp={}", getStatusCode(), getResponse());
547                 }
548         }
549
550         @PUT
551         @Path("{aaiNetworkId}")
552         @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
553         @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
554         @ApiOperation(value = "UpdateNetwork", 
555                 response = Response.class,
556                 notes = "Update an existing network")
557         @ApiResponses({
558                 @ApiResponse(code = 200, message = "Update network successful"),
559                 @ApiResponse(code = 202, message = "Update network request has been accepted (async only)"),
560                 @ApiResponse(code = 500, message = "Update network failed, examine entity object for details") })       
561         public Response updateNetwork(
562                 @ApiParam(value = "aaiNetworkId", required = true)
563                 @PathParam("aaiNetworkId") String aaiNetworkId,
564                 @ApiParam(value = "UpdateNetworkRequest in JSON format", required = true)
565                 UpdateNetworkRequest req)
566         {
567       logger.debug("updateNetwork enter: {}", req.toJsonString());
568                 if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
569                         return Response
570                                 .status(HttpStatus.SC_BAD_REQUEST)
571                                 .type(MediaType.TEXT_PLAIN)
572                                 .entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
573                                 .build();
574                 }
575                 UpdateNetworkTask task = new UpdateNetworkTask(req);
576                 if (req.isSynchronous()) {
577                         // This is a synchronous request
578                         task.run();
579                         return Response
580                                 .status(task.getStatusCode())
581                                 .entity(task.getGenericEntityResponse())
582                                 .build();
583                 } else {
584                         // This is an asynchronous request
585                 try {
586                         Thread t1 = new Thread(task);
587                         t1.start();
588                 } catch (Exception e) {
589                         // problem handling create, send generic failure as sync resp to caller
590             logger.error("{} {} Exception in updateNetwork ", MessageEnum.RA_UPDATE_NETWORK_ERR,
591                 ErrorCode.BusinessProcesssError.getValue(), e);
592                         return Response.serverError().build();
593                 }
594                 // send sync response (ACK) to caller
595         logger.debug("updateNetwork exit");
596                 return Response.status(HttpStatus.SC_ACCEPTED).build();
597                 }
598         }
599
600         public class UpdateNetworkTask implements Runnable {
601                 private final UpdateNetworkRequest req;
602                 private UpdateNetworkResponse response = null;
603                 private UpdateNetworkError eresp = null;
604                 private boolean sendxml;
605
606                 public UpdateNetworkTask(UpdateNetworkRequest req) {
607                         this.req = req;
608                         this.sendxml = true; // can be set with a field or header later
609                 }
610                 public int getStatusCode() {
611                         return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
612                 }
613                 public Object getGenericEntityResponse() {
614                         return (response != null)
615                                 ? new GenericEntity<UpdateNetworkResponse>(response) {}
616                                 : new GenericEntity<UpdateNetworkError>(eresp) {};
617                 }
618                 private String getResponse() {
619                         if (response != null) {
620                                 return sendxml ? response.toXmlString() : response.toJsonString();
621                         } else {
622                                 return sendxml ? eresp.toXmlString() : eresp.toJsonString();
623                         }
624                 }
625                 @Override
626                 public void run() {
627         logger.debug("UpdateNetworkTask start");
628                         try {
629                                 Holder<Map<String, String>> subnetIdMap = new Holder<>();
630                                 Holder<NetworkRollback> rollback = new Holder<> ();
631                                 HashMap<String, String> params = (HashMap<String, String>) req.getNetworkParams();
632                                 if (params == null) {
633                                         params = new HashMap<String,String>();
634                                 }
635                                 String shared = null;
636                                 String external = null;
637
638                                 if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
639                                         subnetIdMap.value = testMap();
640                                 NetworkRollback rb = new NetworkRollback ();
641                                 rb.setCloudId(req.getCloudSiteId());
642                                 rb.setTenantId(req.getTenantId());
643                                 rb.setMsoRequest(req.getMsoRequest());
644                                 rollback.value = rb;
645                                 } else if (req.isContrailRequest()) {
646                                         ContrailNetwork ctn = req.getContrailNetwork();
647                                         if (ctn == null) {
648                                                 ctn = new ContrailNetwork();
649                                                 req.setContrailNetwork(ctn);
650                                         }
651                                         if (params.containsKey("shared")) {
652                                                 shared = params.get("shared");
653                                         } else {
654                                                 if (ctn.getShared() != null) {
655                                                         shared = ctn.getShared();
656                                                 }
657                                         }
658                                         if (params.containsKey("external")) {
659                                                 external = params.get("external");
660                                         } else {
661                                                 if (ctn.getExternal() != null) {
662                                                         external = ctn.getExternal();
663                                                 }
664                                         }
665                                         adapter.updateNetworkContrail(
666                                                 req.getCloudSiteId(),
667                                                 req.getTenantId(),
668                                                 req.getNetworkType(),
669                                                 req.getModelCustomizationUuid(),
670                                                 req.getNetworkStackId(),
671                                                 req.getNetworkName(),
672                                                 req.getContrailNetwork().getRouteTargets(),
673                                                 shared,
674                                                 external,
675                             req.getSubnets(),
676                             params,
677                             req.getContrailNetwork().getPolicyFqdns(),
678                             req.getContrailNetwork().getRouteTableFqdns(),
679                             req.getMsoRequest(),
680                             subnetIdMap,
681                             rollback);
682                                 } else {
683                                         ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
684                                         if (pvn == null) {
685                                                 pvn = new ProviderVlanNetwork();
686                                                 req.setProviderVlanNetwork(pvn);
687                                         }
688                                         if (params.containsKey("shared")) {
689                                                 shared = params.get("shared");
690                                         } 
691                                         if (params.containsKey("external")) {
692                                                 external = params.get("external");
693                                         } 
694                                         adapter.updateNetwork(
695                                                 req.getCloudSiteId(),
696                                                 req.getTenantId(),
697                                                 req.getNetworkType(),
698                                                 req.getModelCustomizationUuid(),
699                                                 req.getNetworkStackId(),
700                                                 req.getNetworkName(),
701                                                 req.getProviderVlanNetwork().getPhysicalNetworkName(),
702                                                 req.getProviderVlanNetwork().getVlans(),
703                                                 shared,
704                                                 external,
705                                                 req.getSubnets(),
706                                                 params,
707                                                 req.getMsoRequest(),
708                                                 subnetIdMap,
709                                                 rollback);
710                                 }
711                                 response = new UpdateNetworkResponse(
712                                         req.getNetworkId(),
713                                         null,   // NeutronNetworkId is not available from an update
714                                         subnetIdMap.value,
715                                         req.getMessageId());
716                         } catch (NetworkException e) {
717           logger.debug(EXCEPTION, e);
718                                 eresp = new UpdateNetworkError(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
719                         }
720                         if (!req.isSynchronous()) {
721                                 // This is asynch, so POST response back to caller
722                                 BpelRestClient bpelClient = bpelRestClientProvider.get();
723                                 bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
724                         }
725         logger.debug("UpdateNetworkTask exit: code={}, resp={}", getStatusCode(), getResponse());
726                 }
727         }
728
729         public static Map<String, String> testMap() {
730                 Map<String, String> m = new HashMap<>();
731                 m.put("mickey", "7");
732                 m.put("clyde", "10");
733                 m.put("wayne", "99");
734                 return m;
735     }
736 }