173e776af9dbeadacdb47f357c34f8b8acc87790
[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.ProviderVlanNetwork;
38 import org.onap.so.adapters.nwrest.RollbackNetworkRequest;
39 import org.onap.so.adapters.nwrest.UpdateNetworkRequest;
40 import org.onap.so.bpmn.core.UrnPropertiesReader;
41 import org.onap.so.bpmn.servicedecomposition.bbobjects.CloudRegion;
42 import org.onap.so.bpmn.servicedecomposition.bbobjects.Customer;
43 import org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network;
44 import org.onap.so.bpmn.servicedecomposition.bbobjects.NetworkPolicy;
45 import org.onap.so.bpmn.servicedecomposition.bbobjects.RouteTableReference;
46 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
47 import org.onap.so.bpmn.servicedecomposition.bbobjects.VpnBinding;
48 import org.onap.so.bpmn.servicedecomposition.generalobjects.OrchestrationContext;
49 import org.onap.so.bpmn.servicedecomposition.generalobjects.RequestContext;
50 import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoNetwork;
51 import org.onap.so.entity.MsoRequest;
52 import org.onap.so.openstack.beans.NetworkRollback;
53 import org.onap.so.openstack.beans.RouteTarget;
54 import org.onap.so.openstack.beans.Subnet;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57 import org.springframework.stereotype.Component;
58 import org.springframework.web.util.UriUtils;
59
60 @Component
61 public class NetworkAdapterObjectMapper {
62     private static final ModelMapper modelMapper = new ModelMapper();
63     private static String FORWARD_SLASH = "/";
64     private static final Logger logger = LoggerFactory.getLogger(NetworkAdapterObjectMapper.class);
65
66     public CreateNetworkRequest createNetworkRequestMapper(RequestContext requestContext, CloudRegion cloudRegion,
67             OrchestrationContext orchestrationContext, ServiceInstance serviceInstance, L3Network l3Network,
68             Map<String, String> userInput, String cloudRegionPo, Customer customer)
69             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,
122             ServiceInstance serviceInstance, L3Network l3Network) throws UnsupportedEncodingException {
123         DeleteNetworkRequest deleteNetworkRequest = new DeleteNetworkRequest();
124
125         deleteNetworkRequest.setCloudSiteId(cloudRegion.getLcpCloudRegionId());
126
127         String messageId = getRandomUuid();
128         deleteNetworkRequest.setMessageId(messageId);
129
130         ModelInfoNetwork modelInfoNetwork = l3Network.getModelInfoNetwork();
131         if (modelInfoNetwork != null) {
132             deleteNetworkRequest.setModelCustomizationUuid(modelInfoNetwork.getModelCustomizationUUID());
133         }
134
135         deleteNetworkRequest.setMsoRequest(createMsoRequest(requestContext, serviceInstance));
136         deleteNetworkRequest.setNetworkId(l3Network.getNetworkId());
137         if (!StringUtils.isEmpty(l3Network.getHeatStackId())) {
138             deleteNetworkRequest.setNetworkStackId(l3Network.getHeatStackId());
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      * 
154      * @return
155      * @throws UnsupportedEncodingException
156      */
157     public RollbackNetworkRequest createNetworkRollbackRequestMapper(RequestContext requestContext,
158             CloudRegion cloudRegion, OrchestrationContext orchestrationContext, ServiceInstance serviceInstance,
159             L3Network l3Network, Map<String, String> userInput, String cloudRegionPo,
160             CreateNetworkResponse createNetworkResponse) throws UnsupportedEncodingException {
161         RollbackNetworkRequest rollbackNetworkRequest = new RollbackNetworkRequest();
162
163         rollbackNetworkRequest = setCommonRollbackRequestFields(rollbackNetworkRequest, requestContext);
164
165         NetworkRollback networkRollback =
166                 buildNetworkRollback(l3Network, cloudRegion, cloudRegionPo, createNetworkResponse);
167         rollbackNetworkRequest.setNetworkRollback(networkRollback);
168
169         return rollbackNetworkRequest;
170     }
171
172     public UpdateNetworkRequest createNetworkUpdateRequestMapper(RequestContext requestContext, CloudRegion cloudRegion,
173             OrchestrationContext orchestrationContext, ServiceInstance serviceInstance, L3Network l3Network,
174             Map<String, String> userInput, Customer customer) throws UnsupportedEncodingException {
175         UpdateNetworkRequest updateNetworkRequest = new UpdateNetworkRequest();
176
177         updateNetworkRequest.setCloudSiteId(cloudRegion.getLcpCloudRegionId());
178         updateNetworkRequest.setTenantId(cloudRegion.getTenantId());
179         updateNetworkRequest.setNetworkId(l3Network.getNetworkId());
180         updateNetworkRequest.setNetworkStackId(l3Network.getHeatStackId());
181         updateNetworkRequest.setNetworkName(l3Network.getNetworkName());
182         updateNetworkRequest.setNetworkType(l3Network.getModelInfoNetwork().getNetworkType());
183         updateNetworkRequest.setNetworkTypeVersion(l3Network.getModelInfoNetwork().getModelVersion());
184         updateNetworkRequest.setModelCustomizationUuid(l3Network.getModelInfoNetwork().getModelCustomizationUUID());
185         updateNetworkRequest.setSubnets(buildOpenstackSubnetList(l3Network));
186         updateNetworkRequest.setProviderVlanNetwork(buildProviderVlanNetwork(l3Network));
187         updateNetworkRequest.setContrailNetwork(buildContrailNetwork(l3Network, customer));
188         updateNetworkRequest.setNetworkParams(addSharedAndExternal(userInput, l3Network));
189         updateNetworkRequest.setMsoRequest(createMsoRequest(requestContext, serviceInstance));
190
191         setFlowFlags(updateNetworkRequest, orchestrationContext);
192
193         String messageId = getRandomUuid();
194         updateNetworkRequest.setMessageId(messageId);
195         updateNetworkRequest.setNotificationUrl(createCallbackUrl("NetworkAResponse", messageId));
196
197         return updateNetworkRequest;
198     }
199
200     private RollbackNetworkRequest setCommonRollbackRequestFields(RollbackNetworkRequest request,
201             RequestContext requestContext) throws UnsupportedEncodingException {
202         request.setSkipAAI(true);
203         String messageId = requestContext.getMsoRequestId();
204         request.setMessageId(messageId);
205         // request.setNotificationUrl(createCallbackUrl("NetworkAResponse", messageId));
206         return request;
207     }
208
209     private NetworkRollback buildNetworkRollback(L3Network l3Network, CloudRegion cloudRegion, String cloudRegionPo,
210             CreateNetworkResponse createNetworkResponse) {
211         NetworkRollback networkRollback = new NetworkRollback();
212         networkRollback.setNetworkId(l3Network.getNetworkId());
213         networkRollback.setNeutronNetworkId(createNetworkResponse.getMessageId());
214         networkRollback.setNetworkStackId(createNetworkResponse.getNetworkStackId());
215         networkRollback.setTenantId(cloudRegion.getTenantId());
216         networkRollback.setCloudId(cloudRegionPo);
217         networkRollback.setNetworkType(l3Network.getNetworkType());
218         ModelInfoNetwork modelInfoNetwork = l3Network.getModelInfoNetwork();
219         if (modelInfoNetwork != null) {
220             networkRollback.setModelCustomizationUuid(modelInfoNetwork.getModelCustomizationUUID());
221         }
222         // rollback will only be called when network was actually created
223         networkRollback.setNetworkCreated(createNetworkResponse.getNetworkCreated());
224         // TODO confirm below not required for create rollback
225         // NetworkName
226         // PhysicalNetwork
227         // Vlans
228         // msoRequest
229         return networkRollback;
230     }
231
232     public MsoRequest createMsoRequest(RequestContext requestContext, ServiceInstance serviceInstance) {
233         MsoRequest msoRequest = new MsoRequest();
234         msoRequest.setRequestId(requestContext.getMsoRequestId());
235         msoRequest.setServiceInstanceId(serviceInstance.getServiceInstanceId());
236         return msoRequest;
237     }
238
239     protected String getRandomUuid() {
240         return UUID.randomUUID().toString();
241     }
242
243     protected String createCallbackUrl(String messageType, String correlator) throws UnsupportedEncodingException {
244         String endpoint = this.getEndpoint();
245
246         while (endpoint.endsWith("/")) {
247             endpoint = endpoint.substring(0, endpoint.length() - 1);
248         }
249         return endpoint + "/" + UriUtils.encodePathSegment(messageType, "UTF-8") + "/"
250                 + UriUtils.encodePathSegment(correlator, "UTF-8");
251     }
252
253     protected String getEndpoint() {
254         return UrnPropertiesReader.getVariable("mso.workflow.message.endpoint");
255     }
256
257     /**
258      * Use BB L3Network object to build subnets list of type org.onap.so.openstack.beans.Subnet
259      * 
260      * @param L3Network
261      * @return List<org.onap.so.openstack.beans.Subnet>
262      */
263     protected List<Subnet> buildOpenstackSubnetList(L3Network l3Network) {
264
265         List<org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet> subnets = l3Network.getSubnets();
266         List<org.onap.so.openstack.beans.Subnet> subnetList = new ArrayList<org.onap.so.openstack.beans.Subnet>();
267         // create mapper from onap Subnet to openstack bean Subnet
268         if (modelMapper.getTypeMap(org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet.class,
269                 org.onap.so.openstack.beans.Subnet.class) == null) {
270             PropertyMap<org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet, org.onap.so.openstack.beans.Subnet> personMap =
271                     new PropertyMap<org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet, org.onap.so.openstack.beans.Subnet>() {
272                         protected void configure() {
273                             map().setSubnetName(source.getSubnetName());
274                             map(source.getSubnetId(), destination.getSubnetId());
275                             map(source.getNeutronSubnetId(), destination.getNeutronId());
276                             map(source.getGatewayAddress(), destination.getGatewayIp());
277                             map(source.getIpVersion(), destination.getIpVersion());
278                             map(source.isDhcpEnabled(), destination.getEnableDHCP());
279                             map(source.getSubnetSequence(), destination.getSubnetSequence());
280                         }
281                     };
282             modelMapper.addMappings(personMap);
283         }
284
285         for (org.onap.so.bpmn.servicedecomposition.bbobjects.Subnet subnet : subnets) {
286             org.onap.so.openstack.beans.Subnet openstackSubnet =
287                     modelMapper.map(subnet, org.onap.so.openstack.beans.Subnet.class);
288             // update cidr value
289             if (subnet.getNetworkStartAddress() != null && subnet.getCidrMask() != null)
290                 openstackSubnet
291                         .setCidr(subnet.getNetworkStartAddress().concat(FORWARD_SLASH).concat(subnet.getCidrMask()));
292             List<org.onap.so.bpmn.servicedecomposition.bbobjects.HostRoute> hostRouteList = subnet.getHostRoutes();
293             List<org.onap.so.openstack.beans.HostRoute> openstackHostRouteList = new ArrayList<>();
294             org.onap.so.openstack.beans.HostRoute openstackHostRoute = null;
295             // TODO only 2 fields available on openstack object. Confirm it is sufficient or add as needed
296             for (org.onap.so.bpmn.servicedecomposition.bbobjects.HostRoute hostRoute : hostRouteList) {
297                 openstackHostRoute = new org.onap.so.openstack.beans.HostRoute();
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 }