f917aed39ebb125261bf1ee40e712c93d398e109
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / client / adapter / network / mapper / NetworkAdapterObjectMapper.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.onap.so.client.adapter.network.mapper;
22
23 import java.io.UnsupportedEncodingException;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Optional;
29 import java.util.UUID;
30
31 import org.apache.commons.lang3.StringUtils;
32 import org.modelmapper.ModelMapper;
33 import org.modelmapper.PropertyMap;
34 import org.onap.so.adapters.nwrest.ContrailNetwork;
35 import org.onap.so.adapters.nwrest.CreateNetworkRequest;
36 import org.onap.so.adapters.nwrest.CreateNetworkResponse;
37 import org.onap.so.adapters.nwrest.DeleteNetworkRequest;
38 import org.onap.so.adapters.nwrest.NetworkTechnology;
39 import org.onap.so.adapters.nwrest.ProviderVlanNetwork;
40 import org.onap.so.adapters.nwrest.RollbackNetworkRequest;
41 import org.onap.so.adapters.nwrest.UpdateNetworkRequest;
42 import org.onap.so.bpmn.core.UrnPropertiesReader;
43 import org.onap.so.bpmn.servicedecomposition.bbobjects.CloudRegion;
44 import org.onap.so.bpmn.servicedecomposition.bbobjects.Customer;
45 import org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network;
46 import org.onap.so.bpmn.servicedecomposition.bbobjects.NetworkPolicy;
47 import org.onap.so.bpmn.servicedecomposition.bbobjects.RouteTableReference;
48 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
49 import org.onap.so.bpmn.servicedecomposition.bbobjects.VpnBinding;
50 import org.onap.so.bpmn.servicedecomposition.generalobjects.OrchestrationContext;
51 import org.onap.so.bpmn.servicedecomposition.generalobjects.RequestContext;
52 import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoNetwork;
53 import org.onap.so.entity.MsoRequest;
54 import org.onap.so.logger.MsoLogger;
55 import org.onap.so.openstack.beans.NetworkRollback;
56 import org.onap.so.openstack.beans.RouteTarget;
57 import org.onap.so.openstack.beans.Subnet;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60 import org.springframework.stereotype.Component;
61 import org.springframework.web.util.UriUtils;
62
63 @Component
64 public class NetworkAdapterObjectMapper {
65         private static final ModelMapper modelMapper = new ModelMapper();
66         private static String FORWARD_SLASH = "/";
67         private static final Logger logger = LoggerFactory.getLogger(NetworkAdapterObjectMapper.class);
68
69         public CreateNetworkRequest createNetworkRequestMapper(RequestContext requestContext, CloudRegion cloudRegion, OrchestrationContext orchestrationContext, ServiceInstance serviceInstance, L3Network l3Network, Map<String, String> userInput, String cloudRegionPo, Customer customer) throws UnsupportedEncodingException {
70                 CreateNetworkRequest createNetworkRequest = new CreateNetworkRequest();
71                 
72                 //set cloudSiteId as determined for cloud region PO instead of cloudRegion.getLcpCloudRegionId()
73                 createNetworkRequest.setCloudSiteId(cloudRegionPo);
74                 createNetworkRequest.setTenantId(cloudRegion.getTenantId());
75                 createNetworkRequest.setNetworkId(l3Network.getNetworkId());
76                 createNetworkRequest.setNetworkName(l3Network.getNetworkName());
77                 //TODO fields not available
78                 createNetworkRequest.setNetworkType(l3Network.getNetworkType());
79                 //createNetworkRequest.setNetworkTypeVersion(serviceInstance.getModelInfoServiceInstance().getModelVersion());
80                 ModelInfoNetwork modelInfoNetwork  = l3Network.getModelInfoNetwork();
81                 if (modelInfoNetwork != null){
82                         createNetworkRequest.setModelCustomizationUuid(modelInfoNetwork.getModelCustomizationUUID());
83                 }
84
85                 //build and set Subnet list
86                 createNetworkRequest.setSubnets(buildOpenstackSubnetList(l3Network));
87                 
88                 //build and set provider Vlan Network
89                 ProviderVlanNetwork providerVlanNetwork = buildProviderVlanNetwork(l3Network);
90                 createNetworkRequest.setProviderVlanNetwork(providerVlanNetwork);
91                 String networkTechnology = l3Network.getModelInfoNetwork().getNetworkTechnology();
92                 if(networkTechnology == null) {
93                         networkTechnology = l3Network.getNetworkTechnology();
94                         logger.warn("NetworkTechnology was null in CatalogDB. Using field from AAI: " + networkTechnology);
95                 }
96                 if (networkTechnology != null) {
97                         createNetworkRequest.setNetworkTechnology(networkTechnology.toUpperCase());
98                         if (createNetworkRequest.getNetworkTechnology().contains("CONTRAIL")) {
99                                 createNetworkRequest.setContrailRequest(true);
100                         }
101                 }
102                 
103                 //build and set Contrail Network
104                 ContrailNetwork contrailNetwork = buildContrailNetwork(l3Network, customer);
105                 createNetworkRequest.setContrailNetwork(contrailNetwork);
106                 
107                 //set Network Parameters from VID request, add "shared" and "external" to this map
108                 createNetworkRequest.setNetworkParams(addSharedAndExternal(userInput, l3Network));
109                 
110                 createNetworkRequest = setFlowFlags(createNetworkRequest, orchestrationContext);
111
112                 createNetworkRequest.setMsoRequest(createMsoRequest(requestContext, serviceInstance));
113                 
114                 String messageId = getRandomUuid();
115                 createNetworkRequest.setMessageId(messageId);
116                 createNetworkRequest.setNotificationUrl(createCallbackUrl("NetworkAResponse", messageId));
117
118                 return createNetworkRequest;
119         }
120
121         public DeleteNetworkRequest deleteNetworkRequestMapper(RequestContext requestContext, CloudRegion cloudRegion, ServiceInstance serviceInstance, L3Network l3Network) throws UnsupportedEncodingException {
122                 DeleteNetworkRequest deleteNetworkRequest = new DeleteNetworkRequest();
123                 
124                 deleteNetworkRequest.setCloudSiteId(cloudRegion.getLcpCloudRegionId());
125                 
126                 String messageId = getRandomUuid();
127                 deleteNetworkRequest.setMessageId(messageId);
128                 
129                 ModelInfoNetwork modelInfoNetwork  = l3Network.getModelInfoNetwork();
130                 if (modelInfoNetwork != null){
131                         deleteNetworkRequest.setModelCustomizationUuid(modelInfoNetwork.getModelCustomizationUUID());
132                 }
133                 
134                 deleteNetworkRequest.setMsoRequest(createMsoRequest(requestContext, serviceInstance));
135                 deleteNetworkRequest.setNetworkId(l3Network.getNetworkId());
136                 if (!StringUtils.isEmpty(l3Network.getHeatStackId())){
137                         deleteNetworkRequest.setNetworkStackId(l3Network.getHeatStackId());
138                 }
139                 else {
140                         deleteNetworkRequest.setNetworkStackId(l3Network.getNetworkName());
141                 }
142                 deleteNetworkRequest.setNetworkType(l3Network.getNetworkType());
143                 deleteNetworkRequest.setSkipAAI(true);
144                 deleteNetworkRequest.setTenantId(cloudRegion.getTenantId());
145                 
146                 deleteNetworkRequest.setNotificationUrl(createCallbackUrl("NetworkAResponse", messageId));
147                 
148                 return deleteNetworkRequest;
149         }
150         
151         /**
152          * Access method to build Rollback Network Request
153          * @return
154          * @throws UnsupportedEncodingException
155          */
156         public RollbackNetworkRequest createNetworkRollbackRequestMapper(RequestContext requestContext, CloudRegion cloudRegion, OrchestrationContext orchestrationContext, ServiceInstance serviceInstance, L3Network l3Network, Map<String, String> userInput, String cloudRegionPo, CreateNetworkResponse createNetworkResponse) throws UnsupportedEncodingException {
157                 RollbackNetworkRequest rollbackNetworkRequest = new RollbackNetworkRequest();
158                 
159                 rollbackNetworkRequest = setCommonRollbackRequestFields(rollbackNetworkRequest, requestContext);
160                 
161                 NetworkRollback networkRollback = buildNetworkRollback(l3Network, cloudRegion, cloudRegionPo, createNetworkResponse);
162                 rollbackNetworkRequest.setNetworkRollback(networkRollback);
163                 
164                 return rollbackNetworkRequest;
165         }
166         
167         public UpdateNetworkRequest createNetworkUpdateRequestMapper(RequestContext requestContext, CloudRegion cloudRegion, OrchestrationContext orchestrationContext, ServiceInstance serviceInstance, L3Network l3Network, Map<String, String> userInput, Customer customer) throws UnsupportedEncodingException {
168                 UpdateNetworkRequest updateNetworkRequest = new UpdateNetworkRequest();
169                 
170                 updateNetworkRequest.setCloudSiteId(cloudRegion.getLcpCloudRegionId());
171                 updateNetworkRequest.setTenantId(cloudRegion.getTenantId());
172                 updateNetworkRequest.setNetworkId(l3Network.getNetworkId());
173                 updateNetworkRequest.setNetworkStackId(l3Network.getHeatStackId());
174                 updateNetworkRequest.setNetworkName(l3Network.getNetworkName());
175                 updateNetworkRequest.setNetworkType(l3Network.getModelInfoNetwork().getNetworkType());
176                 updateNetworkRequest.setNetworkTypeVersion(l3Network.getModelInfoNetwork().getModelVersion());
177                 updateNetworkRequest.setModelCustomizationUuid(l3Network.getModelInfoNetwork().getModelCustomizationUUID());
178                 updateNetworkRequest.setSubnets(buildOpenstackSubnetList(l3Network));
179                 updateNetworkRequest.setProviderVlanNetwork(buildProviderVlanNetwork(l3Network));
180                 updateNetworkRequest.setContrailNetwork(buildContrailNetwork(l3Network, customer));
181                 updateNetworkRequest.setNetworkParams(addSharedAndExternal(userInput, l3Network));
182                 updateNetworkRequest.setMsoRequest(createMsoRequest(requestContext, serviceInstance));
183                 
184                 setFlowFlags(updateNetworkRequest, orchestrationContext);
185                 
186                 String messageId = getRandomUuid();
187                 updateNetworkRequest.setMessageId(messageId);
188                 updateNetworkRequest.setNotificationUrl(createCallbackUrl("NetworkAResponse", messageId));
189                 
190                 return updateNetworkRequest;
191         }
192         
193         private RollbackNetworkRequest setCommonRollbackRequestFields(RollbackNetworkRequest request,RequestContext requestContext) throws UnsupportedEncodingException{
194                 request.setSkipAAI(true);
195                 String messageId = requestContext.getMsoRequestId();
196                 request.setMessageId(messageId);
197                 //request.setNotificationUrl(createCallbackUrl("NetworkAResponse", messageId));
198                 return request;
199         }
200         
201         private NetworkRollback buildNetworkRollback(L3Network l3Network, CloudRegion cloudRegion, String cloudRegionPo, CreateNetworkResponse createNetworkResponse){
202                 NetworkRollback networkRollback = new NetworkRollback();
203                 networkRollback.setNetworkId(l3Network.getNetworkId());
204                 networkRollback.setNeutronNetworkId(createNetworkResponse.getMessageId());
205                 networkRollback.setNetworkStackId(createNetworkResponse.getNetworkStackId());
206                 networkRollback.setTenantId(cloudRegion.getTenantId());
207                 networkRollback.setCloudId(cloudRegionPo);
208                 networkRollback.setNetworkType(l3Network.getNetworkType());
209                 ModelInfoNetwork modelInfoNetwork  = l3Network.getModelInfoNetwork();
210                 if (modelInfoNetwork != null){
211                         networkRollback.setModelCustomizationUuid(modelInfoNetwork.getModelCustomizationUUID());
212                 }
213                 //rollback will only be called when network was actually created
214                 networkRollback.setNetworkCreated(createNetworkResponse.getNetworkCreated());
215                 //TODO confirm below not required for create rollback
216                 //NetworkName
217                 //PhysicalNetwork
218                 //Vlans
219                 //msoRequest
220                 return networkRollback;
221         }
222         
223         public MsoRequest createMsoRequest(RequestContext requestContext, ServiceInstance serviceInstance) {
224                 MsoRequest msoRequest = new MsoRequest();
225                 msoRequest.setRequestId(requestContext.getMsoRequestId());
226                 msoRequest.setServiceInstanceId(serviceInstance.getServiceInstanceId());
227                 return msoRequest;
228         }
229         
230         protected String getRandomUuid() {
231                 return UUID.randomUUID().toString();
232         }
233         
234         protected String createCallbackUrl(String messageType, String correlator) throws UnsupportedEncodingException {
235                 String endpoint = this.getEndpoint();
236
237                 while (endpoint.endsWith("/")) {
238                         endpoint = endpoint.substring(0, endpoint.length()-1);
239                 }
240                 return endpoint + "/" + UriUtils.encodePathSegment(messageType, "UTF-8") + "/" + UriUtils.encodePathSegment(correlator, "UTF-8");
241         }
242         
243         protected String getEndpoint() {
244                 return UrnPropertiesReader.getVariable("mso.workflow.message.endpoint");
245         }
246         /**
247          * Use BB L3Network object to build subnets list of type org.onap.so.openstack.beans.Subnet
248          * @param L3Network
249          * @return List<org.onap.so.openstack.beans.Subnet>
250          */
251         private List<Subnet> buildOpenstackSubnetList(L3Network l3Network){
252                 
253                 List<org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet> subnets = l3Network.getSubnets();
254                 List<org.onap.so.openstack.beans.Subnet> subnetList = new ArrayList<org.onap.so.openstack.beans.Subnet>();
255                 //create mapper from onap Subnet to openstack bean Subnet
256                 if(modelMapper.getTypeMap(org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet.class, org.onap.so.openstack.beans.Subnet.class) == null) {
257                         PropertyMap<org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet, org.onap.so.openstack.beans.Subnet> personMap = new PropertyMap<org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet, org.onap.so.openstack.beans.Subnet>() {
258                                   protected void configure() {
259                                     map().setSubnetName(source.getSubnetName());
260                                     map(source.getSubnetId(), destination.getSubnetId());
261                                     map(source.getNeutronSubnetId(), destination.getNeutronId());
262                                     map(source.getGatewayAddress(), destination.getGatewayIp());
263                                     map(source.getIpVersion(), destination.getIpVersion());
264                                     map(source.isDhcpEnabled(), destination.getEnableDHCP());
265                                     map(source.getSubnetSequence(), destination.getSubnetSequence());
266                                   }
267                                 };
268                         modelMapper.addMappings(personMap);
269                 }
270                 
271                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet subnet : subnets) {
272                         org.onap.so.openstack.beans.Subnet openstackSubnet = modelMapper.map(subnet, org.onap.so.openstack.beans.Subnet.class);
273                         //update cidr value
274                         if (subnet.getNetworkStartAddress() != null && subnet.getCidrMask() != null)
275                                 openstackSubnet.setCidr(subnet.getNetworkStartAddress().concat(FORWARD_SLASH).concat(subnet.getCidrMask()));
276                         List<org.onap.so.bpmn.servicedecomposition.bbobjects.HostRoute> hostRouteList = subnet.getHostRoutes();
277                         List<org.onap.so.openstack.beans.HostRoute> openstackHostRouteList = new ArrayList<>();
278                         org.onap.so.openstack.beans.HostRoute openstackHostRoute = new org.onap.so.openstack.beans.HostRoute();
279                         //TODO only 2 fields available on openstack object. Confirm it is sufficient or add as needed
280                         for (org.onap.so.bpmn.servicedecomposition.bbobjects.HostRoute hostRoute : hostRouteList) {
281                                 openstackHostRoute.setNextHop(hostRoute.getNextHop());
282                                 openstackHostRoute.setPrefix(hostRoute.getRoutePrefix());
283                                 //add host route to the list
284                                 openstackHostRouteList.add(openstackHostRoute);
285                         }
286                         if (subnet.getDhcpStart() != null && !subnet.getDhcpStart().equals("")) {
287                                 org.onap.so.openstack.beans.Pool openstackAllocationPool = new org.onap.so.openstack.beans.Pool();
288                                 openstackAllocationPool.setStart(subnet.getDhcpStart());
289                                 openstackAllocationPool.setEnd(subnet.getDhcpEnd());
290                                 List<org.onap.so.openstack.beans.Pool> allocationPools = new ArrayList<>();
291                                 allocationPools.add(openstackAllocationPool);
292                                 openstackSubnet.setAllocationPools(allocationPools);
293                         }
294                         openstackSubnet.setHostRoutes(openstackHostRouteList);
295                         //add subnet to the list
296                         subnetList.add(openstackSubnet);
297                 }
298                 return subnetList;
299         }
300         
301         private ProviderVlanNetwork buildProviderVlanNetwork(L3Network l3Network){
302                 ProviderVlanNetwork providerVlanNetwork = new ProviderVlanNetwork();
303                 providerVlanNetwork.setPhysicalNetworkName(l3Network.getPhysicalNetworkName());
304                 List<Integer> vlans = new ArrayList<Integer>();
305                 List<org.onap.so.bpmn.servicedecomposition.bbobjects.SegmentationAssignment> segmentationAssignments = l3Network.getSegmentationAssignments();
306                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.SegmentationAssignment assignment : segmentationAssignments) {
307                         vlans.add(Integer.valueOf(assignment.getSegmentationId()));
308                 }
309                 providerVlanNetwork.setVlans(vlans);
310                 return providerVlanNetwork;
311         }
312
313         private ContrailNetwork buildContrailNetwork(L3Network l3Network, Customer customer){
314                 ContrailNetwork contrailNetwork = new ContrailNetwork();
315                 contrailNetwork.setExternal(Optional.ofNullable(l3Network.isIsExternalNetwork()).orElse(false).toString());
316                 contrailNetwork.setShared(Optional.ofNullable(l3Network.isIsSharedNetwork()).orElse(false).toString());
317                 contrailNetwork.setPolicyFqdns(buildPolicyFqdns(l3Network.getNetworkPolicies()));
318                 contrailNetwork.setRouteTableFqdns(buildRouteTableFqdns(l3Network.getContrailNetworkRouteTableReferences()));
319                 if(customer!= null)
320                         contrailNetwork.setRouteTargets(buildRouteTargets(customer.getVpnBindings()));
321                 //PolicyFqdns(policyFqdns); --- is set in getAAINetworkPolicy
322                 //RouteTableFqdns(routeTableFqdns); --- is set in getAAINetworkTableRef
323                 //RouteTargets(routeTargets); --- is set in getAAINetworkVpnBinding
324                 return contrailNetwork;
325         }
326         
327         private List<String> buildPolicyFqdns(List<NetworkPolicy> networkPolicies) {
328                 List<String> policyFqdns = new ArrayList<>();
329                 for(NetworkPolicy networkPolicy : networkPolicies) {
330                         policyFqdns.add(networkPolicy.getNetworkPolicyFqdn());
331                 }
332                 return policyFqdns;
333         }
334         
335         private List<String> buildRouteTableFqdns(List<RouteTableReference> contrailNetworkRouteTableReferences) {
336                 List<String> routeTableFqdns = new ArrayList<>();
337                 for(RouteTableReference routeTableReference : contrailNetworkRouteTableReferences) {
338                         routeTableFqdns.add(routeTableReference.getRouteTableReferenceFqdn());
339                 }
340                 return routeTableFqdns;
341         }
342
343         private List<RouteTarget> buildRouteTargets(List<VpnBinding> vpnBindings) {
344                 if(modelMapper.getTypeMap(org.onap.so.bpmn.servicedecomposition.bbobjects.RouteTarget.class, RouteTarget.class) == null) {
345                         modelMapper.addMappings(new PropertyMap<org.onap.so.bpmn.servicedecomposition.bbobjects.RouteTarget, RouteTarget>() {
346                                 @Override
347                                 protected void configure() {
348                                         map().setRouteTarget(source.getGlobalRouteTarget());
349                                         map().setRouteTargetRole(source.getRouteTargetRole());
350                                 }
351                         });
352                 }
353                 
354                 List<RouteTarget> routeTargets = new ArrayList<>();
355                 for(VpnBinding vpnBinding : vpnBindings) {
356                         for(org.onap.so.bpmn.servicedecomposition.bbobjects.RouteTarget routeTarget : vpnBinding.getRouteTargets()) {
357                                 routeTargets.add(modelMapper.map(routeTarget, RouteTarget.class));
358                         }
359                 }
360                 return routeTargets;
361         }
362
363         private CreateNetworkRequest setFlowFlags(CreateNetworkRequest createNetworkRequest, OrchestrationContext orchestrationContext){
364                 //TODO confirm flag value
365                 createNetworkRequest.setSkipAAI(true);          
366                 createNetworkRequest.setBackout(Boolean.TRUE.equals(orchestrationContext.getIsRollbackEnabled()));
367                 //TODO confirm value - false by default
368                 createNetworkRequest.setFailIfExists(true);
369                 //NetworkTechnology(NetworkTechnology.NEUTRON); NOOP - default
370                 return createNetworkRequest;
371         }
372         
373         private void setFlowFlags(UpdateNetworkRequest updateNetworkRequest, OrchestrationContext orchestrationContext){
374                 updateNetworkRequest.setSkipAAI(true);          
375                 updateNetworkRequest.setBackout(Boolean.TRUE.equals(orchestrationContext.getIsRollbackEnabled()));
376                 //NetworkTechnology(NetworkTechnology.NEUTRON); NOOP - default
377         }
378         
379         private Map<String, String> addSharedAndExternal(Map<String, String> userInput, L3Network l3Network) {
380                 if (userInput == null)
381                         userInput = new HashMap<String, String>();
382                 if (!userInput.containsKey("shared")) {
383                         userInput.put("shared", Optional.ofNullable(l3Network.isIsSharedNetwork()).orElse(false).toString());
384                 }
385                 if (!userInput.containsKey("external")) {
386                         userInput.put("external", Optional.ofNullable(l3Network.isIsExternalNetwork()).orElse(false).toString());
387                 }
388                 return userInput;
389         }
390 }