2 * Copyright © 2017-2018 AT&T Intellectual Property.
\r
3 * Modifications Copyright © 2018 IBM.
\r
5 * Licensed under the Apache License, Version 2.0 (the "License");
\r
6 * you may not use this file except in compliance with the License.
\r
7 * You may obtain a copy of the License at
\r
9 * http://www.apache.org/licenses/LICENSE-2.0
\r
11 * Unless required by applicable law or agreed to in writing, software
\r
12 * distributed under the License is distributed on an "AS IS" BASIS,
\r
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
14 * See the License for the specific language governing permissions and
\r
15 * limitations under the License.
\r
18 package org.onap.ccsdk.config.assignment.processor;
\r
20 import java.util.HashMap;
\r
21 import java.util.List;
\r
22 import java.util.Map;
\r
23 import org.apache.commons.collections.CollectionUtils;
\r
24 import org.apache.commons.collections.MapUtils;
\r
25 import org.apache.commons.lang3.StringUtils;
\r
26 import org.onap.ccsdk.config.assignment.service.ConfigAssignmentUtils;
\r
27 import org.onap.ccsdk.config.model.ConfigModelConstant;
\r
28 import org.onap.ccsdk.config.model.ConfigModelException;
\r
29 import org.onap.ccsdk.config.model.data.ResourceAssignment;
\r
30 import org.onap.ccsdk.config.model.data.dict.ResourceDefinition;
\r
31 import org.onap.ccsdk.config.model.data.dict.SourcesDefinition;
\r
32 import org.onap.ccsdk.config.model.service.ComponentNode;
\r
33 import org.onap.ccsdk.config.model.utils.ResourceAssignmentUtils;
\r
34 import org.onap.ccsdk.config.model.utils.TransformationUtils;
\r
35 import org.onap.ccsdk.config.rest.adaptor.ConfigRestAdaptorConstants;
\r
36 import org.onap.ccsdk.config.rest.adaptor.service.ConfigRestAdaptorService;
\r
37 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
\r
38 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
\r
39 import com.att.eelf.configuration.EELFLogger;
\r
40 import com.att.eelf.configuration.EELFManager;
\r
41 import com.fasterxml.jackson.databind.JsonNode;
\r
43 public class MdsalResourceProcessor implements ComponentNode {
\r
45 private static EELFLogger logger = EELFManager.getInstance().getLogger(MdsalResourceProcessor.class);
\r
46 private ConfigRestAdaptorService configRestAdaptorService;
\r
47 private Map<String, ResourceDefinition> dictionaries;
\r
49 public MdsalResourceProcessor(ConfigRestAdaptorService configRestAdaptorService) {
\r
50 this.configRestAdaptorService = configRestAdaptorService;
\r
54 public Boolean preCondition(Map<String, String> inParams, SvcLogicContext ctx, Map<String, Object> componentContext)
\r
55 throws SvcLogicException {
\r
56 return Boolean.TRUE;
\r
60 public void preProcess(Map<String, String> inParams, SvcLogicContext ctx, Map<String, Object> componentContext)
\r
61 throws SvcLogicException {
\r
62 // Auto-generated method stub
\r
66 public void process(Map<String, String> inParams, SvcLogicContext ctx) throws SvcLogicException {
\r
67 // Auto-generated method stub
\r
70 @SuppressWarnings("unchecked")
\r
72 public void process(Map<String, String> inParams, SvcLogicContext ctx, Map<String, Object> componentContext)
\r
73 throws SvcLogicException {
\r
75 List<ResourceAssignment> batchResourceAssignment =
\r
76 (List<ResourceAssignment>) componentContext.get(ConfigModelConstant.PROPERTY_RESOURCE_ASSIGNMENTS);
\r
78 (Map<String, ResourceDefinition>) componentContext.get(ConfigModelConstant.PROPERTY_DICTIONARIES);
\r
80 if (CollectionUtils.isNotEmpty(batchResourceAssignment)) {
\r
81 for (ResourceAssignment resourceAssignment : batchResourceAssignment) {
\r
82 processResourceAssignmnet(ctx, componentContext, resourceAssignment);
\r
85 } catch (Exception e) {
\r
86 throw new SvcLogicException(String.format("MdsalResourceProcessor Exception : (%s) ", e), e);
\r
90 private void processResourceAssignmnet(SvcLogicContext ctx, Map<String, Object> componentContext,
\r
91 ResourceAssignment resourceAssignment) throws ConfigModelException, SvcLogicException {
\r
94 // Validating Resource Assignment and Dictionary Definition data
\r
95 validate(resourceAssignment);
\r
97 // Check if It has Input
\r
98 Object value = ConfigAssignmentUtils.getContextKeyValue(ctx, resourceAssignment.getName());
\r
99 if (value != null) {
\r
100 logger.info("mdsal source template key ({}) found from input and value is ({})",
\r
101 resourceAssignment.getName(), value);
\r
102 ResourceAssignmentUtils.setResourceDataValue(componentContext, resourceAssignment, value);
\r
106 ResourceDefinition resourceDefinition = dictionaries.get(resourceAssignment.getDictionaryName());
\r
107 SourcesDefinition sourceMdsal = resourceDefinition.getSources().get("mdsal");
\r
108 String urlPath = sourceMdsal.getProperties().getUrlPath();
\r
109 String path = sourceMdsal.getProperties().getPath();
\r
110 Map<String, String> inputKeyMapping = sourceMdsal.getProperties().getInputKeyMapping();
\r
111 Map<String, String> outputKeyMapping = sourceMdsal.getProperties().getOutputKeyMapping();
\r
114 "mdsal dictionary information : urlpath ({}), path({}), inputKeyMapping ({}), outputKeyMapping ({})",
\r
115 urlPath, path, inputKeyMapping, outputKeyMapping);
\r
117 // Resolving url Variables
\r
118 Map<String, Object> urlVariables = populateUrlVariables(inputKeyMapping, componentContext);
\r
119 for (Map.Entry<String, Object> entry : urlVariables.entrySet()) {
\r
120 urlPath = urlPath.replaceAll("\\$" + entry.getKey(), entry.getValue().toString());
\r
123 String restResponse = fetchResourceFromMDSAL(urlPath);
\r
124 // if restResponse is null don't call processMdsalResults to populate the value
\r
125 if (StringUtils.isNotBlank(restResponse)) {
\r
126 // Processing MDSAL Response
\r
127 processMdsalResults(ctx, componentContext, resourceAssignment, sourceMdsal, restResponse);
\r
129 logger.warn("Coudn't get proper mdsal Response content ({}) for Resource Name ({}) for URI ({})",
\r
130 restResponse, resourceAssignment.getDictionaryName(), urlPath);
\r
133 // Check the value has populated for mandatory case
\r
134 ResourceAssignmentUtils.assertTemplateKeyValueNotNull(componentContext, resourceAssignment);
\r
135 } catch (Exception e) {
\r
136 ResourceAssignmentUtils.setFailedResourceDataValue(componentContext, resourceAssignment, e.getMessage());
\r
137 throw new SvcLogicException(
\r
138 String.format("Failed in assignments for (%s) with (%s)", resourceAssignment, e), e);
\r
142 private String fetchResourceFromMDSAL(String urlPath) {
\r
143 String response = null;
\r
145 response = configRestAdaptorService.getResource(ConfigRestAdaptorConstants.SELECTOR_RESTCONF, urlPath,
\r
147 } catch (Exception e) {
\r
148 logger.warn("Fetching MDSAL data for URL ({}) failed with Error ({})", urlPath, e);
\r
153 private void validate(ResourceAssignment resourceAssignment) throws SvcLogicException {
\r
154 if (resourceAssignment == null) {
\r
155 throw new SvcLogicException("resource assignment is not defined");
\r
158 if (StringUtils.isBlank(resourceAssignment.getName())) {
\r
159 throw new SvcLogicException("resource assignment template key is not defined");
\r
162 if (StringUtils.isBlank(resourceAssignment.getDictionaryName())) {
\r
163 throw new SvcLogicException(
\r
164 String.format("resource assignment dictionary name is not defined for template key (%s)",
\r
165 resourceAssignment.getName()));
\r
168 if (!ConfigModelConstant.SOURCE_MDSAL.equalsIgnoreCase(resourceAssignment.getDictionarySource())) {
\r
169 throw new SvcLogicException(String.format("resource assignment source is not mdsal, it is (%s)",
\r
170 resourceAssignment.getDictionarySource()));
\r
173 ResourceDefinition resourceDefinition = dictionaries.get(resourceAssignment.getDictionaryName());
\r
174 if (resourceDefinition == null) {
\r
175 throw new SvcLogicException(String.format("missing resource dictionary definition for name (%s) ",
\r
176 resourceAssignment.getDictionaryName()));
\r
179 if (StringUtils.isBlank(resourceDefinition.getProperty().getType())) {
\r
180 throw new SvcLogicException(String.format(String.format("Failed to get dictionary (%s) data type info.",
\r
181 resourceAssignment.getDictionaryName())));
\r
184 if (resourceDefinition.getSources() == null || resourceDefinition.getSources().get("mdsal") == null) {
\r
185 throw new SvcLogicException(
\r
186 String.format("missing resource dictionary mdsal source definition for name (%s) ",
\r
187 resourceAssignment.getDictionaryName()));
\r
190 SourcesDefinition sourceMdsal = resourceDefinition.getSources().get("mdsal");
\r
191 if (StringUtils.isBlank(sourceMdsal.getProperties().getUrlPath())) {
\r
192 throw new SvcLogicException(String.format("Failed to get request URL Path for dictionary (%s)",
\r
193 resourceAssignment.getDictionaryName()));
\r
196 if (StringUtils.isBlank(sourceMdsal.getProperties().getPath())) {
\r
197 throw new SvcLogicException(String.format("Failed to get request Path for dictionary (%s)",
\r
198 resourceAssignment.getDictionaryName()));
\r
202 private Map<String, Object> populateUrlVariables(Map<String, String> inputKeyMapping,
\r
203 Map<String, Object> componentContext) {
\r
204 Map<String, Object> urlVariables = new HashMap<>();
\r
205 if (MapUtils.isNotEmpty(inputKeyMapping)) {
\r
207 for (Map.Entry<String, String> mapping : inputKeyMapping.entrySet()) {
\r
208 ResourceDefinition referenceDictionaryDefinition = dictionaries.get(mapping.getValue());
\r
209 Object expressionValue =
\r
210 ResourceAssignmentUtils.getDictionaryKeyValue(componentContext, referenceDictionaryDefinition);
\r
211 logger.trace("Reference dictionary key ({}), value ({})", mapping.getKey(), expressionValue);
\r
212 urlVariables.put(mapping.getKey(), expressionValue);
\r
215 return urlVariables;
\r
218 private void processMdsalResults(SvcLogicContext ctx, Map<String, Object> componentContext,
\r
219 ResourceAssignment resourceAssignment, SourcesDefinition sourceMdsal, String restResponse)
\r
220 throws SvcLogicException, ConfigModelException {
\r
222 Map<String, String> outputKeyMapping = sourceMdsal.getProperties().getOutputKeyMapping();
\r
223 JsonNode responseNode = TransformationUtils.getJsonNodeForString(restResponse);
\r
224 if (StringUtils.isNotBlank(sourceMdsal.getProperties().getPath())) {
\r
225 responseNode = responseNode.at(sourceMdsal.getProperties().getPath());
\r
227 if (responseNode != null) {
\r
228 ConfigAssignmentUtils.populateValueForOutputMapping(ctx, componentContext, resourceAssignment,
\r
229 outputKeyMapping, responseNode);
\r
234 public void postProcess(Map<String, String> inParams, SvcLogicContext ctx, Map<String, Object> componentContext)
\r
235 throws SvcLogicException {
\r