Fixed the Sonar technical debt.
[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 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() == false) {
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) == false) {
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(".") == false) {
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() == false) {
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 }