5d731552b38ba057740f1a543961b62291a139b2
[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         }
128         
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));
139                 }
140                 for (PIPResolver resolver : config.pipresolvers) {
141                         this.addPipresolver(new PIPResolver(resolver));
142                 }
143         }
144         
145         public PIPConfiguration(String id, Properties properties) throws PIPException {
146                 this.readProperties(id, properties);
147         }
148         
149         public PIPConfiguration(String id, Properties properties, String user) throws PIPException {
150                 this.createdBy = user;
151                 this.modifiedBy = user;
152                 this.readProperties(id, properties);
153         }
154
155         @PrePersist
156         public void     prePersist() {
157                 Date date = new Date();
158                 this.createdDate = date;
159                 this.modifiedDate = date;
160         }
161         
162         @PreUpdate
163         public void preUpdate() {
164                 this.modifiedDate = new Date();
165         }
166
167         public int getId() {
168                 return this.id;
169         }
170
171         public void setId(int id) {
172                 this.id = id;
173         }
174
175         public String getDescription() {
176                 return this.description;
177         }
178
179         public void setDescription(String description) {
180                 this.description = description;
181         }
182
183         public String getName() {
184                 return this.name;
185         }
186
187         public void setName(String name) {
188                 this.name = name;
189         }
190
191         public String getClassname() {
192                 return classname;
193         }
194
195         public void setClassname(String classname) {
196                 this.classname = classname;
197         }
198
199         public String getIssuer() {
200                 return issuer;
201         }
202
203         public void setIssuer(String issuer) {
204                 this.issuer = issuer;
205         }
206
207         public char getReadOnly() {
208                 return readOnly;
209         }
210
211         public void setReadOnly(char readOnly) {
212                 this.readOnly = readOnly;
213         }
214
215         public char getRequiresResolvers() {
216                 return requiresResolvers;
217         }
218
219         public void setRequiresResolvers(char requireResolvers) {
220                 this.requiresResolvers = requireResolvers;
221         }
222
223         public Set<PIPConfigParam> getPipconfigParams() {
224                 return this.pipconfigParams;
225         }
226
227         public void setPipconfigParams(Set<PIPConfigParam> pipconfigParams) {
228                 this.pipconfigParams = pipconfigParams;
229         }
230
231         public PIPConfigParam addPipconfigParam(PIPConfigParam pipconfigParam) {
232                 getPipconfigParams().add(pipconfigParam);
233                 pipconfigParam.setPipconfiguration(this);
234
235                 return pipconfigParam;
236         }
237
238         public PIPConfigParam removePipconfigParam(PIPConfigParam pipconfigParam) {
239                 if (pipconfigParam == null) {
240                         return pipconfigParam;
241                 }
242                 getPipconfigParams().remove(pipconfigParam);
243                 pipconfigParam.setPipconfiguration(null);
244
245                 return pipconfigParam;
246         }
247         
248         @Transient
249         public void clearConfigParams() {
250                 while (this.pipconfigParams.isEmpty() == false) {
251                         this.removePipconfigParam(this.pipconfigParams.iterator().next());
252                 }
253         }
254
255         public PIPType getPiptype() {
256                 return this.piptype;
257         }
258
259         public void setPiptype(PIPType piptype) {
260                 this.piptype = piptype;
261         }
262
263         public Set<PIPResolver> getPipresolvers() {
264                 return this.pipresolvers;
265         }
266
267         public void setPipresolvers(Set<PIPResolver> pipresolvers) {
268                 this.pipresolvers = pipresolvers;
269         }
270
271         public PIPResolver addPipresolver(PIPResolver pipresolver) {
272                 getPipresolvers().add(pipresolver);
273                 pipresolver.setPipconfiguration(this);
274
275                 return pipresolver;
276         }
277
278         public PIPResolver removePipresolver(PIPResolver pipresolver) {
279                 getPipresolvers().remove(pipresolver);
280                 pipresolver.setPipconfiguration(null);
281
282                 return pipresolver;
283         }
284
285         public String getCreatedBy() {
286                 return createdBy;
287         }
288
289         public void setCreatedBy(String createdBy) {
290                 this.createdBy = createdBy;
291         }
292
293         public Date getCreatedDate() {
294                 return createdDate;
295         }
296
297         public void setCreatedDate(Date createdDate) {
298                 this.createdDate = createdDate;
299         }
300
301         public String getModifiedBy() {
302                 return modifiedBy;
303         }
304
305         public void setModifiedBy(String modifiedBy) {
306                 this.modifiedBy = modifiedBy;
307         }
308
309         public Date getModifiedDate() {
310                 return modifiedDate;
311         }
312
313         public void setModifiedDate(Date modifiedDate) {
314                 this.modifiedDate = modifiedDate;
315         }
316
317         @Transient
318         public boolean isReadOnly() {
319                 return (this.readOnly == '1');
320         }
321         
322         @Transient
323         public void setReadOnly(boolean readOnly) {
324                 if (readOnly) {
325                         this.readOnly = '1';
326                 } else {
327                         this.readOnly = '0';
328                 }
329         }
330         
331         @Transient
332         public boolean requiresResolvers() {
333                 return (this.requiresResolvers == '1');
334         }
335         
336         @Transient
337         public void     setRequiresResolvers(boolean requires) {
338                 if (requires) {
339                         this.requiresResolvers = '1';
340                 } else {
341                         this.requiresResolvers = '0';
342                 }
343         }
344         
345         @Transient
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;
351                 }
352                 for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(engines)) {
353                         PIPConfiguration configuration;
354                         try {
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");
363                         }
364                 }
365                 
366                 return configurations;
367         }
368         
369         @Transient
370         protected       void            readProperties(String id, Properties properties) throws PIPException {
371                 //
372                 // Save the id if we don't have one already
373                 //
374                 
375                 if (this.id == 0) {
376                         try {
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");
381                         }
382                 }
383                 //
384                 // Get its classname, this MUST exist.
385                 //
386                 this.classname = properties.getProperty(id + ".classname");
387                 if (this.classname == null) {
388                         throw new PIPException("PIP Engine defined without a classname");
389                 }
390                 //
391                 // Go through each property
392                 //
393                 for (Object name : properties.keySet()) {
394                         if (name.toString().startsWith(id) == false) {
395                                 continue;
396                         }
397                         if (name.equals(id + ".classname")) {
398                                 //
399                                 // We already saved this
400                                 //
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")) {
408                                 //
409                                 // It has resolvers, make sure this is set to true if
410                                 // it has been already.
411                                 //
412                                 this.setRequiresResolvers(true);
413                                 //
414                                 // Parse the resolvers
415                                 //
416                                 Collection<PIPResolver> resolvers = PIPResolver.importResolvers(id + ".resolver",
417                                                                                                                                                 properties.getProperty(name.toString()),
418                                                                                                                                                 properties,"super-admin"
419                                                                                                                                                 );
420                                 for (PIPResolver resolver : resolvers) {
421                                         this.addPipresolver(resolver);
422                                 }
423                         } else if (name.toString().startsWith(id + ".resolver")) {
424                                 //
425                                 // Ignore, the PIPResolver will parse these values
426                                 //
427                         } else {
428                                 //
429                                 // Config Parameter
430                                 //
431                                 this.addPipconfigParam(new PIPConfigParam(name.toString().substring(id.length() + 1), 
432                                                                                                         properties.getProperty(name.toString())));
433                         }
434                 }
435                 //
436                 // Make sure we have a name at least
437                 //
438                 if (this.name == null) {
439                         this.name = id;
440                 }
441         }
442         
443
444         @Transient
445         public Map<String, String> getConfiguration(String name) {
446                 String prefix;
447                 if (name == null) {
448                         prefix = Integer.toString(this.id);
449                 } else {
450                         prefix = name;
451                 }
452                 if (prefix.endsWith(".") == false) {
453                         prefix = prefix + ".";
454                 }
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);
460                 }
461                 if (this.issuer != null) {
462                         map.put(prefix + "issuer", this.issuer);
463                 }
464                 
465                 for (PIPConfigParam param : this.pipconfigParams) {
466                         map.put(prefix + param.getParamName(), param.getParamValue());
467                 }
468                 
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);
476                         ids.add(id);
477                 }
478                 if (ids.size() > 0) {
479                         map.put(prefix + "resolvers", Joiner.on(',').join(ids));
480                 }
481                 return map;
482         }
483         
484         @Transient
485         public Properties       generateProperties(String name) {
486                 String prefix;
487                 if (name == null) {
488                         prefix = Integer.toString(this.id);
489                 } else {
490                         if (name.endsWith(".")) {
491                                 prefix = name;
492                         } else {
493                                 prefix = name + ".";
494                         }
495                 }
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);
502                 }
503                 if (this.issuer != null && this.issuer.isEmpty() == false) {
504                         props.setProperty(prefix + "issuer", this.issuer);
505                 }
506                 
507                 for (PIPConfigParam param : this.pipconfigParams) {
508                         props.setProperty(prefix + param.getParamName(), param.getParamValue());
509                 }
510                 
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);
517                         ids.add(id);
518                 }
519                 if (ids.size() > 0) {
520                         props.setProperty(prefix + "resolvers", Joiner.on(',').join(ids));
521                 }
522                 return props;
523         }
524
525         @Transient
526         @Override
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 + "]";
536         }
537 }