Initial OpenECOMP policy/engine commit
[policy/engine.git] / ECOMP-REST / src / main / java / org / openecomp / policy / rest / jpa / PIPConfiguration.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP-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.openecomp.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
55 import org.openecomp.policy.xacml.api.XACMLErrorConstants;
56 import com.att.research.xacml.api.pip.PIPException;
57 import com.att.research.xacml.std.pip.engines.StdConfigurableEngine;
58 import com.att.research.xacml.std.pip.engines.csv.CSVEngine;
59 import com.att.research.xacml.std.pip.engines.csv.HyperCSVEngine;
60 import com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine;
61 import com.att.research.xacml.std.pip.engines.ldap.LDAPEngine;
62 import com.att.research.xacml.util.XACMLProperties;
63 import com.google.common.base.Joiner;
64 import com.google.common.base.Splitter;
65
66 import org.openecomp.policy.common.logging.eelf.MessageCodes;
67 import org.openecomp.policy.common.logging.eelf.PolicyLogger;
68
69
70 /**
71  * The persistent class for the PIPConfiguration database table.
72  * 
73  */
74 @Entity
75 @Table(name="PIPConfiguration")
76 @NamedQuery(name="PIPConfiguration.findAll", query="SELECT p FROM PIPConfiguration p")
77 public class PIPConfiguration implements Serializable {
78         private static final long serialVersionUID = 1L;
79         private static final Log logger = LogFactory.getLog(PIPConfiguration.class);
80
81         @Id
82         @GeneratedValue(strategy=GenerationType.AUTO)
83         @Column(name="id")
84         private int id;
85
86         @Column(name="DESCRIPTION", nullable=true, length=2048)
87         private String description;
88
89         @Column(name="NAME", nullable=false, length=255)
90         private String name;
91
92         @Column(name="CLASSNAME", nullable=false, length=2048)
93         private String classname;
94
95         @Column(name="ISSUER", nullable=true, length=1024)
96         private String issuer;
97
98         @Column(name="READ_ONLY", nullable=false)
99         private char readOnly = '0';
100
101         @Column(name="REQUIRES_RESOLVER", nullable=false)
102         private char requiresResolvers;
103
104         @Column(name="CREATED_BY", nullable=false, length=255)
105         private String createdBy = "guest";
106
107         @Temporal(TemporalType.TIMESTAMP)
108         @Column(name="CREATED_DATE", nullable=false, updatable=false)
109         private Date createdDate;
110
111         @Column(name="MODIFIED_BY", nullable=false, length=255)
112         private String modifiedBy = "guest";
113
114         @Temporal(TemporalType.TIMESTAMP)
115         @Column(name="MODIFIED_DATE", nullable=false)
116         private Date modifiedDate;
117
118         //bi-directional many-to-one association to PIPConfigParam
119         @OneToMany(mappedBy="pipconfiguration", orphanRemoval=true, cascade=CascadeType.REMOVE)
120         private Set<PIPConfigParam> pipconfigParams = new HashSet<PIPConfigParam>();
121
122         //bi-directional many-to-one association to PIPType
123         @ManyToOne
124         @JoinColumn(name="TYPE")
125         private PIPType piptype;
126
127         //bi-directional many-to-one association to PIPResolver
128         @OneToMany(mappedBy="pipconfiguration", orphanRemoval=true, cascade=CascadeType.REMOVE)
129         private Set<PIPResolver> pipresolvers = new HashSet<PIPResolver>();
130
131         public PIPConfiguration() {
132         }
133         
134         public PIPConfiguration(PIPConfiguration config, String user) {
135                 this.description = config.description;
136                 this.name = config.name;
137                 this.classname = config.classname;
138                 this.issuer = config.issuer;
139                 this.requiresResolvers = config.requiresResolvers;
140                 this.readOnly = config.readOnly;
141                 this.piptype = config.piptype;
142                 for (PIPConfigParam param : config.pipconfigParams) {
143                         this.addPipconfigParam(new PIPConfigParam(param));
144                 }
145                 for (PIPResolver resolver : config.pipresolvers) {
146                         this.addPipresolver(new PIPResolver(resolver));
147                 }
148         }
149         
150         public PIPConfiguration(String id, Properties properties) throws PIPException {
151                 this.readProperties(id, properties);
152         }
153         
154         public PIPConfiguration(String id, Properties properties, String user) throws PIPException {
155                 this.createdBy = user;
156                 this.modifiedBy = user;
157                 this.readProperties(id, properties);
158         }
159
160         @PrePersist
161         public void     prePersist() {
162                 Date date = new Date();
163                 this.createdDate = date;
164                 this.modifiedDate = date;
165         }
166         
167         @PreUpdate
168         public void preUpdate() {
169                 this.modifiedDate = new Date();
170         }
171
172         public int getId() {
173                 return this.id;
174         }
175
176         public void setId(int id) {
177                 this.id = id;
178         }
179
180         public String getDescription() {
181                 return this.description;
182         }
183
184         public void setDescription(String description) {
185                 this.description = description;
186         }
187
188         public String getName() {
189                 return this.name;
190         }
191
192         public void setName(String name) {
193                 this.name = name;
194         }
195
196         public String getClassname() {
197                 return classname;
198         }
199
200         public void setClassname(String classname) {
201                 this.classname = classname;
202         }
203
204         public String getIssuer() {
205                 return issuer;
206         }
207
208         public void setIssuer(String issuer) {
209                 this.issuer = issuer;
210         }
211
212         public char getReadOnly() {
213                 return readOnly;
214         }
215
216         public void setReadOnly(char readOnly) {
217                 this.readOnly = readOnly;
218         }
219
220         public char getRequiresResolvers() {
221                 return requiresResolvers;
222         }
223
224         public void setRequiresResolvers(char requireResolvers) {
225                 this.requiresResolvers = requireResolvers;
226         }
227
228         public Set<PIPConfigParam> getPipconfigParams() {
229                 return this.pipconfigParams;
230         }
231
232         public void setPipconfigParams(Set<PIPConfigParam> pipconfigParams) {
233                 this.pipconfigParams = pipconfigParams;
234         }
235
236         public PIPConfigParam addPipconfigParam(PIPConfigParam pipconfigParam) {
237                 getPipconfigParams().add(pipconfigParam);
238                 pipconfigParam.setPipconfiguration(this);
239
240                 return pipconfigParam;
241         }
242
243         public PIPConfigParam removePipconfigParam(PIPConfigParam pipconfigParam) {
244                 if (pipconfigParam == null) {
245                         return pipconfigParam;
246                 }
247                 getPipconfigParams().remove(pipconfigParam);
248                 pipconfigParam.setPipconfiguration(null);
249
250                 return pipconfigParam;
251         }
252         
253         @Transient
254         public void clearConfigParams() {
255                 while (this.pipconfigParams.isEmpty() == false) {
256                         this.removePipconfigParam(this.pipconfigParams.iterator().next());
257                 }
258         }
259
260         public PIPType getPiptype() {
261                 return this.piptype;
262         }
263
264         public void setPiptype(PIPType piptype) {
265                 this.piptype = piptype;
266         }
267
268         public Set<PIPResolver> getPipresolvers() {
269                 return this.pipresolvers;
270         }
271
272         public void setPipresolvers(Set<PIPResolver> pipresolvers) {
273                 this.pipresolvers = pipresolvers;
274         }
275
276         public PIPResolver addPipresolver(PIPResolver pipresolver) {
277                 getPipresolvers().add(pipresolver);
278                 pipresolver.setPipconfiguration(this);
279
280                 return pipresolver;
281         }
282
283         public PIPResolver removePipresolver(PIPResolver pipresolver) {
284                 getPipresolvers().remove(pipresolver);
285                 pipresolver.setPipconfiguration(null);
286
287                 return pipresolver;
288         }
289
290         public String getCreatedBy() {
291                 return createdBy;
292         }
293
294         public void setCreatedBy(String createdBy) {
295                 this.createdBy = createdBy;
296         }
297
298         public Date getCreatedDate() {
299                 return createdDate;
300         }
301
302         public void setCreatedDate(Date createdDate) {
303                 this.createdDate = createdDate;
304         }
305
306         public String getModifiedBy() {
307                 return modifiedBy;
308         }
309
310         public void setModifiedBy(String modifiedBy) {
311                 this.modifiedBy = modifiedBy;
312         }
313
314         public Date getModifiedDate() {
315                 return modifiedDate;
316         }
317
318         public void setModifiedDate(Date modifiedDate) {
319                 this.modifiedDate = modifiedDate;
320         }
321
322         @Transient
323         public boolean isReadOnly() {
324                 return (this.readOnly == '1');
325         }
326         
327         @Transient
328         public void setReadOnly(boolean readOnly) {
329                 if (readOnly) {
330                         this.readOnly = '1';
331                 } else {
332                         this.readOnly = '0';
333                 }
334         }
335         
336         @Transient
337         public boolean requiresResolvers() {
338                 return (this.requiresResolvers == '1');
339         }
340         
341         @Transient
342         public void     setRequiresResolvers(boolean requires) {
343                 if (requires) {
344                         this.requiresResolvers = '1';
345                 } else {
346                         this.requiresResolvers = '0';
347                 }
348         }
349         
350         @Transient
351         public static Collection<PIPConfiguration>              importPIPConfigurations(Properties properties) {
352                 Collection<PIPConfiguration> configurations = new ArrayList<PIPConfiguration>();
353                 String engines = properties.getProperty(XACMLProperties.PROP_PIP_ENGINES);
354                 if (engines == null || engines.isEmpty()) {
355                         return configurations;
356                 }
357                 for (String id : Splitter.on(',').trimResults().omitEmptyStrings().split(engines)) {
358                         PIPConfiguration configuration;
359                         try {
360                                 String user = "super-admin";
361                                 //TODO
362                                 //String user = ((XacmlAdminUI)UI.getCurrent()).getUserid();
363                                 configuration = new PIPConfiguration(id, properties, user);
364                                 configuration.setCreatedBy(user);
365                                 configuration.setModifiedBy(user);
366                                 configurations.add(configuration);
367                         } catch (PIPException e) {
368                                 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Import failed: " + e.getLocalizedMessage());
369                                 // TODO:EELF Cleanup - Remove logger
370                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PIPConfiguration", "Import failed");
371                         }
372                 }
373                 
374                 return configurations;
375         }
376         
377         @Transient
378         protected       void            readProperties(String id, Properties properties) throws PIPException {
379                 //
380                 // Save the id if we don't have one already
381                 //
382                 
383                 if (this.id == 0) {
384                         try {
385                                 this.id = Integer.parseInt(id);
386                         } catch (NumberFormatException e) {
387                                 logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Convert id to integer failed: " + id);
388                                 // TODO:EELF Cleanup - Remove logger
389                                 PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "PIPConfiguration", "Convert id to integer failed");
390                         }
391                 }
392                 //
393                 // Get its classname, this MUST exist.
394                 //
395                 this.classname = properties.getProperty(id + ".classname");
396                 if (this.classname == null) {
397                         throw new PIPException("PIP Engine defined without a classname");
398                 }
399                 //
400                 // These classes we know for sure require resolvers.
401                 //
402                 //TODO: Commented out due to JPAUtils class & As of now we are not using PIP. So, it will not impact any Errors
403                 /*if (this.classname.equals(JDBCEngine.class.getCanonicalName())) {
404                         this.setRequiresResolvers(true);
405                         this.setPiptype(JPAUtils.getPIPType(PIPType.TYPE_SQL));
406                 } else if (this.classname.equals(LDAPEngine.class.getCanonicalName())) {
407                         this.setRequiresResolvers(true);
408                         this.setPiptype(JPAUtils.getPIPType(PIPType.TYPE_LDAP));
409                 } else if (this.classname.equals(HyperCSVEngine.class.getCanonicalName())) {
410                         this.setRequiresResolvers(true);
411                         this.setPiptype(JPAUtils.getPIPType(PIPType.TYPE_HYPERCSV));
412                 } else if (this.classname.equals(CSVEngine.class.getCanonicalName())) {
413                         this.setRequiresResolvers(true);
414                         this.setPiptype(JPAUtils.getPIPType(PIPType.TYPE_CSV));
415                 } else {
416                         //
417                         // Assume it does not require resolvers for now, if we encounter
418                         // one then we will change it. The user can always change it via the gui.
419                         // 
420                         this.setRequiresResolvers(false);
421                         this.setPiptype(JPAUtils.getPIPType(PIPType.TYPE_CUSTOM));
422                 }*/
423                 //
424                 // Go through each property
425                 //
426                 for (Object name : properties.keySet()) {
427                         if (name.toString().startsWith(id) == false) {
428                                 continue;
429                         }
430                         if (name.equals(id + ".classname")) {
431                                 //
432                                 // We already saved this
433                                 //
434                         } else if (name.equals(id + "." + StdConfigurableEngine.PROP_NAME)) {
435                                 this.name = properties.getProperty(name.toString());
436                         } else if (name.equals(id + "." + StdConfigurableEngine.PROP_DESCRIPTION)) {
437                                 this.description = properties.getProperty(name.toString());
438                         } else if (name.equals(id + "." + StdConfigurableEngine.PROP_ISSUER)) {
439                                 this.issuer = properties.getProperty(name.toString());
440                         } else if (name.equals(id + ".resolvers")) {
441                                 //
442                                 // It has resolvers, make sure this is set to true if
443                                 // it has been already.
444                                 //
445                                 this.setRequiresResolvers(true);
446                                 //
447                                 // Parse the resolvers
448                                 //
449                                 Collection<PIPResolver> resolvers = PIPResolver.importResolvers(id + ".resolver",
450                                                                                                                                                 properties.getProperty(name.toString()),
451                                                                                                                                                 properties,"super-admin"
452                                                                                                                                                 );
453                                 //TODO: replace with UserId
454                                 //((XacmlAdminUI)UI.getCurrent()).getUserid()
455                                 for (PIPResolver resolver : resolvers) {
456                                         this.addPipresolver(resolver);
457                                 }
458                         } else if (name.toString().startsWith(id + ".resolver")) {
459                                 //
460                                 // Ignore, the PIPResolver will parse these values
461                                 //
462                         } else {
463                                 //
464                                 // Config Parameter
465                                 //
466                                 this.addPipconfigParam(new PIPConfigParam(name.toString().substring(id.length() + 1), 
467                                                                                                         properties.getProperty(name.toString())));
468                         }
469                 }
470                 //
471                 // Make sure we have a name at least
472                 //
473                 if (this.name == null) {
474                         this.name = id;
475                 }
476         }
477         
478
479         @Transient
480         public Map<String, String> getConfiguration(String name) {
481                 String prefix;
482                 if (name == null) {
483                         prefix = Integer.toString(this.id);
484                 } else {
485                         prefix = name;
486                 }
487                 if (prefix.endsWith(".") == false) {
488                         prefix = prefix + ".";
489                 }
490                 Map<String, String> map = new HashMap<String, String>();
491                 map.put(prefix + "classname", this.classname);
492                 map.put(prefix + "name", this.name);
493                 if (this.description != null) {
494                         map.put(prefix + "description", this.description);
495                 }
496                 if (this.issuer != null) {
497                         map.put(prefix + "issuer", this.issuer);
498                 }
499                 
500                 for (PIPConfigParam param : this.pipconfigParams) {
501                         map.put(prefix + param.getParamName(), param.getParamValue());
502                 }
503                 
504                 List<String> ids = new ArrayList<String>();
505                 Iterator<PIPResolver> iter = this.pipresolvers.iterator();
506                 while (iter.hasNext()) {
507                         PIPResolver resolver = iter.next();
508                         String id = Integer.toString(resolver.getId());
509                         Map<String, String> resolverMap = resolver.getConfiguration(prefix + "resolver." + id);
510                         map.putAll(resolverMap);
511                         ids.add(id);
512                 }
513                 if (ids.size() > 0) {
514                         map.put(prefix + "resolvers", Joiner.on(',').join(ids));
515                 }
516                 return map;
517         }
518         
519         @Transient
520         public Properties       generateProperties(String name) {
521                 String prefix;
522                 if (name == null) {
523                         prefix = Integer.toString(this.id);
524                 } else {
525                         if (name.endsWith(".")) {
526                                 prefix = name;
527                         } else {
528                                 prefix = name + ".";
529                         }
530                 }
531                 Properties props = new Properties();
532                 props.setProperty("xacml.pip.engines", name);
533                 props.setProperty(prefix + "classname", this.classname);
534                 props.setProperty(prefix + "name", this.name);
535                 if (this.description != null) {
536                         props.setProperty(prefix + "description", this.description);
537                 }
538                 if (this.issuer != null && this.issuer.isEmpty() == false) {
539                         props.setProperty(prefix + "issuer", this.issuer);
540                 }
541                 
542                 for (PIPConfigParam param : this.pipconfigParams) {
543                         props.setProperty(prefix + param.getParamName(), param.getParamValue());
544                 }
545                 
546                 List<String> ids = new ArrayList<String>();
547                 Iterator<PIPResolver> iter = this.pipresolvers.iterator();
548                 while (iter.hasNext()) {
549                         PIPResolver resolver = iter.next();
550                         String id = Integer.toString(resolver.getId());
551                         resolver.generateProperties(props, prefix + "resolver." + id);
552                         ids.add(id);
553                 }
554                 if (ids.size() > 0) {
555                         props.setProperty(prefix + "resolvers", Joiner.on(',').join(ids));
556                 }
557                 return props;
558         }
559
560         @Transient
561         @Override
562         public String toString() {
563                 return "PIPConfiguration [id=" + id + ", piptype=" + piptype
564                                 + ", classname=" + classname + ", name=" + name
565                                 + ", description=" + description + ", issuer=" + issuer
566                                 + ", readOnly=" + readOnly + ", requiresResolvers="
567                                 + requiresResolvers + ", createdBy=" + createdBy
568                                 + ", createdDate=" + createdDate + ", modifiedBy=" + modifiedBy
569                                 + ", modifiedDate=" + modifiedDate + ", pipconfigParams="
570                                 + pipconfigParams + ", pipresolvers=" + pipresolvers + "]";
571         }
572 }