heatbridge implementation for openstack-adapter
[so.git] / adapters / mso-openstack-adapters / src / main / java / org / onap / so / heatbridge / helpers / AaiHelper.java
1 /*
2  * Copyright (C) 2018 Bell Canada.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.onap.so.heatbridge.helpers;
17
18 import com.google.common.base.Preconditions;
19 import com.google.common.collect.ImmutableMap;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.stream.Collectors;
26 import org.apache.commons.collections.CollectionUtils;
27 import org.onap.aai.domain.yang.Flavor;
28 import org.onap.aai.domain.yang.Image;
29 import org.onap.aai.domain.yang.Relationship;
30 import org.onap.aai.domain.yang.RelationshipData;
31 import org.onap.aai.domain.yang.RelationshipList;
32 import org.onap.aai.domain.yang.SriovVf;
33 import org.onap.aai.domain.yang.Vserver;
34 import org.onap.so.heatbridge.constants.HeatBridgeConstants;
35 import org.openstack4j.model.compute.Server;
36
37 /**
38  * This class provides wrapper methods to manage creation of AAI objects and extracting objects from AAI and
39  * transforming into required objects.
40  */
41 public class AaiHelper {
42
43     /**
44      * Build vserver relationship object to entities: pserver, vf-module, image, flavor
45      *
46      * @param cloudOwner AAI cloudOwner value
47      * @param cloudRegionId AAI cloud-region identifier
48      * @param genericVnfId AAI generic-vnf identifier
49      * @param vfModuleId AAI vf-module identifier
50      * @param server Openstack Server object
51      */
52     public RelationshipList getVserverRelationshipList(final String cloudOwner, final String cloudRegionId, final String
53         genericVnfId, final String vfModuleId, final Server server) {
54         RelationshipList relationshipList = new RelationshipList();
55         List<Relationship> relationships = relationshipList.getRelationship();
56
57         // vserver to pserver relationship
58         Relationship pserverRelationship = buildRelationship(HeatBridgeConstants.AAI_PSERVER,
59             ImmutableMap.<String, String>builder()
60                 .put(HeatBridgeConstants.AAI_PSERVER_HOSTNAME, server.getHypervisorHostname())
61                 .build());
62         relationships.add(pserverRelationship);
63
64         // vserver to vf-module relationship
65         Relationship vfModuleRelationship = buildRelationship(HeatBridgeConstants.AAI_VF_MODULE,
66             ImmutableMap.<String, String>builder()
67                 .put(HeatBridgeConstants.AAI_GENERIC_VNF_ID, genericVnfId)
68                 .put(HeatBridgeConstants.AAI_VF_MODULE_ID, vfModuleId)
69                 .build());
70         relationships.add(vfModuleRelationship);
71
72         // vserver to image relationship
73         Relationship imageRel = buildRelationship(HeatBridgeConstants.AAI_IMAGE,
74             ImmutableMap.<String, String>builder()
75                 .put(HeatBridgeConstants.AAI_CLOUD_OWNER, cloudOwner)
76                 .put(HeatBridgeConstants.AAI_CLOUD_REGION_ID, cloudRegionId)
77                 .put(HeatBridgeConstants.AAI_IMAGE_ID, server.getImage().getId())
78                 .build());
79         relationships.add(imageRel);
80
81         // vserver to flavor relationship
82         Relationship flavorRel = buildRelationship(HeatBridgeConstants.AAI_FLAVOR,
83             ImmutableMap.<String, String>builder()
84                 .put(HeatBridgeConstants.AAI_CLOUD_OWNER, cloudOwner)
85                 .put(HeatBridgeConstants.AAI_CLOUD_REGION_ID, cloudRegionId)
86                 .put(HeatBridgeConstants.AAI_FLAVOR_ID, server.getFlavor().getId())
87                 .build());
88         relationships.add(flavorRel);
89         return relationshipList;
90     }
91
92     public RelationshipList getLInterfaceRelationshipList(final String pserverName, final String pIfName,
93         final String pfPciId) {
94         RelationshipList relationshipList = new RelationshipList();
95         List<Relationship> relationships = relationshipList.getRelationship();
96
97         // sriov-vf to sriov-pf relationship
98         Relationship sriovPfRelationship = buildRelationship(HeatBridgeConstants.AAI_SRIOV_PF,
99             ImmutableMap.<String, String>builder()
100                 .put(HeatBridgeConstants.AAI_PSERVER_HOSTNAME, pserverName)
101                 .put(HeatBridgeConstants.AAI_P_INTERFACE_NAME, pIfName)
102                 .put(HeatBridgeConstants.AAI_SRIOV_PF_PCI_ID, pfPciId)
103                 .build());
104         relationships.add(sriovPfRelationship);
105
106         return relationshipList;
107     }
108
109     /**
110      * Transform Openstack Server object to AAI Vserver object
111      *
112      * @param serverId Openstack server identifier
113      * @param server Openstack server object
114      * @return AAI Vserver object
115      */
116     public Vserver buildVserver(final String serverId, final Server server) {
117         Vserver vserver = new Vserver();
118         vserver.setInMaint(false);
119         vserver.setIsClosedLoopDisabled(false);
120         vserver.setVserverId(serverId);
121         vserver.setVserverName(server.getName());
122         vserver.setVserverName2(server.getName());
123         vserver.setProvStatus(server.getStatus().value());
124         server.getLinks().stream().filter(link -> link.getRel().equals(HeatBridgeConstants.OS_RESOURCES_SELF_LINK_KEY))
125             .findFirst().ifPresent(link -> vserver.setVserverSelflink(link.getHref()));
126         return vserver;
127     }
128
129     /**
130      * Transform Openstack Image object to AAI Image object
131      *
132      * @param image Openstack Image object
133      * @return AAI Image object
134      */
135     public Image buildImage(final org.openstack4j.model.compute.Image image) {
136         Image aaiImage = new Image();
137         aaiImage.setImageId(image.getId());
138         aaiImage.setImageName(image.getName());
139         aaiImage.setImageOsDistro(HeatBridgeConstants.OS_UNKNOWN_KEY);
140         aaiImage.setImageOsVersion(HeatBridgeConstants.OS_UNKNOWN_KEY);
141         image.getLinks().stream().filter(link -> link.getRel().equals(HeatBridgeConstants.OS_RESOURCES_SELF_LINK_KEY))
142             .findFirst().ifPresent(link -> aaiImage.setImageSelflink(link.getHref()));
143         return aaiImage;
144     }
145
146     /**
147      * Transform Openstack Flavor object to AAI Flavor object
148      *
149      * @param flavor Openstack Flavor object
150      * @return AAI Flavor object
151      */
152     public Flavor buildFlavor(final org.openstack4j.model.compute.Flavor flavor) {
153         Flavor aaiFlavor = new Flavor();
154         aaiFlavor.setFlavorId(flavor.getId());
155         aaiFlavor.setFlavorName(flavor.getName());
156         flavor.getLinks().stream().filter(link -> link.getRel().equals(HeatBridgeConstants.OS_RESOURCES_SELF_LINK_KEY))
157             .findFirst().ifPresent(link -> aaiFlavor.setFlavorSelflink(link.getHref()));
158         return aaiFlavor;
159     }
160
161     /**
162      * Extract a list of flavors URI associated with the list of vservers
163      *
164      * @param vservers List of vserver AAI objects
165      * @return a list of related flavor related-links
166      */
167     public List<String> getFlavorsUriFromVserver(final List<Vserver> vservers) {
168         List<String> flavorUris = new ArrayList<>();
169         vservers.forEach(vserver -> flavorUris.addAll(
170             filterRelatedLinksByRelatedToProperty(vserver.getRelationshipList(), HeatBridgeConstants.AAI_FLAVOR)));
171         return flavorUris;
172     }
173
174     /**
175      * Extract a list of images URI associated with the list of vservers
176      *
177      * @param vservers List of vserver AAI objects
178      * @return a list of related image related-links
179      */
180     public List<String> getImagesUriFromVserver(final List<Vserver> vservers) {
181         List<String> imageUris = new ArrayList<>();
182         vservers.forEach(vserver -> imageUris.addAll(
183             filterRelatedLinksByRelatedToProperty(vserver.getRelationshipList(), HeatBridgeConstants.AAI_IMAGE)));
184         return imageUris;
185     }
186
187     /**
188      * From the list vserver objects build a map of compute hosts's name and the PCI IDs linked to it.
189      *
190      * @param vservers List of vserver AAI objects
191      * @return a map of compute names to the PCI ids associated with the compute
192      */
193     public Map<String, List<String>> getPserverToPciIdMap(final List<Vserver> vservers) {
194         Map<String, List<String>> pserverToPciIdMap = new HashMap<>();
195         for(Vserver vserver : vservers) {
196             if(vserver.getLInterfaces() != null) {
197                 List<String> pciIds = vserver.getLInterfaces().getLInterface()
198                     .stream()
199                     .filter(lInterface -> lInterface.getSriovVfs() != null
200                         && CollectionUtils.isNotEmpty(lInterface.getSriovVfs().getSriovVf()))
201                     .flatMap(lInterface -> lInterface.getSriovVfs().getSriovVf().stream())
202                     .map(SriovVf::getPciId)
203                     .collect(Collectors.toList());
204                 if (CollectionUtils.isNotEmpty(pciIds)) {
205                     List<String> matchingPservers = extractRelationshipDataValue(vserver.getRelationshipList(),
206                         HeatBridgeConstants.AAI_PSERVER, HeatBridgeConstants.AAI_PSERVER_HOSTNAME);
207                     Preconditions.checkState(matchingPservers != null && matchingPservers.size() == 1,
208                         "Invalid pserver relationships for vserver: " + vserver.getVserverName());
209                     pserverToPciIdMap.put(matchingPservers.get(0), pciIds);
210                 }
211             }
212         }
213         return pserverToPciIdMap;
214     }
215
216     /**
217      * Extract from relationship-list object all the relationship-value that match the related-to and
218      * relationship-key fields.
219      *
220      * @param relationshipListObj AAI relationship-list object
221      * @param relatedToProperty related-to value
222      * @param relationshipKey relationship-key value
223      * @return relationship-value matching the key requested for the relationship object of type related-to property
224      */
225     private List<String> extractRelationshipDataValue(final RelationshipList relationshipListObj,
226         final String relatedToProperty, final String relationshipKey) {
227         if (relationshipListObj != null && relationshipListObj.getRelationship() != null) {
228             return relationshipListObj.getRelationship().stream()
229                 .filter(relationship -> relationship.getRelatedTo().equals(relatedToProperty))
230                 .map(Relationship::getRelationshipData)
231                 .flatMap(Collection::stream)
232                 .filter(data -> data.getRelationshipKey() != null && relationshipKey.equals(data.getRelationshipKey()))
233                 .map(RelationshipData::getRelationshipValue)
234                 .collect(Collectors.toList());
235         }
236         return new ArrayList<>();
237     }
238
239     /**
240      * Extract and filter the related-links to all objects that match the type specified by the filter property
241      *
242      * @param relationshipListObj AAI object representing relationship object
243      * @param relatedToProperty Value identifying the type of AAI object for related-to field
244      * @return a list of related-links filtered by the specified related-to property
245      */
246     private List<String> filterRelatedLinksByRelatedToProperty(final RelationshipList relationshipListObj,
247         final String relatedToProperty) {
248         if (relationshipListObj != null && relationshipListObj.getRelationship() != null) {
249             return relationshipListObj.getRelationship().stream()
250                 .filter(relationship -> relationship.getRelatedTo().equals(relatedToProperty))
251                 .map(Relationship::getRelatedLink)
252                 .collect(Collectors.toList());
253         }
254         return new ArrayList<>();
255     }
256
257     /**
258      * Build the relationship object
259      *
260      * @param relatedTo Related to entity value
261      * @param relationshipKeyValues Key value pairs of relationship data
262      * @return AAI Relationship object
263      */
264     private Relationship buildRelationship(final String relatedTo, final Map<String, String> relationshipKeyValues) {
265         Relationship relationship = new Relationship();
266         relationship.setRelatedTo(relatedTo);
267         relationshipKeyValues.keySet().forEach(k -> {
268             RelationshipData relationshipData = new RelationshipData();
269             relationshipData.setRelationshipKey(k);
270             relationshipData.setRelationshipValue(relationshipKeyValues.get(k));
271             relationship.getRelationshipData().add(relationshipData);
272         });
273         return relationship;
274     }
275 }