2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 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() {
127 //An empty constructor
130 public PIPConfiguration(PIPConfiguration config, String user) {
131 this.description = config.description;
132 this.name = config.name;
133 this.classname = config.classname;
134 this.issuer = config.issuer;
135 this.requiresResolvers = config.requiresResolvers;
136 this.readOnly = config.readOnly;
137 this.piptype = config.piptype;
138 for (PIPConfigParam param : config.pipconfigParams) {
139 this.addPipconfigParam(new PIPConfigParam(param));
141 for (PIPResolver resolver : config.pipresolvers) {
142 this.addPipresolver(new PIPResolver(resolver));
146 public PIPConfiguration(String id, Properties properties) throws PIPException {
147 this.readProperties(id, properties);
150 public PIPConfiguration(String id, Properties properties, String user) throws PIPException {
151 this.createdBy = user;
152 this.modifiedBy = user;
153 this.readProperties(id, properties);
157 public void prePersist() {
158 Date date = new Date();
159 this.createdDate = date;
160 this.modifiedDate = date;
164 public void preUpdate() {
165 this.modifiedDate = new Date();
172 public void setId(int id) {
176 public String getDescription() {
177 return this.description;
180 public void setDescription(String description) {
181 this.description = description;
184 public String getName() {
188 public void setName(String name) {
192 public String getClassname() {
196 public void setClassname(String classname) {
197 this.classname = classname;
200 public String getIssuer() {
204 public void setIssuer(String issuer) {
205 this.issuer = issuer;
208 public char getReadOnly() {
212 public void setReadOnly(char readOnly) {
213 this.readOnly = readOnly;
216 public char getRequiresResolvers() {
217 return requiresResolvers;
220 public void setRequiresResolvers(char requireResolvers) {
221 this.requiresResolvers = requireResolvers;
224 public Set<PIPConfigParam> getPipconfigParams() {
225 return this.pipconfigParams;
228 public void setPipconfigParams(Set<PIPConfigParam> pipconfigParams) {
229 this.pipconfigParams = pipconfigParams;
232 public PIPConfigParam addPipconfigParam(PIPConfigParam pipconfigParam) {
233 getPipconfigParams().add(pipconfigParam);
234 pipconfigParam.setPipconfiguration(this);
236 return pipconfigParam;
239 public PIPConfigParam removePipconfigParam(PIPConfigParam pipconfigParam) {
240 if (pipconfigParam == null) {
241 return pipconfigParam;
243 getPipconfigParams().remove(pipconfigParam);
244 pipconfigParam.setPipconfiguration(null);
246 return pipconfigParam;
250 public void clearConfigParams() {
251 while (!this.pipconfigParams.isEmpty()) {
252 this.removePipconfigParam(this.pipconfigParams.iterator().next());
256 public PIPType getPiptype() {
260 public void setPiptype(PIPType piptype) {
261 this.piptype = piptype;
264 public Set<PIPResolver> getPipresolvers() {
265 return this.pipresolvers;
268 public void setPipresolvers(Set<PIPResolver> pipresolvers) {
269 this.pipresolvers = pipresolvers;
272 public PIPResolver addPipresolver(PIPResolver pipresolver) {
273 getPipresolvers().add(pipresolver);
274 pipresolver.setPipconfiguration(this);
279 public PIPResolver removePipresolver(PIPResolver pipresolver) {
280 getPipresolvers().remove(pipresolver);
281 pipresolver.setPipconfiguration(null);
286 public String getCreatedBy() {
290 public void setCreatedBy(String createdBy) {
291 this.createdBy = createdBy;
294 public Date getCreatedDate() {
298 public void setCreatedDate(Date createdDate) {
299 this.createdDate = createdDate;
302 public String getModifiedBy() {
306 public void setModifiedBy(String modifiedBy) {
307 this.modifiedBy = modifiedBy;
310 public Date getModifiedDate() {
314 public void setModifiedDate(Date modifiedDate) {
315 this.modifiedDate = modifiedDate;
319 public boolean isReadOnly() {
320 return this.readOnly == '1';
324 public void setReadOnly(boolean readOnly) {
333 public boolean requiresResolvers() {
334 return this.requiresResolvers == '1';
338 public void setRequiresResolvers(boolean requires) {
340 this.requiresResolvers = '1';
342 this.requiresResolvers = '0';
347 public static Collection<PIPConfiguration> importPIPConfigurations(Properties properties) {
348 Collection<PIPConfiguration> configurations = new ArrayList<>();
349 String engines = properties.getProperty(XACMLProperties.PROP_PIP_ENGINES);
350 if (engines == null || engines.isEmpty()) {
351 return configurations;
353 for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(engines)) {
354 PIPConfiguration configuration;
356 String user = "super-admin";
357 configuration = new PIPConfiguration(id, properties, user);
358 configuration.setCreatedBy(user);
359 configuration.setModifiedBy(user);
360 configurations.add(configuration);
361 } catch (PIPException e) {
362 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Import failed: " + e.getLocalizedMessage());
363 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PIPConfiguration", "Import failed");
367 return configurations;
371 protected void readProperties(String id, Properties properties) throws PIPException {
373 // Save the id if we don't have one already
378 this.id = Integer.parseInt(id);
379 } catch (NumberFormatException e) {
380 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Convert id to integer failed: " + id);
381 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PIPConfiguration", "Convert id to integer failed");
385 // Get its classname, this MUST exist.
387 this.classname = properties.getProperty(id + ".classname");
388 if (this.classname == null) {
389 throw new PIPException("PIP Engine defined without a classname");
392 // Go through each property
394 for (Object nme : properties.keySet()) {
395 if (!nme.toString().startsWith(id)) {
398 if (nme.equals(id + ".classname")) {
400 // We already saved this
402 } else if (nme.equals(id + "." + StdConfigurableEngine.PROP_NAME)) {
403 this.name = properties.getProperty(nme.toString());
404 } else if (nme.equals(id + "." + StdConfigurableEngine.PROP_DESCRIPTION)) {
405 this.description = properties.getProperty(nme.toString());
406 } else if (nme.equals(id + "." + StdConfigurableEngine.PROP_ISSUER)) {
407 this.issuer = properties.getProperty(nme.toString());
408 } else if (nme.equals(id + ".resolvers")) {
410 // It has resolvers, make sure this is set to true if
411 // it has been already.
413 this.setRequiresResolvers(true);
415 // Parse the resolvers
417 Collection<PIPResolver> resolvers = PIPResolver.importResolvers(id + ".resolver",
418 properties.getProperty(nme.toString()),
419 properties,"super-admin"
421 for (PIPResolver resolver : resolvers) {
422 this.addPipresolver(resolver);
424 } else if (nme.toString().startsWith(id + ".resolver")) {
426 // Ignore, the PIPResolver will parse these values
432 this.addPipconfigParam(new PIPConfigParam(nme.toString().substring(id.length() + 1),
433 properties.getProperty(nme.toString())));
437 // Make sure we have a name at least
439 if (this.name == null) {
446 public Map<String, String> getConfiguration(String name) {
449 prefix = Integer.toString(this.id);
453 if (!prefix.endsWith(".")) {
454 prefix = prefix + ".";
456 Map<String, String> map = new HashMap<>();
457 map.put(prefix + "classname", this.classname);
458 map.put(prefix + "name", this.name);
459 if (this.description != null) {
460 map.put(prefix + "description", this.description);
462 if (this.issuer != null) {
463 map.put(prefix + "issuer", this.issuer);
466 for (PIPConfigParam param : this.pipconfigParams) {
467 map.put(prefix + param.getParamName(), param.getParamValue());
470 List<String> ids = new ArrayList<>();
471 Iterator<PIPResolver> iter = this.pipresolvers.iterator();
472 while (iter.hasNext()) {
473 PIPResolver resolver = iter.next();
474 String idd = Integer.toString(resolver.getId());
475 Map<String, String> resolverMap = resolver.getConfiguration(prefix + "resolver." + idd);
476 map.putAll(resolverMap);
479 if (!ids.isEmpty()) {
480 map.put(prefix + "resolvers", Joiner.on(',').join(ids));
486 public Properties generateProperties(String name) {
489 prefix = Integer.toString(this.id);
491 if (name.endsWith(".")) {
497 Properties props = new Properties();
498 props.setProperty("xacml.pip.engines", name);
499 props.setProperty(prefix + "classname", this.classname);
500 props.setProperty(prefix + "name", this.name);
501 if (this.description != null) {
502 props.setProperty(prefix + "description", this.description);
504 if (this.issuer != null && !this.issuer.isEmpty()) {
505 props.setProperty(prefix + "issuer", this.issuer);
508 for (PIPConfigParam param : this.pipconfigParams) {
509 props.setProperty(prefix + param.getParamName(), param.getParamValue());
512 List<String> ids = new ArrayList<>();
513 Iterator<PIPResolver> iter = this.pipresolvers.iterator();
514 while (iter.hasNext()) {
515 PIPResolver resolver = iter.next();
516 String idd = Integer.toString(resolver.getId());
517 resolver.generateProperties(props, prefix + "resolver." + idd);
520 if (!ids.isEmpty()) {
521 props.setProperty(prefix + "resolvers", Joiner.on(',').join(ids));
528 public String toString() {
529 return "PIPConfiguration [id=" + id + ", piptype=" + piptype
530 + ", classname=" + classname + ", name=" + name
531 + ", description=" + description + ", issuer=" + issuer
532 + ", readOnly=" + readOnly + ", requiresResolvers="
533 + requiresResolvers + ", createdBy=" + createdBy
534 + ", createdDate=" + createdDate + ", modifiedBy=" + modifiedBy
535 + ", modifiedDate=" + modifiedDate + ", pipconfigParams="
536 + pipconfigParams + ", pipresolvers=" + pipresolvers + "]";