84012c0d364df9316b86f7b815eeb6a8ec1cbece
[policy/engine.git] / ECOMP-PDP / src / test / java / org / openecomp / policy / pdp / test / conformance / ConformancePIPEngine.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP-PDP
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.openecomp.policy.pdp.test.conformance;
22
23 import java.io.BufferedReader;
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.io.InputStreamReader;
29 import java.text.ParseException;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Properties;
38
39 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
40 import org.openecomp.policy.common.logging.flexlogger.Logger;
41
42 import com.att.research.xacml.api.Attribute;
43 import com.att.research.xacml.api.AttributeValue;
44 import com.att.research.xacml.api.DataType;
45 import com.att.research.xacml.api.DataTypeException;
46 import com.att.research.xacml.api.DataTypeFactory;
47 import com.att.research.xacml.api.Identifier;
48 import com.att.research.xacml.api.pip.PIPException;
49 import com.att.research.xacml.api.pip.PIPFinder;
50 import com.att.research.xacml.api.pip.PIPRequest;
51 import com.att.research.xacml.api.pip.PIPResponse;
52 import com.att.research.xacml.std.IdentifierImpl;
53 import com.att.research.xacml.std.StdMutableAttribute;
54 import com.att.research.xacml.std.pip.StdPIPResponse;
55 import com.att.research.xacml.std.pip.engines.ConfigurableEngine;
56 import com.att.research.xacml.util.FactoryException; 
57
58 /**
59  * ConformancePIPEngine implements the {@link com.att.research.xacml.api.pip.PIPFinder} interface to find attributes
60  * loaded from a text file containing the following fields:
61  *      category-id,attribute-id,datatype-id,issuer,value
62  * 
63  * @version $Revision: 1.1 $
64  */
65 public class ConformancePIPEngine implements ConfigurableEngine {
66         public static final String PROP_DESCRIPTION     = ".description";
67         public static final String PROP_FILE            = ".file";
68         
69         private static final Logger logger      = FlexLogger.getLogger(ConformancePIPEngine.class);
70         
71         private String name;
72         private String description;
73         private Map<String,PIPResponse> cache   = new HashMap<String,PIPResponse>();
74         private List<Attribute> listAttributes  = new ArrayList<Attribute>();
75         private DataTypeFactory dataTypeFactory;
76         
77         public ConformancePIPEngine() {
78                 
79         }
80         
81         protected DataTypeFactory getDataTypeFactory() throws FactoryException {
82                 if (this.dataTypeFactory == null) {
83                         this.dataTypeFactory    = DataTypeFactory.newInstance();
84                 }
85                 return this.dataTypeFactory;
86         }
87         
88         protected static String generateKey(PIPRequest pipRequest) {
89                 StringBuilder stringBuilder     = new StringBuilder(pipRequest.getCategory().toString());
90                 stringBuilder.append('+');
91                 stringBuilder.append(pipRequest.getAttributeId().toString());
92                 stringBuilder.append('+');
93                 stringBuilder.append(pipRequest.getDataTypeId().toString());
94                 String issuer   = pipRequest.getIssuer();
95                 if (issuer != null) {
96                         stringBuilder.append('+');
97                         stringBuilder.append(issuer);
98                 }
99                 return stringBuilder.toString();
100         }
101         
102         protected void store(String[] fields) throws FactoryException {
103                 DataTypeFactory thisDataTypeFactory     = this.getDataTypeFactory();
104                 Identifier identifierCategory           = new IdentifierImpl(fields[0]);
105                 Identifier identifierAttribute          = new IdentifierImpl(fields[1]);
106                 Identifier identifierDataType           = new IdentifierImpl(fields[2]);
107                 String issuer                                           = (fields.length == 5 ? fields[3] : null);
108                 String value                                            = fields[fields.length - 1];
109                 
110                 DataType<?> dataType                            = thisDataTypeFactory.getDataType(identifierDataType);
111                 if (dataType == null) {
112                         logger.error("Unknown data type " + identifierDataType.stringValue());
113                         return;
114                 }
115                 
116                 AttributeValue<?> attributeValue        = null;
117                 try {
118                         attributeValue  = dataType.createAttributeValue(value);
119                 } catch (DataTypeException ex) {
120                         throw new FactoryException("DataTypeException creating AttributeValue", ex);
121                 }
122                 Attribute attribute                                     = new StdMutableAttribute(identifierCategory, identifierAttribute, attributeValue, issuer, false);
123                 this.listAttributes.add(attribute);
124         }
125         
126         public void loadAttributes(File fileAttributes) throws IOException, ParseException, FactoryException {
127                 if (fileAttributes != null) {
128                         if (!fileAttributes.exists()) {
129                                 throw new FileNotFoundException("Attributes file " + fileAttributes.getAbsolutePath() + " not found.");
130                         } else if (!fileAttributes.canRead()) {
131                                 throw new IOException("Attributes file " + fileAttributes.getAbsolutePath() + " is not readable.");
132                         }
133                         
134                         BufferedReader bufferedReader   = null;
135                         try {
136                                 bufferedReader  = new BufferedReader(new InputStreamReader(new FileInputStream(fileAttributes)));
137                                 String line;
138                                 while ((line = bufferedReader.readLine()) != null) {
139                                         if (line.length() > 0) {
140                                                 String[] fields = line.split("[|]",-1);
141                                                 if (fields.length < 4) {
142                                                         logger.warn("Not enough fields in record \"" + line + "\"");
143                                                         continue;
144                                                 }
145                                                 this.store(fields);
146                                                 
147                                         }
148                                 }
149                         } finally {
150                                 if (bufferedReader != null) {
151                                         bufferedReader.close();
152                                 }
153                         }
154                 }
155         }
156         
157         protected Attribute findAttribute(PIPRequest pipRequest) {
158                 Attribute attributeResult                       = null;
159                 Iterator<Attribute> iterAttributes      = this.listAttributes.iterator();
160                 while ((attributeResult == null) && iterAttributes.hasNext()) {
161                         Attribute attributeTest = iterAttributes.next();
162                         if (pipRequest.getCategory().equals(attributeTest.getCategory()) &&
163                                 pipRequest.getAttributeId().equals(attributeTest.getAttributeId()) &&
164                                 (pipRequest.getIssuer() == null || pipRequest.getIssuer().equals(attributeTest.getIssuer()))) {
165                                 attributeResult = attributeTest;
166                         }
167                 }
168                 return attributeResult;
169         }
170
171         @Override
172         public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException {
173                 String pipRequestKey    = generateKey(pipRequest);
174                 PIPResponse pipResponse = this.cache.get(pipRequestKey);
175                 if (pipResponse != null) {
176                         return pipResponse;
177                 }
178                 Attribute attributeMatch        = this.findAttribute(pipRequest);
179                 if (attributeMatch == null) {
180                         return StdPIPResponse.PIP_RESPONSE_EMPTY;
181                 }
182                 /*
183                  * Iterate through the values and only return the ones that match the requested data type
184                  */
185                 List<AttributeValue<?>> matchingValues  = new ArrayList<AttributeValue<?>>();
186                 Iterator<AttributeValue<?>> iterAttributeValues = attributeMatch.getValues().iterator();
187                 while (iterAttributeValues.hasNext()) {
188                         AttributeValue<?> attributeValue        = iterAttributeValues.next();
189                         if (pipRequest.getDataTypeId().equals(attributeValue.getDataTypeId())) {
190                                 matchingValues.add(attributeValue);
191                         }
192                 }
193                 if (matchingValues.size() > 0) {
194                         Attribute attributeResponse     = new StdMutableAttribute(attributeMatch.getCategory(), attributeMatch.getAttributeId(), matchingValues, attributeMatch.getIssuer(), false);
195                         pipResponse                                     = new StdPIPResponse(attributeResponse);
196                         this.cache.put(pipRequestKey, pipResponse);
197                 }
198                 return pipResponse;
199         }
200
201         @Override
202         public String getName() {
203                 return this.name;
204         }
205
206         @Override
207         public String getDescription() {
208                 return this.description;
209         }
210
211         @Override
212         public void configure(String id, Properties properties) throws PIPException {
213                 this.name       = id;
214                 this.description        = properties.getProperty(id + PROP_DESCRIPTION);
215                 if (this.description == null) {
216                         this.description        = "PIPEngine for the Conformance tests that loads attributes from a CSV file";
217                 }
218                 String pipFile          = properties.getProperty(id + PROP_FILE);
219                 if (pipFile != null) {
220                         try {
221                                 this.loadAttributes(new File(pipFile));
222                         } catch (Exception ex) {
223                                 logger.error("Exception loading PIP file " + pipFile, ex);
224                                 throw new PIPException("Exception loading PIP file " + pipFile, ex);
225                         }
226                 }
227         }
228
229         @Override
230         public Collection<PIPRequest> attributesRequired() {
231                 return Collections.emptyList();
232         }
233
234         @Override
235         public Collection<PIPRequest> attributesProvided() {
236                 //
237                 // We could return everything in our list
238                 //
239                 return Collections.emptyList();
240         }
241
242 }