1 /*******************************************************************************
\r
2 * Copyright © 2017-2018 AT&T Intellectual Property.
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
15 ******************************************************************************/
\r
16 package org.onap.ccsdk.apps.ms.vlantagapi.core.service;
\r
18 import java.util.ArrayList;
\r
19 import java.util.Date;
\r
20 import java.util.List;
\r
21 import java.util.Optional;
\r
22 import java.util.UUID;
\r
24 import org.onap.ccsdk.apps.ms.vlantagapi.core.exception.VlantagApiException;
\r
25 import org.onap.ccsdk.apps.ms.vlantagapi.core.extinf.pm.model.AllowedRanges;
\r
26 import org.onap.ccsdk.apps.ms.vlantagapi.core.extinf.pm.model.Elements;
\r
27 import org.onap.ccsdk.apps.ms.vlantagapi.core.extinf.pm.model.ResourceModel;
\r
28 import org.onap.ccsdk.apps.ms.vlantagapi.core.model.AssignVlanTagRequest;
\r
29 import org.onap.ccsdk.apps.ms.vlantagapi.core.model.AssignVlanTagRequestInput;
\r
30 import org.onap.ccsdk.apps.ms.vlantagapi.core.model.AssignVlanTagResponse;
\r
31 import org.onap.ccsdk.apps.ms.vlantagapi.core.model.AssignVlanTagResponseOutput;
\r
32 import org.onap.ccsdk.apps.ms.vlantagapi.core.model.PingResponse;
\r
33 import org.onap.ccsdk.apps.ms.vlantagapi.core.model.UnassignVlanTagRequest;
\r
34 import org.onap.ccsdk.apps.ms.vlantagapi.core.model.UnassignVlanTagRequestInput;
\r
35 import org.onap.ccsdk.apps.ms.vlantagapi.core.model.UnassignVlanTagResponse;
\r
36 import org.onap.ccsdk.apps.ms.vlantagapi.core.model.UnassignVlanTagResponseOutput;
\r
37 import org.onap.ccsdk.apps.ms.vlantagapi.core.model.VlanTag;
\r
38 import org.onap.ccsdk.apps.ms.vlantagapi.extinf.pm.PolicyManagerClient;
\r
39 import org.onap.ccsdk.sli.adaptors.ra.ResourceAllocator;
\r
40 import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceEntity;
\r
41 import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceRequest;
\r
42 import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceResponse;
\r
43 import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceTarget;
\r
44 import org.onap.ccsdk.sli.adaptors.rm.data.AllocationStatus;
\r
45 import org.onap.ccsdk.sli.adaptors.rm.data.Range;
\r
46 import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType;
\r
47 import org.onap.ccsdk.sli.adaptors.util.str.StrUtil;
\r
50 import org.slf4j.Logger;
\r
51 import org.slf4j.LoggerFactory;
\r
52 import org.springframework.beans.factory.annotation.Autowired;
\r
53 import org.springframework.stereotype.Service;
\r
56 * VlantagApiServiceImpl.java Purpose: Provide Vlantag Assignment & UnAssignment
\r
57 * APIs service implementation for VNFs
\r
59 * @author Saurav Paira
\r
63 public class VlantagApiServiceImpl implements VlantagApiService {
\r
65 private static final VlantagApiService INSTANCE = new VlantagApiServiceImpl();
\r
66 private static final Logger log = LoggerFactory.getLogger(VlantagApiServiceImpl.class);
\r
67 private static final String BEGIN_SQUAREBRACKET_RC = "#BSB#";
\r
68 private static final String END_SQUAREBRACKET_RC = "#ESB#";
\r
71 private ResourceAllocator resourceAllocator;
\r
73 private PolicyManagerClient policyClient;
\r
75 public static VlantagApiService getInstance() {
\r
80 * This is a assignVlanTag service implementation to assign Vlantags based on the
\r
81 * AssignVlanTagRequest and Policy instance.
\r
83 * @param AssignVlanTagRequest
\r
84 * @return AssignVlanTagResponse
\r
87 public AssignVlanTagResponse assignVlanTag(AssignVlanTagRequest request) throws Exception {
\r
88 List<AssignVlanTagResponseOutput> outputList = new ArrayList<>();
\r
91 validateRequest(request);
\r
92 List<AssignVlanTagRequestInput> vlanTagRequests = request.getInput();
\r
94 List<AssignVlanTagRequestInput> reservedResources = new ArrayList<>();
\r
96 for (AssignVlanTagRequestInput input : vlanTagRequests) {
\r
97 log.info("PolicyManagerClient called..for policy : {}", input.getPolicyInstanceName());
\r
99 List<ResourceModel> resourceModels = policyClient.getPolicy(input.getPolicyInstanceName());
\r
100 ResourceModel model = validate(resourceModels, input);
\r
101 List<ResourceResponse> rl = new ArrayList<>();
\r
103 for (Elements elements : model.getElements()) {
\r
105 ResourceEntity re = new ResourceEntity();
\r
106 ResourceTarget rt = new ResourceTarget();
\r
107 ResourceRequest rr = new ResourceRequest();
\r
108 List<ResourceResponse> rsList = new ArrayList<>();
\r
110 prepareResourceAllocatorObjects(input, model, elements, re, rt, rr);
\r
112 if (resourceAllocator != null) {
\r
113 AllocationStatus status = resourceAllocator.reserve(re, rt, rr, rsList);
\r
115 if (AllocationStatus.Success.equals(status))
\r
118 rollbackVlanTags(reservedResources);
\r
119 throw new VlantagApiException(
\r
120 "Failed to reserve VlanTags for Element : {}. " + elements.getVlantagName()
\r
121 + ". Rolling back vlantags for other elements (if any).");
\r
124 throw new VlantagApiException(
\r
125 "ResourceAllocator not available. Failed to Assign VlanTags for Element : "
\r
126 + elements.getVlantagName()
\r
127 + ". Rolling back vlantags for other elements (if any).");
\r
130 reservedResources.add(input);
\r
131 outputList.add(prepareVlanTagResponse(input, model, rl));
\r
134 } catch (Exception e) {
\r
135 log.error("Exception : " + e.getMessage(), e);
\r
137 AssignVlanTagResponse response = new AssignVlanTagResponse();
\r
138 response.setErrorCode(500);
\r
139 response.setErrorMessage(e.getMessage());
\r
143 AssignVlanTagResponse response = new AssignVlanTagResponse();
\r
144 response.setErrorCode(200);
\r
145 response.setErrorMessage("Success");
\r
146 response.setOutput(outputList);
\r
150 private void prepareResourceAllocatorObjects(AssignVlanTagRequestInput input, ResourceModel model, Elements element,
\r
151 ResourceEntity re, ResourceTarget rt, ResourceRequest rr) throws VlantagApiException {
\r
152 log.info("Preparing RA Objects for Vlan Type : " + input.getVlanType() + " and Element : "
\r
153 + element.getVlantagName());
\r
154 re.resourceEntityId = input.getVlanTagKey();
\r
155 re.resourceEntityType = model.getKeyType() == null ? "DEFAULT" : model.getKeyType();
\r
156 re.resourceEntityVersion = "1";
\r
158 rt.resourceTargetId = input.getScopeId();
\r
159 rt.resourceTargetType = model.getScope() == null ? "DEFAULT" : model.getScope();
\r
161 rr.resourceName = input.getVlanType();
\r
162 rr.serviceModel = input.getPolicyInstanceName();
\r
163 rr.endPointPosition = element.getVlantagName();
\r
164 rr.resourceType = ResourceType.Range;
\r
165 rr.applicationId = "SDNC";
\r
166 rr.rangeMaxOverride = -1;
\r
167 rr.rangeMinOverride = -1;
\r
168 if("TRUE".equalsIgnoreCase(element.getSharedRange()))
\r
169 rr.resourceShareGroup = input.getScopeId();
\r
171 List<Range> rangeList = new ArrayList<>();
\r
172 for (AllowedRanges allowedRange : element.getAllowedRanges()) {
\r
173 Range range = new Range();
\r
175 if (allowedRange.getMin() != null && !allowedRange.getMin().isEmpty())
\r
176 range.min = Integer.parseInt(allowedRange.getMin());
\r
178 if (allowedRange.getMax() != null && !allowedRange.getMax().isEmpty())
\r
179 range.max = Integer.parseInt(allowedRange.getMax());
\r
181 rangeList.add(range);
\r
184 rr.rangeOverrideList = rangeList;
\r
186 String resourceValue = resolveResourceElementValue(input, model, element);
\r
187 if (resourceValue != null) {
\r
188 rr.rangeRequestedNumbers = resourceValue; /* Manually provided values */
\r
191 * If the override flag is TRUE, then add the resource value also in the range,
\r
192 * so it will ignore the current range min-max in the policy. Persist in the DB
\r
193 * if available else Fail.
\r
195 if (element.getOverwrite() != null && element.getOverwrite().equalsIgnoreCase("TRUE")) {
\r
196 Range range = new Range();
\r
197 range.min = Integer.parseInt(resourceValue);
\r
198 rangeList.add(range);
\r
202 StrUtil.info(log, re);
\r
203 StrUtil.info(log, rt);
\r
204 StrUtil.info(log, rr);
\r
208 protected String resolveResourceElementValue(AssignVlanTagRequestInput input, ResourceModel model, Elements element)
\r
209 throws VlantagApiException {
\r
210 String recipe = trimBrackets(model.getResourceResolutionRecipe().trim());
\r
212 if (input.getResourceValue() != null && !input.getResourceValue().trim().isEmpty()
\r
213 && !input.getResourceValue().contains("$")) {
\r
214 log.info("Resource Value : " + input.getResourceValue());
\r
215 String resourceValue = trimBrackets(input.getResourceValue());
\r
217 String[] vlantagNames = recipe.split(",");
\r
218 String[] resourceValues = resourceValue.split(",");
\r
221 for (int i = 0; i < vlantagNames.length; i++) {
\r
222 if (vlantagNames[i].trim().equalsIgnoreCase(element.getVlantagName().trim()))
\r
223 return resourceValues[i].trim();
\r
225 } catch (IndexOutOfBoundsException e) {
\r
226 throw new VlantagApiException("No Matching Resource Value found from Recipe : \""
\r
227 + model.getResourceResolutionRecipe() + "\" for Vlantag Name : " + element.getVlantagName());
\r
234 ResourceModel validate(List<ResourceModel> resourceModels, AssignVlanTagRequestInput input)
\r
235 throws VlantagApiException {
\r
236 ResourceModel targetModel = null;
\r
237 if (resourceModels != null && !resourceModels.isEmpty()) {
\r
238 for (ResourceModel model : resourceModels) {
\r
239 if (model.getVlanType().equals(input.getVlanType())) {
\r
240 targetModel = model;
\r
244 validateModel(targetModel, input);
\r
246 throw new VlantagApiException("No Resource Models available in Policy Manager for Policy Instance Name : "
\r
247 + input.getPolicyInstanceName());
\r
248 return targetModel;
\r
251 void validateModel(ResourceModel model, AssignVlanTagRequestInput input) throws VlantagApiException {
\r
254 throw new VlantagApiException(
\r
255 "No Matching Policy Resource Model found for Vlan Type : " + input.getVlanType());
\r
257 if (model.getResourceResolutionRecipe() == null || model.getResourceResolutionRecipe().isEmpty())
\r
258 throw new VlantagApiException(
\r
259 "Resource Resolution Recipe is null in Resource Model for Vlan Type : " + input.getVlanType());
\r
261 if (model.getScope() == null || model.getScope().isEmpty())
\r
262 throw new VlantagApiException("Scope is null in Resource Model for Vlan Type : " + input.getVlanType());
\r
264 List<Elements> elements = model.getElements();
\r
265 validateElements(elements, input);
\r
270 void validateElements(List<Elements> elements, AssignVlanTagRequestInput input) throws VlantagApiException {
\r
271 if (elements != null && !elements.isEmpty()) {
\r
272 for (Elements element : elements) {
\r
273 if (element.getVlantagName() == null)
\r
274 throw new VlantagApiException(
\r
275 "Vlantag Name missing for Element in Resource Model Policy for Vlan Type : "
\r
276 + input.getVlanType());
\r
277 if (element.getAllowedRanges() == null || element.getAllowedRanges().isEmpty())
\r
278 throw new VlantagApiException(
\r
279 "Allowed Ranges missing for Element in Resource Model Policy for Vlan Type : "
\r
280 + input.getVlanType());
\r
283 throw new VlantagApiException(
\r
284 "No Vlantag Elements found in Resource Model Policy for Vlan Type : " + input.getVlanType());
\r
288 PolicyManagerClient getPolicyManagerClient() {
\r
289 return new PolicyManagerClient();
\r
292 void validateRequest(AssignVlanTagRequest request) throws VlantagApiException {
\r
293 if (request == null)
\r
294 throw new VlantagApiException("VlanTag Assign Request is null.");
\r
296 List<AssignVlanTagRequestInput> inputList = request.getInput();
\r
298 if (inputList == null || inputList.isEmpty())
\r
299 throw new VlantagApiException("VlanTag Assign Request Input is null or empty.");
\r
301 for (AssignVlanTagRequestInput input : inputList) {
\r
302 if (input.getPolicyInstanceName() == null || input.getPolicyInstanceName().isEmpty())
\r
303 throw new VlantagApiException("VlanTag Assign Request policy-instance-name is null.");
\r
305 if (input.getVlanType() == null || input.getVlanType().isEmpty())
\r
306 throw new VlantagApiException("VlanTag Assign Request vlan-type is null.");
\r
308 if (input.getScopeId() == null || input.getScopeId().isEmpty())
\r
309 throw new VlantagApiException("VlanTag Assign Request scope-id is null.");
\r
311 if (input.getVlanTagKey() == null || input.getVlanTagKey().isEmpty())
\r
312 throw new VlantagApiException("VlanTag Assign Request key is null.");
\r
317 private AssignVlanTagResponseOutput prepareVlanTagResponse(AssignVlanTagRequestInput input, ResourceModel model,
\r
318 List<ResourceResponse> rl) {
\r
319 AssignVlanTagResponseOutput ro = new AssignVlanTagResponseOutput();
\r
320 List<VlanTag> vlanTagList = new ArrayList<>();
\r
322 if (rl != null && !rl.isEmpty()) {
\r
323 ro.setResourceName(input.getResourceName());
\r
324 ro.setResourceValue(resolveRecipe(model, rl));
\r
325 ro.setResourceVlanRole(model.getResourceVlanRole());
\r
326 if (model.getDataStore() != null && !model.getDataStore().isEmpty()) {
\r
327 for (ResourceResponse rr : rl) {
\r
328 VlanTag tag = new VlanTag();
\r
329 Optional<Elements> optionalElements = model.getElements().stream()
\r
330 .filter(element -> element.getVlantagName().equalsIgnoreCase(rr.endPointPosition))
\r
332 optionalElements.ifPresent(element -> tag.setElementVlanRole(element.getElementVlanRole()));
\r
334 tag.setVlanUuid(UUID.randomUUID().toString());
\r
335 tag.setVlantagName(rr.endPointPosition);
\r
336 tag.setVlantagValue(rr.resourceAllocated);
\r
337 vlanTagList.add(tag);
\r
341 ro.setStoredElements(vlanTagList);
\r
347 protected String resolveRecipe(ResourceModel model, List<ResourceResponse> rl) {
\r
348 String recipe = model.getResourceResolutionRecipe().trim();
\r
349 String resourceValue = recipe;
\r
351 if (recipe.contains(BEGIN_SQUAREBRACKET_RC)) {
\r
352 recipe = recipe.replace(BEGIN_SQUAREBRACKET_RC, "");
\r
353 resourceValue = resourceValue.replace(BEGIN_SQUAREBRACKET_RC, "[ ");
\r
356 if (recipe.contains(END_SQUAREBRACKET_RC)) {
\r
357 recipe = recipe.replace(END_SQUAREBRACKET_RC, "");
\r
358 resourceValue = resourceValue.replace(END_SQUAREBRACKET_RC, " ]");
\r
361 String[] vlantagNames = recipe.split(",");
\r
363 for (String vlantagName : vlantagNames) {
\r
364 for (ResourceResponse rr : rl) {
\r
365 if (vlantagName.trim().equalsIgnoreCase(rr.endPointPosition)) {
\r
366 resourceValue = resourceValue.replace(vlantagName, " " + rr.resourceAllocated);
\r
372 log.info(resourceValue);
\r
374 return resourceValue;
\r
377 private void rollbackVlanTags(List<AssignVlanTagRequestInput> reservedResources) throws Exception {
\r
378 UnassignVlanTagRequest unassignRequest = new UnassignVlanTagRequest();
\r
379 List<UnassignVlanTagRequestInput> inputList = new ArrayList<>();
\r
381 if (reservedResources != null && !reservedResources.isEmpty()) {
\r
382 reservedResources.forEach(assignReqInput -> {
\r
384 UnassignVlanTagRequestInput input = new UnassignVlanTagRequestInput();
\r
385 input.setVlanType(assignReqInput.getVlanType());
\r
386 input.setVlanTagKey(assignReqInput.getVlanTagKey());
\r
387 input.setPolicyInstanceName(assignReqInput.getPolicyInstanceName());
\r
388 inputList.add(input);
\r
390 unassignRequest.setInput(inputList);
\r
391 unassignVlanTag(unassignRequest);
\r
397 * This is a unassignVlanTag service implementation to unassign Vlantags based on the
\r
398 * UnassignVlanTagRequest and Policy instance.
\r
400 * @param UnassignVlanTagRequest
\r
401 * @return UnassignVlanTagResponse
\r
404 public UnassignVlanTagResponse unassignVlanTag(UnassignVlanTagRequest request) throws Exception {
\r
405 UnassignVlanTagResponse response = new UnassignVlanTagResponse();
\r
406 List<UnassignVlanTagResponseOutput> output = new ArrayList<>();
\r
409 validateRequest(request);
\r
410 List<UnassignVlanTagRequestInput> vlanTagRequests = request.getInput();
\r
412 for (UnassignVlanTagRequestInput input : vlanTagRequests) {
\r
413 List<ResourceModel> resourceModels = policyClient.getPolicy(input.getPolicyInstanceName());
\r
414 ResourceModel model = validate(resourceModels, input);
\r
416 for (Elements elements : model.getElements()) {
\r
418 ResourceEntity re = new ResourceEntity();
\r
419 re.resourceEntityId = input.getVlanTagKey();
\r
420 re.resourceEntityType = model.getKeyType() == null ? "DEFAULT" : model.getKeyType();
\r
421 re.resourceEntityVersion = "1";
\r
423 ResourceRequest rr = new ResourceRequest();
\r
424 rr.endPointPosition = elements.getVlantagName();
\r
426 if (resourceAllocator != null) {
\r
427 AllocationStatus status = resourceAllocator.release(re, rr);
\r
429 if (AllocationStatus.Success.equals(status)) {
\r
430 UnassignVlanTagResponseOutput ro = new UnassignVlanTagResponseOutput();
\r
431 ro.setVlanTagKey(input.getVlanTagKey());
\r
432 ro.setVlanType(input.getVlanType());
\r
433 ro.setVlantagName(elements.getVlantagName());
\r
436 throw new VlantagApiException(
\r
437 "Failed to release VlanTags for Element : " + elements.getVlantagName() + ".");
\r
440 throw new VlantagApiException(
\r
441 "ResourceAllocator not available. Failed to Unassign VlanTags for Element : "
\r
442 + elements.getVlantagName()
\r
443 + ". Rolling back vlantags for other elements (if any).");
\r
446 } catch (Exception e) {
\r
447 log.error("Exception : " + e.getMessage(), e);
\r
449 response.setErrorCode(500);
\r
450 response.setErrorMessage(e.getMessage());
\r
454 response.setOutput(output);
\r
455 response.setErrorCode(200);
\r
456 response.setErrorMessage("Success");
\r
460 ResourceModel validate(List<ResourceModel> resourceModels, UnassignVlanTagRequestInput input)
\r
461 throws VlantagApiException {
\r
462 ResourceModel targetModel = null;
\r
463 if (resourceModels != null && !resourceModels.isEmpty()) {
\r
464 for (ResourceModel model : resourceModels) {
\r
465 if (model.getVlanType().equals(input.getVlanType())) {
\r
466 targetModel = model;
\r
470 validateModel(targetModel, input);
\r
472 throw new VlantagApiException("No Resource Models available in Policy Manager for Policy Instance Name : "
\r
473 + input.getPolicyInstanceName());
\r
474 return targetModel;
\r
477 void validateModel(ResourceModel model, UnassignVlanTagRequestInput input) throws VlantagApiException {
\r
479 throw new VlantagApiException(
\r
480 "No Matching Policy Resource Model found for Vlan Type : " + input.getVlanType());
\r
482 if (model.getResourceResolutionRecipe() == null || model.getResourceResolutionRecipe().isEmpty())
\r
483 throw new VlantagApiException(
\r
484 "Resource Resolution Recipe is null in Resource Model for Vlan Type : " + input.getVlanType());
\r
486 if (model.getScope() == null || model.getScope().isEmpty())
\r
487 throw new VlantagApiException("Scope is null in Resource Model for Vlan Type : " + input.getVlanType());
\r
489 List<Elements> elements = model.getElements();
\r
490 validateElements(elements, input);
\r
495 protected void validateElements(List<Elements> elements, UnassignVlanTagRequestInput input)
\r
496 throws VlantagApiException {
\r
497 if (elements != null && !elements.isEmpty()) {
\r
498 for (Elements element : elements) {
\r
499 if (element.getVlantagName() == null)
\r
500 throw new VlantagApiException(
\r
501 "Vlantag Name missing for Element in Resource Model Policy for Vlan Type : "
\r
502 + input.getVlanType());
\r
505 throw new VlantagApiException(
\r
506 "No Vlantag Elements found in Resource Model Policy for Vlan Type : " + input.getVlanType());
\r
510 protected void validateRequest(UnassignVlanTagRequest request) throws VlantagApiException {
\r
511 if (request == null)
\r
512 throw new VlantagApiException("VlanTag Unassign Request is null.");
\r
514 List<UnassignVlanTagRequestInput> inputList = request.getInput();
\r
515 if (inputList == null || inputList.isEmpty())
\r
516 throw new VlantagApiException("VlanTag Unassign Request Input is null or empty.");
\r
518 for (UnassignVlanTagRequestInput input : inputList) {
\r
519 if (input.getPolicyInstanceName() == null || input.getPolicyInstanceName().isEmpty())
\r
520 throw new VlantagApiException("VlanTag Unassign Request policy-instance-name is null.");
\r
522 if (input.getVlanType() == null || input.getVlanType().isEmpty())
\r
523 throw new VlantagApiException("VlanTag Unassign Request resource-name is null.");
\r
525 if (input.getVlanTagKey() == null || input.getVlanTagKey().isEmpty())
\r
526 throw new VlantagApiException("VlanTag Unassign Request key is null.");
\r
532 * This is a ping service implementation to check the Vlantag Api is Up and running.
\r
535 * @return PingResponse
\r
538 public PingResponse getPing(String name) {
\r
539 PingResponse ping = new PingResponse();
\r
540 ping.setMessage("Ping response : " + name + " Time : " + new Date());
\r
545 protected void setResourceAllocator(ResourceAllocator ra) {
\r
546 this.resourceAllocator = ra;
\r
549 protected String trimBrackets(String recipe) {
\r
550 if (recipe != null) {
\r
551 if (recipe.contains(BEGIN_SQUAREBRACKET_RC))
\r
552 recipe = recipe.replace(BEGIN_SQUAREBRACKET_RC, "");
\r
553 if (recipe.contains(END_SQUAREBRACKET_RC))
\r
554 recipe = recipe.replace(END_SQUAREBRACKET_RC, "");
\r
555 if (recipe.contains("["))
\r
556 recipe = recipe.replace("[", "");
\r
557 if (recipe.contains("]"))
\r
558 recipe = recipe.replace("]", "");
\r