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.Collection;
24  import java.util.HashSet;
25  import java.util.List;
26  import java.util.Optional;
27  import java.util.Set;
28  import javax.persistence.CascadeType;
29  import javax.persistence.Column;
30  import javax.persistence.Entity;
31  import javax.persistence.FetchType;
32  import javax.persistence.Lob;
33  import javax.persistence.ManyToOne;
34  import javax.persistence.OneToMany;
35  import javax.persistence.PostLoad;
36  import javax.persistence.PostPersist;
37  import javax.persistence.PostUpdate;
38  import javax.persistence.PrePersist;
39  import javax.persistence.PreUpdate;
40  import javax.persistence.Table;
41  import javax.validation.constraints.NotNull;
42  import org.apache.commons.lang3.StringUtils;
43  import org.apache.syncope.common.lib.types.ConnConfProperty;
44  import org.apache.syncope.common.lib.types.ConnectorCapability;
45  import org.apache.syncope.core.persistence.api.entity.ConnInstance;
46  import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
47  import org.apache.syncope.core.persistence.api.entity.ExternalResource;
48  import org.apache.syncope.core.persistence.api.entity.Realm;
49  import org.apache.syncope.core.persistence.jpa.validation.entity.ConnInstanceCheck;
50  import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
51  
52  @Entity
53  @Table(name = JPAConnInstance.TABLE)
54  @ConnInstanceCheck
55  public class JPAConnInstance extends AbstractGeneratedKeyEntity implements ConnInstance {
56  
57      private static final long serialVersionUID = -2294708794497208872L;
58  
59      public static final String TABLE = "ConnInstance";
60  
61      protected static final TypeReference<Set<ConnectorCapability>> TYPEREF =
62              new TypeReference<Set<ConnectorCapability>>() {
63      };
64  
65      private static final int DEFAULT_TIMEOUT = 10;
66  
67      @ManyToOne(fetch = FetchType.EAGER, optional = false)
68      private JPARealm adminRealm;
69  
70      /**
71       * URI identifying the local / remote ConnId location where the related connector bundle is found.
72       */
73      @NotNull
74      private String location;
75  
76      /**
77       * Connector bundle class name.
78       * Within a given location, the triple
79       * (ConnectorBundle-Name, ConnectorBundle-Version, ConnectorBundle-Version) must be unique.
80       */
81      @NotNull
82      private String connectorName;
83  
84      /**
85       * Qualified name for the connector bundle.
86       * Within a given location, the triple
87       * (ConnectorBundle-Name, ConnectorBundle-Version, ConnectorBundle-Version) must be unique.
88       */
89      @NotNull
90      private String bundleName;
91  
92      /**
93       * Version of the bundle.
94       * Within a given location, the triple
95       * (ConnectorBundle-Name, ConnectorBundle-Version, ConnectorBundle-Version) must be unique.
96       */
97      @NotNull
98      private String version;
99  
100     @Lob
101     private String capabilities;
102 
103     private final Set<ConnectorCapability> capabilitiesSet = new HashSet<>();
104 
105     /**
106      * The main configuration for the connector instance. This is directly implemented by the Configuration bean class
107      * which contains annotated ConfigurationProperties.
108      *
109      * @see org.identityconnectors.framework.api.ConfigurationProperty
110      */
111     @Lob
112     private String jsonConf;
113 
114     @Column(unique = true)
115     private String displayName;
116 
117     /**
118      * External resources associated to the connector.
119      */
120     @OneToMany(cascade = { CascadeType.ALL }, mappedBy = "connector")
121     private List<JPAExternalResource> resources = new ArrayList<>();
122 
123     /**
124      * Connector request timeout. It is not applied in case of sync, full reconciliation and search.
125      * DEFAULT_TIMEOUT is the default value to be used in case of unspecified timeout.
126      */
127     private Integer connRequestTimeout = DEFAULT_TIMEOUT;
128 
129     private JPAConnPoolConf poolConf;
130 
131     @Override
132     public Realm getAdminRealm() {
133         return adminRealm;
134     }
135 
136     @Override
137     public void setAdminRealm(final Realm adminRealm) {
138         checkType(adminRealm, JPARealm.class);
139         this.adminRealm = (JPARealm) adminRealm;
140     }
141 
142     @Override
143     public String getLocation() {
144         return location;
145     }
146 
147     @Override
148     public void setLocation(final String location) {
149         this.location = location;
150     }
151 
152     @Override
153     public String getConnectorName() {
154         return connectorName;
155     }
156 
157     @Override
158     public void setConnectorName(final String connectorName) {
159         this.connectorName = connectorName;
160     }
161 
162     @Override
163     public String getBundleName() {
164         return bundleName;
165     }
166 
167     @Override
168     public void setBundleName(final String bundleName) {
169         this.bundleName = bundleName;
170     }
171 
172     @Override
173     public String getVersion() {
174         return version;
175     }
176 
177     @Override
178     public void setVersion(final String version) {
179         this.version = version;
180     }
181 
182     @Override
183     public Set<ConnConfProperty> getConf() {
184         Set<ConnConfProperty> configuration = new HashSet<>();
185         if (!StringUtils.isBlank(jsonConf)) {
186             configuration.addAll(List.of(POJOHelper.deserialize(jsonConf, ConnConfProperty[].class)));
187         }
188 
189         return configuration;
190     }
191 
192     @Override
193     public void setConf(final Collection<ConnConfProperty> conf) {
194         jsonConf = POJOHelper.serialize(new HashSet<>(conf));
195     }
196 
197     @Override
198     public String getDisplayName() {
199         return displayName;
200     }
201 
202     @Override
203     public void setDisplayName(final String displayName) {
204         this.displayName = displayName;
205     }
206 
207     @Override
208     public List<? extends ExternalResource> getResources() {
209         return resources;
210     }
211 
212     @Override
213     public boolean add(final ExternalResource resource) {
214         checkType(resource, JPAExternalResource.class);
215         return resources.contains((JPAExternalResource) resource) || resources.add((JPAExternalResource) resource);
216     }
217 
218     @Override
219     public Set<ConnectorCapability> getCapabilities() {
220         return capabilitiesSet;
221     }
222 
223     @Override
224     public Integer getConnRequestTimeout() {
225         // DEFAULT_TIMEOUT will be returned in case of null timeout:
226         // * instances created by the content loader
227         // * or with a timeout nullified explicitely
228         return Optional.ofNullable(connRequestTimeout).orElse(DEFAULT_TIMEOUT);
229     }
230 
231     @Override
232     public void setConnRequestTimeout(final Integer timeout) {
233         this.connRequestTimeout = timeout;
234     }
235 
236     @Override
237     public ConnPoolConf getPoolConf() {
238         return poolConf;
239     }
240 
241     @Override
242     public void setPoolConf(final ConnPoolConf poolConf) {
243         checkType(poolConf, JPAConnPoolConf.class);
244         this.poolConf = (JPAConnPoolConf) poolConf;
245     }
246 
247     protected void json2list(final boolean clearFirst) {
248         if (clearFirst) {
249             getCapabilities().clear();
250         }
251         if (capabilities != null) {
252             getCapabilities().addAll(POJOHelper.deserialize(capabilities, TYPEREF));
253         }
254     }
255 
256     @PostLoad
257     public void postLoad() {
258         json2list(false);
259     }
260 
261     @PostPersist
262     @PostUpdate
263     public void postSave() {
264         json2list(true);
265     }
266 
267     @PrePersist
268     @PreUpdate
269     public void list2json() {
270         capabilities = POJOHelper.serialize(getCapabilities());
271     }
272 }