d34c4bd0b78fffd0a353bd66083f94344f0aad5e
[policy/engine.git] / ONAP-REST / src / main / java / org / onap / policy / rest / jpa / PIPConfiguration.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-REST
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
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.onap.policy.rest.jpa;
22
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;
31 import java.util.Map;
32 import java.util.Properties;
33 import java.util.Set;
34
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;
51
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;
57
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;
63
64
65 /**
66  * The persistent class for the PIPConfiguration database table.
67  * 
68  */
69 @Entity
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);
75
76     @Id
77     @GeneratedValue(strategy=GenerationType.AUTO)
78     @Column(name="id")
79     private int id;
80
81     @Column(name="DESCRIPTION", nullable=true, length=2048)
82     private String description;
83
84     @Column(name="NAME", nullable=false, length=255)
85     private String name;
86
87     @Column(name="CLASSNAME", nullable=false, length=2048)
88     private String classname;
89
90     @Column(name="ISSUER", nullable=true, length=1024)
91     private String issuer;
92
93     @Column(name="READ_ONLY", nullable=false)
94     private char readOnly = '0';
95
96     @Column(name="REQUIRES_RESOLVER", nullable=false)
97     private char requiresResolvers;
98
99     @Column(name="CREATED_BY", nullable=false, length=255)
100     private String createdBy = "guest";
101
102     @Temporal(TemporalType.TIMESTAMP)
103     @Column(name="CREATED_DATE", nullable=false, updatable=false)
104     private Date createdDate;
105
106     @Column(name="MODIFIED_BY", nullable=false, length=255)
107     private String modifiedBy = "guest";
108
109     @Temporal(TemporalType.TIMESTAMP)
110     @Column(name="MODIFIED_DATE", nullable=false)
111     private Date modifiedDate;
112
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<>();
116
117     //bi-directional many-to-one association to PIPType
118     @ManyToOne
119     @JoinColumn(name="TYPE")
120     private PIPType piptype;
121
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<>();
125
126     public PIPConfiguration() {
127         //An empty constructor
128     }
129
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));
140         }
141         for (PIPResolver resolver : config.pipresolvers) {
142             this.addPipresolver(new PIPResolver(resolver));
143         }
144     }
145
146     public PIPConfiguration(String id, Properties properties) throws PIPException {
147         this.readProperties(id, properties);
148     }
149
150     public PIPConfiguration(String id, Properties properties, String user) throws PIPException {
151         this.createdBy = user;
152         this.modifiedBy = user;
153         this.readProperties(id, properties);
154     }
155
156     @PrePersist
157     public void prePersist() {
158         Date date = new Date();
159         this.createdDate = date;
160         this.modifiedDate = date;
161     }
162
163     @PreUpdate
164     public void preUpdate() {
165         this.modifiedDate = new Date();
166     }
167
168     public int getId() {
169         return this.id;
170     }
171
172     public void setId(int id) {
173         this.id = id;
174     }
175
176     public String getDescription() {
177         return this.description;
178     }
179
180     public void setDescription(String description) {
181         this.description = description;
182     }
183
184     public String getName() {
185         return this.name;
186     }
187
188     public void setName(String name) {
189         this.name = name;
190     }
191
192     public String getClassname() {
193         return classname;
194     }
195
196     public void setClassname(String classname) {
197         this.classname = classname;
198     }
199
200     public String getIssuer() {
201         return issuer;
202     }
203
204     public void setIssuer(String issuer) {
205         this.issuer = issuer;
206     }
207
208     public char getReadOnly() {
209         return readOnly;
210     }
211
212     public void setReadOnly(char readOnly) {
213         this.readOnly = readOnly;
214     }
215
216     public char getRequiresResolvers() {
217         return requiresResolvers;
218     }
219
220     public void setRequiresResolvers(char requireResolvers) {
221         this.requiresResolvers = requireResolvers;
222     }
223
224     public Set<PIPConfigParam> getPipconfigParams() {
225         return this.pipconfigParams;
226     }
227
228     public void setPipconfigParams(Set<PIPConfigParam> pipconfigParams) {
229         this.pipconfigParams = pipconfigParams;
230     }
231
232     public PIPConfigParam addPipconfigParam(PIPConfigParam pipconfigParam) {
233         getPipconfigParams().add(pipconfigParam);
234         pipconfigParam.setPipconfiguration(this);
235
236         return pipconfigParam;
237     }
238
239     public PIPConfigParam removePipconfigParam(PIPConfigParam pipconfigParam) {
240         if (pipconfigParam == null) {
241             return pipconfigParam;
242         }
243         getPipconfigParams().remove(pipconfigParam);
244         pipconfigParam.setPipconfiguration(null);
245
246         return pipconfigParam;
247     }
248
249     @Transient
250     public void clearConfigParams() {
251         while (!this.pipconfigParams.isEmpty()) {
252             this.removePipconfigParam(this.pipconfigParams.iterator().next());
253         }
254     }
255
256     public PIPType getPiptype() {
257         return this.piptype;
258     }
259
260     public void setPiptype(PIPType piptype) {
261         this.piptype = piptype;
262     }
263
264     public Set<PIPResolver> getPipresolvers() {
265         return this.pipresolvers;
266     }
267
268     public void setPipresolvers(Set<PIPResolver> pipresolvers) {
269         this.pipresolvers = pipresolvers;
270     }
271
272     public PIPResolver addPipresolver(PIPResolver pipresolver) {
273         getPipresolvers().add(pipresolver);
274         pipresolver.setPipconfiguration(this);
275
276         return pipresolver;
277     }
278
279     public PIPResolver removePipresolver(PIPResolver pipresolver) {
280         getPipresolvers().remove(pipresolver);
281         pipresolver.setPipconfiguration(null);
282
283         return pipresolver;
284     }
285
286     public String getCreatedBy() {
287         return createdBy;
288     }
289
290     public void setCreatedBy(String createdBy) {
291         this.createdBy = createdBy;
292     }
293
294     public Date getCreatedDate() {
295         return createdDate;
296     }
297
298     public void setCreatedDate(Date createdDate) {
299         this.createdDate = createdDate;
300     }
301
302     public String getModifiedBy() {
303         return modifiedBy;
304     }
305
306     public void setModifiedBy(String modifiedBy) {
307         this.modifiedBy = modifiedBy;
308     }
309
310     public Date getModifiedDate() {
311         return modifiedDate;
312     }
313
314     public void setModifiedDate(Date modifiedDate) {
315         this.modifiedDate = modifiedDate;
316     }
317
318     @Transient
319     public boolean isReadOnly() {
320         return this.readOnly == '1';
321     }
322
323     @Transient
324     public void setReadOnly(boolean readOnly) {
325         if (readOnly) {
326             this.readOnly = '1';
327         } else {
328             this.readOnly = '0';
329         }
330     }
331
332     @Transient
333     public boolean requiresResolvers() {
334         return this.requiresResolvers == '1';
335     }
336
337     @Transient
338     public void setRequiresResolvers(boolean requires) {
339         if (requires) {
340             this.requiresResolvers = '1';
341         } else {
342             this.requiresResolvers = '0';
343         }
344     }
345
346     @Transient
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;
352         }
353         for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(engines)) {
354             PIPConfiguration configuration;
355             try {
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");
364             }
365         }
366
367         return configurations;
368     }
369
370     @Transient
371     protected   void            readProperties(String id, Properties properties) throws PIPException {
372         //
373         // Save the id if we don't have one already
374         //
375
376         if (this.id == 0) {
377             try {
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");
382             }
383         }
384         //
385         // Get its classname, this MUST exist.
386         //
387         this.classname = properties.getProperty(id + ".classname");
388         if (this.classname == null) {
389             throw new PIPException("PIP Engine defined without a classname");
390         }
391         //
392         // Go through each property
393         //
394         for (Object nme : properties.keySet()) {
395             if (!nme.toString().startsWith(id)) {
396                 continue;
397             }
398             if (nme.equals(id + ".classname")) {
399                 //
400                 // We already saved this
401                 //
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")) {
409                 //
410                 // It has resolvers, make sure this is set to true if
411                 // it has been already.
412                 //
413                 this.setRequiresResolvers(true);
414                 //
415                 // Parse the resolvers
416                 //
417                 Collection<PIPResolver> resolvers = PIPResolver.importResolvers(id + ".resolver",
418                                                                         properties.getProperty(nme.toString()),
419                                                                         properties,"super-admin"
420                                                                         );
421                 for (PIPResolver resolver : resolvers) {
422                     this.addPipresolver(resolver);
423                 }
424             } else if (nme.toString().startsWith(id + ".resolver")) {
425                 //
426                 // Ignore, the PIPResolver will parse these values
427                 //
428             } else {
429                 //
430                 // Config Parameter
431                 //
432                 this.addPipconfigParam(new PIPConfigParam(nme.toString().substring(id.length() + 1),
433                                                     properties.getProperty(nme.toString())));
434             }
435         }
436         //
437         // Make sure we have a name at least
438         //
439         if (this.name == null) {
440             this.name = id;
441         }
442     }
443
444
445     @Transient
446     public Map<String, String> getConfiguration(String name) {
447         String prefix;
448         if (name == null) {
449             prefix = Integer.toString(this.id);
450         } else {
451             prefix = name;
452         }
453         if (!prefix.endsWith(".")) {
454             prefix = prefix + ".";
455         }
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);
461         }
462         if (this.issuer != null) {
463             map.put(prefix + "issuer", this.issuer);
464         }
465
466         for (PIPConfigParam param : this.pipconfigParams) {
467             map.put(prefix + param.getParamName(), param.getParamValue());
468         }
469
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);
477             ids.add(idd);
478         }
479         if (!ids.isEmpty()) {
480             map.put(prefix + "resolvers", Joiner.on(',').join(ids));
481         }
482         return map;
483     }
484
485     @Transient
486     public Properties   generateProperties(String name) {
487         String prefix;
488         if (name == null) {
489             prefix = Integer.toString(this.id);
490         } else {
491             if (name.endsWith(".")) {
492                 prefix = name;
493             } else {
494                 prefix = name + ".";
495             }
496         }
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);
503         }
504         if (this.issuer != null && !this.issuer.isEmpty()) {
505             props.setProperty(prefix + "issuer", this.issuer);
506         }
507
508         for (PIPConfigParam param : this.pipconfigParams) {
509             props.setProperty(prefix + param.getParamName(), param.getParamValue());
510         }
511
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);
518             ids.add(idd);
519         }
520         if (!ids.isEmpty()) {
521             props.setProperty(prefix + "resolvers", Joiner.on(',').join(ids));
522         }
523         return props;
524     }
525
526     @Transient
527     @Override
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 + "]";
537     }
538 }