753daa2b0e7be4a9c0425f06f98f58ec7c22ae5f
[policy/xacml-pdp.git] / applications / common / src / main / java / org / onap / policy / pdp / xacml / application / common / std / StdOnapPip.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
4  * Modifications Copyright (C) 2020 Bell Canada. All rights reserved.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.pdp.xacml.application.common.std;
23
24 import com.att.research.xacml.api.Attribute;
25 import com.att.research.xacml.api.AttributeValue;
26 import com.att.research.xacml.api.DataTypeException;
27 import com.att.research.xacml.api.Identifier;
28 import com.att.research.xacml.api.XACML3;
29 import com.att.research.xacml.api.pip.PIPException;
30 import com.att.research.xacml.api.pip.PIPFinder;
31 import com.att.research.xacml.api.pip.PIPRequest;
32 import com.att.research.xacml.api.pip.PIPResponse;
33 import com.att.research.xacml.std.StdMutableAttribute;
34 import com.att.research.xacml.std.datatypes.DataTypes;
35 import com.att.research.xacml.std.pip.StdMutablePIPResponse;
36 import com.att.research.xacml.std.pip.StdPIPRequest;
37 import com.att.research.xacml.std.pip.engines.StdConfigurableEngine;
38 import java.math.BigInteger;
39 import java.util.Collection;
40 import java.util.Collections;
41 import java.util.Iterator;
42 import java.util.Properties;
43 import javax.persistence.EntityManager;
44 import javax.persistence.Persistence;
45 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49
50 public abstract class StdOnapPip extends StdConfigurableEngine {
51     protected static Logger logger = LoggerFactory.getLogger(StdOnapPip.class);
52
53     protected static final PIPRequest PIP_REQUEST_ACTOR   = new StdPIPRequest(
54             XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
55             ToscaDictionary.ID_RESOURCE_GUARD_ACTOR,
56             XACML3.ID_DATATYPE_STRING);
57
58     protected static final PIPRequest PIP_REQUEST_RECIPE  = new StdPIPRequest(
59             XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
60             ToscaDictionary.ID_RESOURCE_GUARD_RECIPE,
61             XACML3.ID_DATATYPE_STRING);
62
63     protected static final PIPRequest PIP_REQUEST_TARGET  = new StdPIPRequest(
64             XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
65             ToscaDictionary.ID_RESOURCE_GUARD_TARGETID,
66             XACML3.ID_DATATYPE_STRING);
67
68     protected Properties properties;
69     protected EntityManager em;
70     protected String issuer;
71     protected boolean shutdown = false;
72
73     public StdOnapPip() {
74         super();
75     }
76
77     @Override
78     public Collection<PIPRequest> attributesProvided() {
79         return Collections.emptyList();
80     }
81
82     @Override
83     public synchronized void configure(String id, Properties properties) throws PIPException {
84         //
85         // This most likely will never get called since configure is called
86         // upon startup.
87         //
88         if (this.shutdown) {
89             throw new PIPException("Engine is shutdown.");
90         }
91         super.configure(id, properties);
92         logger.info("Configuring historyDb PIP {}", properties);
93         this.properties = properties;
94         //
95         // Create our entity manager
96         //
97         em = null;
98         try {
99             //
100             // In case there are any overloaded properties for the JPA
101             //
102             Properties emProperties = new Properties();
103             emProperties.putAll(properties);
104
105             //
106             // Create the entity manager factory
107             //
108             em = Persistence.createEntityManagerFactory(
109                     properties.getProperty(this.issuer + ".persistenceunit"),
110                     emProperties).createEntityManager();
111         } catch (Exception e) {
112             logger.error("Persistence failed {} operations history db", e.getLocalizedMessage(), e);
113         }
114     }
115
116     @Override
117     public synchronized void shutdown() {
118         if (this.em != null) {
119             this.em.close();
120             this.em = null;
121         }
122         this.shutdown = true;
123     }
124
125     protected String getAttribute(PIPFinder pipFinder, PIPRequest pipRequest) {
126         //
127         // Get the actor value
128         //
129         PIPResponse pipResponse = this.getAttribute(pipRequest, pipFinder);
130         if (pipResponse == null) {
131             logger.error("Need actor attribute which is not found");
132             return null;
133         }
134         //
135         // Find the actor
136         //
137         return findFirstAttributeValue(pipResponse);
138     }
139
140     protected PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) {
141         PIPResponse pipResponse = null;
142         try {
143             pipResponse = pipFinder.getMatchingAttributes(pipRequest, this);
144             if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) {
145                 logger.info("get attribute error retrieving {}: {}", pipRequest.getAttributeId(),
146                                 pipResponse.getStatus());
147                 pipResponse = null;
148             }
149             if (pipResponse != null && pipResponse.getAttributes().isEmpty()) {
150                 logger.info("No value for {}", pipRequest.getAttributeId());
151                 pipResponse = null;
152             }
153         } catch (PIPException ex) {
154             logger.error("PIPException getting subject-id attribute", ex);
155         }
156         return pipResponse;
157     }
158
159     protected String findFirstAttributeValue(PIPResponse pipResponse) {
160         for (Attribute attribute: pipResponse.getAttributes()) {
161             Iterator<AttributeValue<String>> iterAttributeValues    = attribute.findValues(DataTypes.DT_STRING);
162             while (iterAttributeValues.hasNext()) {
163                 String value   = iterAttributeValues.next().getValue();
164                 if (value != null) {
165                     return value;
166                 }
167             }
168         }
169         return null;
170     }
171
172     protected void addIntegerAttribute(StdMutablePIPResponse stdPipResponse, Identifier category,
173             Identifier attributeId, int value, PIPRequest pipRequest) {
174         AttributeValue<BigInteger> attributeValue   = null;
175         try {
176             attributeValue  = makeInteger(value);
177         } catch (Exception e) {
178             logger.error("Failed to convert {} to integer", value, e);
179         }
180         if (attributeValue != null) {
181             stdPipResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue,
182                     pipRequest.getIssuer(), false));
183         }
184     }
185
186     protected void addLongAttribute(StdMutablePIPResponse stdPipResponse, Identifier category,
187             Identifier attributeId, long value, PIPRequest pipRequest) {
188         AttributeValue<BigInteger> attributeValue   = null;
189         try {
190             attributeValue  = makeLong(value);
191         } catch (Exception e) {
192             logger.error("Failed to convert {} to long", value, e);
193         }
194         if (attributeValue != null) {
195             stdPipResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue,
196                     pipRequest.getIssuer(), false));
197         }
198     }
199
200     protected void addStringAttribute(StdMutablePIPResponse stdPipResponse, Identifier category, Identifier attributeId,
201             String value, PIPRequest pipRequest) {
202         AttributeValue<String> attributeValue = null;
203         try {
204             attributeValue = makeString(value);
205         } catch (Exception ex) {
206             logger.error("Failed to convert {} to an AttributeValue<String>", value, ex);
207         }
208         if (attributeValue != null) {
209             stdPipResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue,
210                     pipRequest.getIssuer(), false));
211         }
212     }
213
214     // these may be overridden by junit tests
215
216     protected AttributeValue<BigInteger> makeInteger(int value) throws DataTypeException {
217         return DataTypes.DT_INTEGER.createAttributeValue(value);
218     }
219
220     protected AttributeValue<BigInteger> makeLong(long value) throws DataTypeException {
221         return DataTypes.DT_INTEGER.createAttributeValue(value);
222     }
223
224     protected AttributeValue<String> makeString(String value) throws DataTypeException {
225         return DataTypes.DT_STRING.createAttributeValue(value);
226     }
227
228 }