4fee1f909bef88ea418e163371352b9ac3b71e40
[so.git] /
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 import org.apache.commons.lang3.StringUtils;
31 import org.modelmapper.ModelMapper;
32 import org.modelmapper.PropertyMap;
33 import org.onap.so.adapters.nwrest.ContrailNetwork;
34 import org.onap.so.adapters.nwrest.CreateNetworkRequest;
35 import org.onap.so.adapters.nwrest.CreateNetworkResponse;
36 import org.onap.so.adapters.nwrest.DeleteNetworkRequest;
37 import org.onap.so.adapters.nwrest.NetworkTechnology;
38 import org.onap.so.adapters.nwrest.ProviderVlanNetwork;
39 import org.onap.so.adapters.nwrest.RollbackNetworkRequest;
40 import org.onap.so.adapters.nwrest.UpdateNetworkRequest;
41 import org.onap.so.bpmn.core.UrnPropertiesReader;
42 import org.onap.so.bpmn.servicedecomposition.bbobjects.CloudRegion;
43 import org.onap.so.bpmn.servicedecomposition.bbobjects.Customer;
44 import org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network;
45 import org.onap.so.bpmn.servicedecomposition.bbobjects.NetworkPolicy;
46 import org.onap.so.bpmn.servicedecomposition.bbobjects.RouteTableReference;
47 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
48 import org.onap.so.bpmn.servicedecomposition.bbobjects.VpnBinding;
49 import org.onap.so.bpmn.servicedecomposition.generalobjects.OrchestrationContext;
50 import org.onap.so.bpmn.servicedecomposition.generalobjects.RequestContext;
51 import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoNetwork;
52 import org.onap.so.entity.MsoRequest;
53 import org.onap.so.openstack.beans.NetworkRollback;
54 import org.onap.so.openstack.beans.RouteTarget;
55 import org.onap.so.openstack.beans.Subnet;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58 import org.springframework.stereotype.Component;
59 import org.springframework.web.util.UriUtils;
60
61 @Component
62 public class NetworkAdapterObjectMapper {
63     private static final ModelMapper modelMapper = new ModelMapper();
64     private static String FORWARD_SLASH = "/";
65     private static final Logger logger = LoggerFactory.getLogger(NetworkAdapterObjectMapper.class);
66
67     public CreateNetworkRequest createNetworkRequestMapper(RequestContext requestContext, CloudRegion cloudRegion,
68             OrchestrationContext orchestrationContext, ServiceInstance serviceInstance, L3Network l3Network,
69             Map<String, String> userInput, String cloudRegionPo, Customer customer)
70             throws UnsupportedEncodingException {
71         CreateNetworkRequest createNetworkRequest = new CreateNetworkRequest();
72
73         // set cloudSiteId as determined for cloud region PO instead of cloudRegion.getLcpCloudRegionId()
74         createNetworkRequest.setCloudSiteId(cloudRegionPo);
75         createNetworkRequest.setTenantId(cloudRegion.getTenantId());
76         createNetworkRequest.setNetworkId(l3Network.getNetworkId());
77         createNetworkRequest.setNetworkName(l3Network.getNetworkName());
78         // TODO fields not available
79         createNetworkRequest.setNetworkType(l3Network.getNetworkType());
80         // createNetworkRequest.setNetworkTypeVersion(serviceInstance.getModelInfoServiceInstance().getModelVersion());
81         ModelInfoNetwork modelInfoNetwork = l3Network.getModelInfoNetwork();
82         if (modelInfoNetwork != null) {
83             createNetworkRequest.setModelCustomizationUuid(modelInfoNetwork.getModelCustomizationUUID());
84         }
85
86         // build and set Subnet list
87         createNetworkRequest.setSubnets(buildOpenstackSubnetList(l3Network));
88
89         // build and set provider Vlan Network
90         ProviderVlanNetwork providerVlanNetwork = buildProviderVlanNetwork(l3Network);
91         createNetworkRequest.setProviderVlanNetwork(providerVlanNetwork);
92         String networkTechnology = l3Network.getModelInfoNetwork().getNetworkTechnology();
93         if (networkTechnology == null) {
94             networkTechnology = l3Network.getNetworkTechnology();
95             logger.warn("NetworkTechnology was null in CatalogDB. Using field from AAI: " + networkTechnology);
96         }
97         if (networkTechnology != null) {
98             createNetworkRequest.setNetworkTechnology(networkTechnology.toUpperCase());
99             if (createNetworkRequest.getNetworkTechnology().contains("CONTRAIL")) {
100                 createNetworkRequest.setContrailRequest(true);
101             }
102         }
103
104         // build and set Contrail Network
105         ContrailNetwork contrailNetwork = buildContrailNetwork(l3Network, customer);
106         createNetworkRequest.setContrailNetwork(contrailNetwork);
107
108         // set Network Parameters from VID request, add "shared" and "external" to this map
109         createNetworkRequest.setNetworkParams(addSharedAndExternal(userInput, l3Network));
110
111         createNetworkRequest = setFlowFlags(createNetworkRequest, orchestrationContext);
112
113         createNetworkRequest.setMsoRequest(createMsoRequest(requestContext, serviceInstance));
114
115         String messageId = getRandomUuid();
116         createNetworkRequest.setMessageId(messageId);
117         createNetworkRequest.setNotificationUrl(createCallbackUrl("NetworkAResponse", messageId));
118
119         return createNetworkRequest;
120     }
121
122     public DeleteNetworkRequest deleteNetworkRequestMapper(RequestContext requestContext, CloudRegion cloudRegion,
123             ServiceInstance serviceInstance, L3Network l3Network) throws UnsupportedEncodingException {
124         DeleteNetworkRequest deleteNetworkRequest = new DeleteNetworkRequest();
125
126         deleteNetworkRequest.setCloudSiteId(cloudRegion.getLcpCloudRegionId());
127
128         String messageId = getRandomUuid();
129         deleteNetworkRequest.setMessageId(messageId);
130
131         ModelInfoNetwork modelInfoNetwork = l3Network.getModelInfoNetwork();
132         if (modelInfoNetwork != null) {
133             deleteNetworkRequest.setModelCustomizationUuid(modelInfoNetwork.getModelCustomizationUUID());
134         }
135
136         deleteNetworkRequest.setMsoRequest(createMsoRequest(requestContext, serviceInstance));
137         deleteNetworkRequest.setNetworkId(l3Network.getNetworkId());
138         if (!StringUtils.isEmpty(l3Network.getHeatStackId())) {
139             deleteNetworkRequest.setNetworkStackId(l3Network.getHeatStackId());
140         } else {
141             deleteNetworkRequest.setNetworkStackId(l3Network.getNetworkName());
142         }
143         deleteNetworkRequest.setNetworkType(l3Network.getNetworkType());
144         deleteNetworkRequest.setSkipAAI(true);
145         deleteNetworkRequest.setTenantId(cloudRegion.getTenantId());
146
147         deleteNetworkRequest.setNotificationUrl(createCallbackUrl("NetworkAResponse", messageId));
148
149         return deleteNetworkRequest;
150     }
151
152     /**
153      * Access method to build Rollback Network Request
154      * 
155      * @return
156      * @throws UnsupportedEncodingException
157      */
158     public RollbackNetworkRequest createNetworkRollbackRequestMapper(RequestContext requestContext,
159             CloudRegion cloudRegion, OrchestrationContext orchestrationContext, ServiceInstance serviceInstance,
160             L3Network l3Network, Map<String, String> userInput, String cloudRegionPo,
161             CreateNetworkResponse createNetworkResponse) throws UnsupportedEncodingException {
162         RollbackNetworkRequest rollbackNetworkRequest = new RollbackNetworkRequest();
163
164         rollbackNetworkRequest = setCommonRollbackRequestFields(rollbackNetworkRequest, requestContext);
165
166         NetworkRollback networkRollback =
167                 buildNetworkRollback(l3Network, cloudRegion, cloudRegionPo, createNetworkResponse);
168         rollbackNetworkRequest.setNetworkRollback(networkRollback);
169
170         return rollbackNetworkRequest;
171     }
172
173     public UpdateNetworkRequest createNetworkUpdateRequestMapper(RequestContext requestContext, CloudRegion cloudRegion,
174             OrchestrationContext orchestrationContext, ServiceInstance serviceInstance, L3Network l3Network,
175             Map<String, String> userInput, Customer customer) throws UnsupportedEncodingException {
176         UpdateNetworkRequest updateNetworkRequest = new UpdateNetworkRequest();
177
178         updateNetworkRequest.setCloudSiteId(cloudRegion.getLcpCloudRegionId());
179         updateNetworkRequest.setTenantId(cloudRegion.getTenantId());
180         updateNetworkRequest.setNetworkId(l3Network.getNetworkId());
181         updateNetworkRequest.setNetworkStackId(l3Network.getHeatStackId());
182         updateNetworkRequest.setNetworkName(l3Network.getNetworkName());
183         updateNetworkRequest.setNetworkType(l3Network.getModelInfoNetwork().getNetworkType());
184         updateNetworkRequest.setNetworkTypeVersion(l3Network.getModelInfoNetwork().getModelVersion());
185         updateNetworkRequest.setModelCustomizationUuid(l3Network.getModelInfoNetwork().getModelCustomizationUUID());
186         updateNetworkRequest.setSubnets(buildOpenstackSubnetList(l3Network));
187         updateNetworkRequest.setProviderVlanNetwork(buildProviderVlanNetwork(l3Network));
188         updateNetworkRequest.setContrailNetwork(buildContrailNetwork(l3Network, customer));
189         updateNetworkRequest.setNetworkParams(addSharedAndExternal(userInput, l3Network));
190         updateNetworkRequest.setMsoRequest(createMsoRequest(requestContext, serviceInstance));
191
192         setFlowFlags(updateNetworkRequest, orchestrationContext);
193
194         String messageId = getRandomUuid();
195         updateNetworkRequest.setMessageId(messageId);
196         updateNetworkRequest.setNotificationUrl(createCallbackUrl("NetworkAResponse", messageId));
197
198         return updateNetworkRequest;
199     }
200
201     private RollbackNetworkRequest setCommonRollbackRequestFields(RollbackNetworkRequest request,
202             RequestContext requestContext) throws UnsupportedEncodingException {
203         request.setSkipAAI(true);
204         String messageId = requestContext.getMsoRequestId();
205         request.setMessageId(messageId);
206         // request.setNotificationUrl(createCallbackUrl("NetworkAResponse", 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) throws UnsupportedEncodingException {
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     private 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<org.onap.so.openstack.beans.Subnet>();
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                         protected void configure() {
274                             map().setSubnetName(source.getSubnetName());
275                             map(source.getSubnetId(), destination.getSubnetId());
276                             map(source.getNeutronSubnetId(), destination.getNeutronId());
277                             map(source.getGatewayAddress(), destination.getGatewayIp());
278                             map(source.getIpVersion(), destination.getIpVersion());
279                             map(source.isDhcpEnabled(), destination.getEnableDHCP());
280                             map(source.getSubnetSequence(), destination.getSubnetSequence());
281                         }
282                     };
283             modelMapper.addMappings(personMap);
284         }
285
286         for (org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet subnet : subnets) {
287             org.onap.so.openstack.beans.Subnet openstackSubnet =
288                     modelMapper.map(subnet, org.onap.so.openstack.beans.Subnet.class);
289             // update cidr value
290             if (subnet.getNetworkStartAddress() != null && subnet.getCidrMask() != null)
291                 openstackSubnet
292                         .setCidr(subnet.getNetworkStartAddress().concat(FORWARD_SLASH).concat(subnet.getCidrMask()));
293             List<org.onap.so.bpmn.servicedecomposition.bbobjects.HostRoute> hostRouteList = subnet.getHostRoutes();
294             List<org.onap.so.openstack.beans.HostRoute> openstackHostRouteList = new ArrayList<>();
295             org.onap.so.openstack.beans.HostRoute openstackHostRoute = new org.onap.so.openstack.beans.HostRoute();
296             // TODO only 2 fields available on openstack object. Confirm it is sufficient or add as needed
297             for (org.onap.so.bpmn.servicedecomposition.bbobjects.HostRoute hostRoute : hostRouteList) {
298                 openstackHostRoute.setNextHop(hostRoute.getNextHop());
299                 openstackHostRoute.setPrefix(hostRoute.getRoutePrefix());
300                 // add host route to the list
301                 openstackHostRouteList.add(openstackHostRoute);
302             }
303             if (subnet.getDhcpStart() != null && !subnet.getDhcpStart().equals("")) {
304                 org.onap.so.openstack.beans.Pool openstackAllocationPool = new org.onap.so.openstack.beans.Pool();
305                 openstackAllocationPool.setStart(subnet.getDhcpStart());
306                 openstackAllocationPool.setEnd(subnet.getDhcpEnd());
307                 List<org.onap.so.openstack.beans.Pool> allocationPools = new ArrayList<>();
308                 allocationPools.add(openstackAllocationPool);
309                 openstackSubnet.setAllocationPools(allocationPools);
310             }
311             openstackSubnet.setHostRoutes(openstackHostRouteList);
312             // add subnet to the list
313             subnetList.add(openstackSubnet);
314         }
315         return subnetList;
316     }
317
318     private ProviderVlanNetwork buildProviderVlanNetwork(L3Network l3Network) {
319         ProviderVlanNetwork providerVlanNetwork = new ProviderVlanNetwork();
320         providerVlanNetwork.setPhysicalNetworkName(l3Network.getPhysicalNetworkName());
321         List<Integer> vlans = new ArrayList<Integer>();
322         List<org.onap.so.bpmn.servicedecomposition.bbobjects.SegmentationAssignment> segmentationAssignments =
323                 l3Network.getSegmentationAssignments();
324         for (org.onap.so.bpmn.servicedecomposition.bbobjects.SegmentationAssignment assignment : segmentationAssignments) {
325             vlans.add(Integer.valueOf(assignment.getSegmentationId()));
326         }
327         providerVlanNetwork.setVlans(vlans);
328         return providerVlanNetwork;
329     }
330
331     private ContrailNetwork buildContrailNetwork(L3Network l3Network, Customer customer) {
332         ContrailNetwork contrailNetwork = new ContrailNetwork();
333         contrailNetwork.setExternal(Optional.ofNullable(l3Network.isIsExternalNetwork()).orElse(false).toString());
334         contrailNetwork.setShared(Optional.ofNullable(l3Network.isIsSharedNetwork()).orElse(false).toString());
335         contrailNetwork.setPolicyFqdns(buildPolicyFqdns(l3Network.getNetworkPolicies()));
336         contrailNetwork.setRouteTableFqdns(buildRouteTableFqdns(l3Network.getContrailNetworkRouteTableReferences()));
337         if (customer != null)
338             contrailNetwork.setRouteTargets(buildRouteTargets(customer.getVpnBindings()));
339         // PolicyFqdns(policyFqdns); --- is set in getAAINetworkPolicy
340         // RouteTableFqdns(routeTableFqdns); --- is set in getAAINetworkTableRef
341         // RouteTargets(routeTargets); --- is set in getAAINetworkVpnBinding
342         return contrailNetwork;
343     }
344
345     private List<String> buildPolicyFqdns(List<NetworkPolicy> networkPolicies) {
346         List<String> policyFqdns = new ArrayList<>();
347         for (NetworkPolicy networkPolicy : networkPolicies) {
348             policyFqdns.add(networkPolicy.getNetworkPolicyFqdn());
349         }
350         return policyFqdns;
351     }
352
353     private List<String> buildRouteTableFqdns(List<RouteTableReference> contrailNetworkRouteTableReferences) {
354         List<String> routeTableFqdns = new ArrayList<>();
355         for (RouteTableReference routeTableReference : contrailNetworkRouteTableReferences) {
356             routeTableFqdns.add(routeTableReference.getRouteTableReferenceFqdn());
357         }
358         return routeTableFqdns;
359     }
360
361     private List<RouteTarget> buildRouteTargets(List<VpnBinding> vpnBindings) {
362         if (modelMapper.getTypeMap(org.onap.so.bpmn.servicedecomposition.bbobjects.RouteTarget.class,
363                 RouteTarget.class) == null) {
364             modelMapper.addMappings(
365                     new PropertyMap<org.onap.so.bpmn.servicedecomposition.bbobjects.RouteTarget, RouteTarget>() {
366                         @Override
367                         protected void configure() {
368                             map().setRouteTarget(source.getGlobalRouteTarget());
369                             map().setRouteTargetRole(source.getRouteTargetRole());
370                         }
371                     });
372         }
373
374         List<RouteTarget> routeTargets = new ArrayList<>();
375         for (VpnBinding vpnBinding : vpnBindings) {
376             for (org.onap.so.bpmn.servicedecomposition.bbobjects.RouteTarget routeTarget : vpnBinding
377                     .getRouteTargets()) {
378                 routeTargets.add(modelMapper.map(routeTarget, RouteTarget.class));
379             }
380         }
381         return routeTargets;
382     }
383
384     private CreateNetworkRequest setFlowFlags(CreateNetworkRequest createNetworkRequest,
385             OrchestrationContext orchestrationContext) {
386         // TODO confirm flag value
387         createNetworkRequest.setSkipAAI(true);
388         createNetworkRequest.setBackout(Boolean.TRUE.equals(orchestrationContext.getIsRollbackEnabled()));
389         // TODO confirm value - false by default
390         createNetworkRequest.setFailIfExists(true);
391         // NetworkTechnology(NetworkTechnology.NEUTRON); NOOP - default
392         return createNetworkRequest;
393     }
394
395     private void setFlowFlags(UpdateNetworkRequest updateNetworkRequest, OrchestrationContext orchestrationContext) {
396         updateNetworkRequest.setSkipAAI(true);
397         updateNetworkRequest.setBackout(Boolean.TRUE.equals(orchestrationContext.getIsRollbackEnabled()));
398         // NetworkTechnology(NetworkTechnology.NEUTRON); NOOP - default
399     }
400
401     private Map<String, String> addSharedAndExternal(Map<String, String> userInput, L3Network l3Network) {
402         if (userInput == null)
403             userInput = new HashMap<String, String>();
404         if (!userInput.containsKey("shared")) {
405             userInput.put("shared", Optional.ofNullable(l3Network.isIsSharedNetwork()).orElse(false).toString());
406         }
407         if (!userInput.containsKey("external")) {
408             userInput.put("external", Optional.ofNullable(l3Network.isIsExternalNetwork()).orElse(false).toString());
409         }
410         return userInput;
411     }
412 }