2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.rest.jpa;
23 import java.io.Serializable;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Date;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.List;
32 import java.util.Properties;
35 import javax.persistence.CascadeType;
36 import javax.persistence.Column;
37 import javax.persistence.Entity;
38 import javax.persistence.GeneratedValue;
39 import javax.persistence.GenerationType;
40 import javax.persistence.Id;
41 import javax.persistence.JoinColumn;
42 import javax.persistence.ManyToOne;
43 import javax.persistence.NamedQuery;
44 import javax.persistence.OneToMany;
45 import javax.persistence.PrePersist;
46 import javax.persistence.PreUpdate;
47 import javax.persistence.Table;
48 import javax.persistence.Temporal;
49 import javax.persistence.TemporalType;
50 import javax.persistence.Transient;
52 import org.apache.commons.logging.Log;
53 import org.apache.commons.logging.LogFactory;
54 import org.onap.policy.common.logging.eelf.MessageCodes;
55 import org.onap.policy.common.logging.eelf.PolicyLogger;
56 import org.onap.policy.xacml.api.XACMLErrorConstants;
58 import com.att.research.xacml.api.pip.PIPException;
59 import com.att.research.xacml.std.pip.engines.StdConfigurableEngine;
60 import com.att.research.xacml.util.XACMLProperties;
61 import com.google.common.base.Joiner;
62 import com.google.common.base.Splitter;
66 * The persistent class for the PIPConfiguration database table.
70 @Table(name="PIPConfiguration")
71 @NamedQuery(name="PIPConfiguration.findAll", query="SELECT p FROM PIPConfiguration p")
72 public class PIPConfiguration implements Serializable {
73 private static final long serialVersionUID = 1L;
74 private static final Log logger = LogFactory.getLog(PIPConfiguration.class);
77 @GeneratedValue(strategy=GenerationType.AUTO)
81 @Column(name="DESCRIPTION", nullable=true, length=2048)
82 private String description;
84 @Column(name="NAME", nullable=false, length=255)
87 @Column(name="CLASSNAME", nullable=false, length=2048)
88 private String classname;
90 @Column(name="ISSUER", nullable=true, length=1024)
91 private String issuer;
93 @Column(name="READ_ONLY", nullable=false)
94 private char readOnly = '0';
96 @Column(name="REQUIRES_RESOLVER", nullable=false)
97 private char requiresResolvers;
99 @Column(name="CREATED_BY", nullable=false, length=255)
100 private String createdBy = "guest";
102 @Temporal(TemporalType.TIMESTAMP)
103 @Column(name="CREATED_DATE", nullable=false, updatable=false)
104 private Date createdDate;
106 @Column(name="MODIFIED_BY", nullable=false, length=255)
107 private String modifiedBy = "guest";
109 @Temporal(TemporalType.TIMESTAMP)
110 @Column(name="MODIFIED_DATE", nullable=false)
111 private Date modifiedDate;
113 //bi-directional many-to-one association to PIPConfigParam
114 @OneToMany(mappedBy="pipconfiguration", orphanRemoval=true, cascade=CascadeType.REMOVE)
115 private Set<PIPConfigParam> pipconfigParams = new HashSet<>();
117 //bi-directional many-to-one association to PIPType
119 @JoinColumn(name="TYPE")
120 private PIPType piptype;
122 //bi-directional many-to-one association to PIPResolver
123 @OneToMany(mappedBy="pipconfiguration", orphanRemoval=true, cascade=CascadeType.REMOVE)
124 private Set<PIPResolver> pipresolvers = new HashSet<>();
126 public PIPConfiguration() {
129 public PIPConfiguration(PIPConfiguration config, String user) {
130 this.description = config.description;
131 this.name = config.name;
132 this.classname = config.classname;
133 this.issuer = config.issuer;
134 this.requiresResolvers = config.requiresResolvers;
135 this.readOnly = config.readOnly;
136 this.piptype = config.piptype;
137 for (PIPConfigParam param : config.pipconfigParams) {
138 this.addPipconfigParam(new PIPConfigParam(param));
140 for (PIPResolver resolver : config.pipresolvers) {
141 this.addPipresolver(new PIPResolver(resolver));
145 public PIPConfiguration(String id, Properties properties) throws PIPException {
146 this.readProperties(id, properties);
149 public PIPConfiguration(String id, Properties properties, String user) throws PIPException {
150 this.createdBy = user;
151 this.modifiedBy = user;
152 this.readProperties(id, properties);
156 public void prePersist() {
157 Date date = new Date();
158 this.createdDate = date;
159 this.modifiedDate = date;
163 public void preUpdate() {
164 this.modifiedDate = new Date();
171 public void setId(int id) {
175 public String getDescription() {
176 return this.description;
179 public void setDescription(String description) {
180 this.description = description;
183 public String getName() {
187 public void setName(String name) {
191 public String getClassname() {
195 public void setClassname(String classname) {
196 this.classname = classname;
199 public String getIssuer() {
203 public void setIssuer(String issuer) {
204 this.issuer = issuer;
207 public char getReadOnly() {
211 public void setReadOnly(char readOnly) {
212 this.readOnly = readOnly;
215 public char getRequiresResolvers() {
216 return requiresResolvers;
219 public void setRequiresResolvers(char requireResolvers) {
220 this.requiresResolvers = requireResolvers;
223 public Set<PIPConfigParam> getPipconfigParams() {
224 return this.pipconfigParams;
227 public void setPipconfigParams(Set<PIPConfigParam> pipconfigParams) {
228 this.pipconfigParams = pipconfigParams;
231 public PIPConfigParam addPipconfigParam(PIPConfigParam pipconfigParam) {
232 getPipconfigParams().add(pipconfigParam);
233 pipconfigParam.setPipconfiguration(this);
235 return pipconfigParam;
238 public PIPConfigParam removePipconfigParam(PIPConfigParam pipconfigParam) {
239 if (pipconfigParam == null) {
240 return pipconfigParam;
242 getPipconfigParams().remove(pipconfigParam);
243 pipconfigParam.setPipconfiguration(null);
245 return pipconfigParam;
249 public void clearConfigParams() {
250 while (this.pipconfigParams.isEmpty() == false) {
251 this.removePipconfigParam(this.pipconfigParams.iterator().next());
255 public PIPType getPiptype() {
259 public void setPiptype(PIPType piptype) {
260 this.piptype = piptype;
263 public Set<PIPResolver> getPipresolvers() {
264 return this.pipresolvers;
267 public void setPipresolvers(Set<PIPResolver> pipresolvers) {
268 this.pipresolvers = pipresolvers;
271 public PIPResolver addPipresolver(PIPResolver pipresolver) {
272 getPipresolvers().add(pipresolver);
273 pipresolver.setPipconfiguration(this);
278 public PIPResolver removePipresolver(PIPResolver pipresolver) {
279 getPipresolvers().remove(pipresolver);
280 pipresolver.setPipconfiguration(null);
285 public String getCreatedBy() {
289 public void setCreatedBy(String createdBy) {
290 this.createdBy = createdBy;
293 public Date getCreatedDate() {
297 public void setCreatedDate(Date createdDate) {
298 this.createdDate = createdDate;
301 public String getModifiedBy() {
305 public void setModifiedBy(String modifiedBy) {
306 this.modifiedBy = modifiedBy;
309 public Date getModifiedDate() {
313 public void setModifiedDate(Date modifiedDate) {
314 this.modifiedDate = modifiedDate;
318 public boolean isReadOnly() {
319 return (this.readOnly == '1');
323 public void setReadOnly(boolean readOnly) {
332 public boolean requiresResolvers() {
333 return (this.requiresResolvers == '1');
337 public void setRequiresResolvers(boolean requires) {
339 this.requiresResolvers = '1';
341 this.requiresResolvers = '0';
346 public static Collection<PIPConfiguration> importPIPConfigurations(Properties properties) {
347 Collection<PIPConfiguration> configurations = new ArrayList<>();
348 String engines = properties.getProperty(XACMLProperties.PROP_PIP_ENGINES);
349 if (engines == null || engines.isEmpty()) {
350 return configurations;
352 for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(engines)) {
353 PIPConfiguration configuration;
355 String user = "super-admin";
356 configuration = new PIPConfiguration(id, properties, user);
357 configuration.setCreatedBy(user);
358 configuration.setModifiedBy(user);
359 configurations.add(configuration);
360 } catch (PIPException e) {
361 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Import failed: " + e.getLocalizedMessage());
362 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PIPConfiguration", "Import failed");
366 return configurations;
370 protected void readProperties(String id, Properties properties) throws PIPException {
372 // Save the id if we don't have one already
377 this.id = Integer.parseInt(id);
378 } catch (NumberFormatException e) {
379 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Convert id to integer failed: " + id);
380 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PIPConfiguration", "Convert id to integer failed");
384 // Get its classname, this MUST exist.
386 this.classname = properties.getProperty(id + ".classname");
387 if (this.classname == null) {
388 throw new PIPException("PIP Engine defined without a classname");
391 // Go through each property
393 for (Object name : properties.keySet()) {
394 if (name.toString().startsWith(id) == false) {
397 if (name.equals(id + ".classname")) {
399 // We already saved this
401 } else if (name.equals(id + "." + StdConfigurableEngine.PROP_NAME)) {
402 this.name = properties.getProperty(name.toString());
403 } else if (name.equals(id + "." + StdConfigurableEngine.PROP_DESCRIPTION)) {
404 this.description = properties.getProperty(name.toString());
405 } else if (name.equals(id + "." + StdConfigurableEngine.PROP_ISSUER)) {
406 this.issuer = properties.getProperty(name.toString());
407 } else if (name.equals(id + ".resolvers")) {
409 // It has resolvers, make sure this is set to true if
410 // it has been already.
412 this.setRequiresResolvers(true);
414 // Parse the resolvers
416 Collection<PIPResolver> resolvers = PIPResolver.importResolvers(id + ".resolver",
417 properties.getProperty(name.toString()),
418 properties,"super-admin"
420 for (PIPResolver resolver : resolvers) {
421 this.addPipresolver(resolver);
423 } else if (name.toString().startsWith(id + ".resolver")) {
425 // Ignore, the PIPResolver will parse these values
431 this.addPipconfigParam(new PIPConfigParam(name.toString().substring(id.length() + 1),
432 properties.getProperty(name.toString())));
436 // Make sure we have a name at least
438 if (this.name == null) {
445 public Map<String, String> getConfiguration(String name) {
448 prefix = Integer.toString(this.id);
452 if (prefix.endsWith(".") == false) {
453 prefix = prefix + ".";
455 Map<String, String> map = new HashMap<>();
456 map.put(prefix + "classname", this.classname);
457 map.put(prefix + "name", this.name);
458 if (this.description != null) {
459 map.put(prefix + "description", this.description);
461 if (this.issuer != null) {
462 map.put(prefix + "issuer", this.issuer);
465 for (PIPConfigParam param : this.pipconfigParams) {
466 map.put(prefix + param.getParamName(), param.getParamValue());
469 List<String> ids = new ArrayList<>();
470 Iterator<PIPResolver> iter = this.pipresolvers.iterator();
471 while (iter.hasNext()) {
472 PIPResolver resolver = iter.next();
473 String id = Integer.toString(resolver.getId());
474 Map<String, String> resolverMap = resolver.getConfiguration(prefix + "resolver." + id);
475 map.putAll(resolverMap);
478 if (ids.size() > 0) {
479 map.put(prefix + "resolvers", Joiner.on(',').join(ids));
485 public Properties generateProperties(String name) {
488 prefix = Integer.toString(this.id);
490 if (name.endsWith(".")) {
496 Properties props = new Properties();
497 props.setProperty("xacml.pip.engines", name);
498 props.setProperty(prefix + "classname", this.classname);
499 props.setProperty(prefix + "name", this.name);
500 if (this.description != null) {
501 props.setProperty(prefix + "description", this.description);
503 if (this.issuer != null && this.issuer.isEmpty() == false) {
504 props.setProperty(prefix + "issuer", this.issuer);
507 for (PIPConfigParam param : this.pipconfigParams) {
508 props.setProperty(prefix + param.getParamName(), param.getParamValue());
511 List<String> ids = new ArrayList<>();
512 Iterator<PIPResolver> iter = this.pipresolvers.iterator();
513 while (iter.hasNext()) {
514 PIPResolver resolver = iter.next();
515 String id = Integer.toString(resolver.getId());
516 resolver.generateProperties(props, prefix + "resolver." + id);
519 if (ids.size() > 0) {
520 props.setProperty(prefix + "resolvers", Joiner.on(',').join(ids));
527 public String toString() {
528 return "PIPConfiguration [id=" + id + ", piptype=" + piptype
529 + ", classname=" + classname + ", name=" + name
530 + ", description=" + description + ", issuer=" + issuer
531 + ", readOnly=" + readOnly + ", requiresResolvers="
532 + requiresResolvers + ", createdBy=" + createdBy
533 + ", createdDate=" + createdDate + ", modifiedBy=" + modifiedBy
534 + ", modifiedDate=" + modifiedDate + ", pipconfigParams="
535 + pipconfigParams + ", pipresolvers=" + pipresolvers + "]";