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