View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.core.persistence.jpa.entity;
20  
21  import com.fasterxml.jackson.core.type.TypeReference;
22  import java.util.ArrayList;
23  import java.util.HashSet;
24  import java.util.List;
25  import java.util.Optional;
26  import java.util.Set;
27  import javax.persistence.Cacheable;
28  import javax.persistence.CascadeType;
29  import javax.persistence.Entity;
30  import javax.persistence.EnumType;
31  import javax.persistence.Enumerated;
32  import javax.persistence.FetchType;
33  import javax.persistence.JoinColumn;
34  import javax.persistence.JoinTable;
35  import javax.persistence.Lob;
36  import javax.persistence.ManyToMany;
37  import javax.persistence.ManyToOne;
38  import javax.persistence.PostLoad;
39  import javax.persistence.PostPersist;
40  import javax.persistence.PostUpdate;
41  import javax.persistence.PrePersist;
42  import javax.persistence.PreUpdate;
43  import javax.persistence.Table;
44  import javax.persistence.Transient;
45  import javax.persistence.UniqueConstraint;
46  import javax.validation.constraints.NotNull;
47  import org.apache.commons.lang3.StringUtils;
48  import org.apache.syncope.common.lib.to.OrgUnit;
49  import org.apache.syncope.common.lib.to.Provision;
50  import org.apache.syncope.common.lib.types.ConnConfProperty;
51  import org.apache.syncope.common.lib.types.ConnectorCapability;
52  import org.apache.syncope.common.lib.types.IdMImplementationType;
53  import org.apache.syncope.common.lib.types.TraceLevel;
54  import org.apache.syncope.core.persistence.api.entity.ConnInstance;
55  import org.apache.syncope.core.persistence.api.entity.ExternalResource;
56  import org.apache.syncope.core.persistence.api.entity.Implementation;
57  import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
58  import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
59  import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy;
60  import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
61  import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
62  import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
63  import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPasswordPolicy;
64  import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPropagationPolicy;
65  import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullPolicy;
66  import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPushPolicy;
67  import org.apache.syncope.core.persistence.jpa.validation.entity.ExternalResourceCheck;
68  import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
69  
70  /**
71   * Resource for propagation and pull.
72   */
73  @Entity
74  @Table(name = JPAExternalResource.TABLE)
75  @ExternalResourceCheck
76  @Cacheable
77  public class JPAExternalResource extends AbstractProvidedKeyEntity implements ExternalResource {
78  
79      private static final long serialVersionUID = -6937712883512073278L;
80  
81      public static final String TABLE = "ExternalResource";
82  
83      protected static final TypeReference<Set<ConnectorCapability>> CAPABILITY_TYPEREF =
84              new TypeReference<Set<ConnectorCapability>>() {
85      };
86  
87      protected static final TypeReference<List<Provision>> PROVISION_TYPEREF =
88              new TypeReference<List<Provision>>() {
89      };
90  
91      /**
92       * Should this resource enforce the mandatory constraints?
93       */
94      @NotNull
95      private Boolean enforceMandatoryCondition = false;
96  
97      /**
98       * The resource type is identified by the associated connector.
99       */
100     @ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.MERGE })
101     private JPAConnInstance connector;
102 
103     /**
104      * Priority index for propagation ordering.
105      */
106     private Integer propagationPriority;
107 
108     @Enumerated(EnumType.STRING)
109     @NotNull
110     private TraceLevel createTraceLevel = TraceLevel.FAILURES;
111 
112     @Enumerated(EnumType.STRING)
113     @NotNull
114     private TraceLevel updateTraceLevel = TraceLevel.FAILURES;
115 
116     @Enumerated(EnumType.STRING)
117     @NotNull
118     private TraceLevel deleteTraceLevel = TraceLevel.FAILURES;
119 
120     @Enumerated(EnumType.STRING)
121     @NotNull
122     private TraceLevel provisioningTraceLevel = TraceLevel.FAILURES;
123 
124     @ManyToOne(fetch = FetchType.EAGER)
125     private JPAPasswordPolicy passwordPolicy;
126 
127     @ManyToOne(fetch = FetchType.EAGER)
128     private JPAAccountPolicy accountPolicy;
129 
130     @ManyToOne(fetch = FetchType.EAGER)
131     private JPAPropagationPolicy propagationPolicy;
132 
133     @ManyToOne(fetch = FetchType.EAGER)
134     private JPAPullPolicy pullPolicy;
135 
136     @ManyToOne(fetch = FetchType.EAGER)
137     private JPAPushPolicy pushPolicy;
138 
139     @ManyToOne(fetch = FetchType.EAGER)
140     private JPAImplementation provisionSorter;
141 
142     /**
143      * Configuration properties that are override from the connector instance.
144      */
145     @Lob
146     private String jsonConf;
147 
148     @NotNull
149     private Boolean overrideCapabilities = false;
150 
151     @Lob
152     private String capabilitiesOverride;
153 
154     @Transient
155     private final Set<ConnectorCapability> capabilitiesOverrideSet = new HashSet<>();
156 
157     @Lob
158     private String provisions;
159 
160     @Transient
161     private final List<Provision> provisionList = new ArrayList<>();
162 
163     @Lob
164     private String orgUnit;
165 
166     @ManyToMany(fetch = FetchType.EAGER)
167     @JoinTable(name = TABLE + "PropAction",
168             joinColumns =
169             @JoinColumn(name = "resource_id"),
170             inverseJoinColumns =
171             @JoinColumn(name = "implementation_id"),
172             uniqueConstraints =
173             @UniqueConstraint(columnNames = { "resource_id", "implementation_id" }))
174     private List<JPAImplementation> propagationActions = new ArrayList<>();
175 
176     @Override
177     public boolean isEnforceMandatoryCondition() {
178         return enforceMandatoryCondition;
179     }
180 
181     @Override
182     public void setEnforceMandatoryCondition(final boolean enforceMandatoryCondition) {
183         this.enforceMandatoryCondition = enforceMandatoryCondition;
184     }
185 
186     @Override
187     public ConnInstance getConnector() {
188         return connector;
189     }
190 
191     @Override
192     public void setConnector(final ConnInstance connector) {
193         checkType(connector, JPAConnInstance.class);
194         this.connector = (JPAConnInstance) connector;
195     }
196 
197     @Override
198     public Optional<Provision> getProvisionByAnyType(final String anyType) {
199         return getProvisions().stream().
200                 filter(provision -> provision.getAnyType().equals(anyType)).findFirst();
201     }
202 
203     @Override
204     public Optional<Provision> getProvisionByObjectClass(final String objectClass) {
205         return getProvisions().stream().
206                 filter(provision -> provision.getObjectClass().equals(objectClass)).findFirst();
207     }
208 
209     @Override
210     public List<Provision> getProvisions() {
211         return provisionList;
212     }
213 
214     @Override
215     public OrgUnit getOrgUnit() {
216         return Optional.ofNullable(orgUnit).map(ou -> POJOHelper.deserialize(ou, OrgUnit.class)).orElse(null);
217     }
218 
219     @Override
220     public void setOrgUnit(final OrgUnit orgUnit) {
221         this.orgUnit = orgUnit == null ? null : POJOHelper.serialize(orgUnit);
222     }
223 
224     @Override
225     public Integer getPropagationPriority() {
226         return propagationPriority;
227     }
228 
229     @Override
230     public void setPropagationPriority(final Integer propagationPriority) {
231         this.propagationPriority = propagationPriority;
232     }
233 
234     @Override
235     public TraceLevel getCreateTraceLevel() {
236         return createTraceLevel;
237     }
238 
239     @Override
240     public void setCreateTraceLevel(final TraceLevel createTraceLevel) {
241         this.createTraceLevel = createTraceLevel;
242     }
243 
244     @Override
245 
246     public TraceLevel getDeleteTraceLevel() {
247         return deleteTraceLevel;
248     }
249 
250     @Override
251     public void setDeleteTraceLevel(final TraceLevel deleteTraceLevel) {
252         this.deleteTraceLevel = deleteTraceLevel;
253     }
254 
255     @Override
256     public TraceLevel getUpdateTraceLevel() {
257         return updateTraceLevel;
258     }
259 
260     @Override
261     public void setUpdateTraceLevel(final TraceLevel updateTraceLevel) {
262         this.updateTraceLevel = updateTraceLevel;
263     }
264 
265     @Override
266     public TraceLevel getProvisioningTraceLevel() {
267         return provisioningTraceLevel;
268     }
269 
270     @Override
271     public void setProvisioningTraceLevel(final TraceLevel provisioningTraceLevel) {
272         this.provisioningTraceLevel = provisioningTraceLevel;
273     }
274 
275     @Override
276     public AccountPolicy getAccountPolicy() {
277         return accountPolicy;
278     }
279 
280     @Override
281     public void setAccountPolicy(final AccountPolicy accountPolicy) {
282         checkType(accountPolicy, JPAAccountPolicy.class);
283         this.accountPolicy = (JPAAccountPolicy) accountPolicy;
284     }
285 
286     @Override
287     public PasswordPolicy getPasswordPolicy() {
288         return passwordPolicy;
289     }
290 
291     @Override
292     public void setPasswordPolicy(final PasswordPolicy passwordPolicy) {
293         checkType(passwordPolicy, JPAPasswordPolicy.class);
294         this.passwordPolicy = (JPAPasswordPolicy) passwordPolicy;
295     }
296 
297     @Override
298     public PropagationPolicy getPropagationPolicy() {
299         return propagationPolicy;
300     }
301 
302     @Override
303     public void setPropagationPolicy(final PropagationPolicy propagationPolicy) {
304         checkType(propagationPolicy, JPAPropagationPolicy.class);
305         this.propagationPolicy = (JPAPropagationPolicy) propagationPolicy;
306     }
307 
308     @Override
309     public PullPolicy getPullPolicy() {
310         return pullPolicy;
311     }
312 
313     @Override
314     public void setPullPolicy(final PullPolicy pullPolicy) {
315         checkType(pullPolicy, JPAPullPolicy.class);
316         this.pullPolicy = (JPAPullPolicy) pullPolicy;
317     }
318 
319     @Override
320     public PushPolicy getPushPolicy() {
321         return pushPolicy;
322     }
323 
324     @Override
325     public void setPushPolicy(final PushPolicy pushPolicy) {
326         checkType(pushPolicy, JPAPushPolicy.class);
327         this.pushPolicy = (JPAPushPolicy) pushPolicy;
328     }
329 
330     @Override
331     public Implementation getProvisionSorter() {
332         return provisionSorter;
333     }
334 
335     @Override
336     public void setProvisionSorter(final Implementation provisionSorter) {
337         checkType(provisionSorter, JPAImplementation.class);
338         checkImplementationType(provisionSorter, IdMImplementationType.PROVISION_SORTER);
339         this.provisionSorter = (JPAImplementation) provisionSorter;
340     }
341 
342     @Override
343     public Set<ConnConfProperty> getConfOverride() {
344         Set<ConnConfProperty> confOverride = new HashSet<>();
345         if (!StringUtils.isBlank(jsonConf)) {
346             confOverride.addAll(List.of(POJOHelper.deserialize(jsonConf, ConnConfProperty[].class)));
347         }
348 
349         return confOverride;
350     }
351 
352     @Override
353     public void setConfOverride(final Set<ConnConfProperty> confOverride) {
354         jsonConf = POJOHelper.serialize(new HashSet<>(confOverride));
355     }
356 
357     @Override
358     public boolean isOverrideCapabilities() {
359         return overrideCapabilities;
360     }
361 
362     @Override
363     public void setOverrideCapabilities(final boolean overrideCapabilities) {
364         this.overrideCapabilities = overrideCapabilities;
365     }
366 
367     @Override
368     public Set<ConnectorCapability> getCapabilitiesOverride() {
369         return capabilitiesOverrideSet;
370     }
371 
372     @Override
373     public boolean add(final Implementation propagationAction) {
374         checkType(propagationAction, JPAImplementation.class);
375         checkImplementationType(propagationAction, IdMImplementationType.PROPAGATION_ACTIONS);
376         return propagationActions.contains((JPAImplementation) propagationAction)
377                 || propagationActions.add((JPAImplementation) propagationAction);
378     }
379 
380     @Override
381     public List<? extends Implementation> getPropagationActions() {
382         return propagationActions;
383     }
384 
385     protected void json2list(final boolean clearFirst) {
386         if (clearFirst) {
387             getCapabilitiesOverride().clear();
388             getProvisions().clear();
389         }
390         if (capabilitiesOverride != null) {
391             getCapabilitiesOverride().addAll(POJOHelper.deserialize(capabilitiesOverride, CAPABILITY_TYPEREF));
392         }
393         if (provisions != null) {
394             getProvisions().addAll(POJOHelper.deserialize(provisions, PROVISION_TYPEREF));
395         }
396     }
397 
398     @PostLoad
399     public void postLoad() {
400         json2list(false);
401     }
402 
403     @PostPersist
404     @PostUpdate
405     public void postSave() {
406         json2list(true);
407     }
408 
409     @PrePersist
410     @PreUpdate
411     public void list2json() {
412         capabilitiesOverride = POJOHelper.serialize(getCapabilitiesOverride());
413         provisions = POJOHelper.serialize(getProvisions());
414     }
415 }