/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.core.persistence.jpa.entity.resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.types.ConnConfProperty;
import org.apache.syncope.common.lib.types.ConnectorCapability;
import org.apache.syncope.common.lib.types.TraceLevel;
import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
import org.apache.syncope.core.persistence.jpa.validation.entity.ExternalResourceCheck;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPasswordPolicy;
import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullPolicy;
import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
import org.apache.syncope.core.persistence.jpa.entity.AbstractProvidedKeyEntity;
import org.identityconnectors.framework.common.objects.ObjectClass;
/**
* Resource for propagation and pull.
*/
@Entity
@Table(name = JPAExternalResource.TABLE)
@ExternalResourceCheck
public class JPAExternalResource extends AbstractProvidedKeyEntity implements ExternalResource {
private static final long serialVersionUID = -6937712883512073278L;
public static final String TABLE = "ExternalResource";
/**
* Should this resource enforce the mandatory constraints?
*/
@NotNull
@Basic
@Min(0)
@Max(1)
private Integer enforceMandatoryCondition;
/**
* The resource type is identified by the associated connector.
*/
@ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.MERGE })
@NotNull
private JPAConnInstance connector;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "resource")
private List<JPAProvision> provisions = new ArrayList<>();
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "resource")
private JPAOrgUnit orgUnit;
/**
* Priority index for propagation ordering.
*/
private Integer propagationPriority;
/**
* Generate random password, if not provided.
*/
@NotNull
@Basic
@Min(0)
@Max(1)
private Integer randomPwdIfNotProvided;
@Enumerated(EnumType.STRING)
@NotNull
private TraceLevel createTraceLevel;
@Enumerated(EnumType.STRING)
@NotNull
private TraceLevel updateTraceLevel;
@Enumerated(EnumType.STRING)
@NotNull
private TraceLevel deleteTraceLevel;
@Enumerated(EnumType.STRING)
@NotNull
private TraceLevel provisioningTraceLevel;
@ManyToOne(fetch = FetchType.EAGER)
private JPAPasswordPolicy passwordPolicy;
@ManyToOne(fetch = FetchType.EAGER)
private JPAAccountPolicy accountPolicy;
@ManyToOne(fetch = FetchType.EAGER)
private JPAPullPolicy pullPolicy;
/**
* Configuration properties that are overridden from the connector instance.
*/
@Lob
private String jsonConf;
@NotNull
@Basic
@Min(0)
@Max(1)
private Integer overrideCapabilities;
@ElementCollection(fetch = FetchType.EAGER)
@Enumerated(EnumType.STRING)
@Column(name = "capabilityOverride")
@CollectionTable(name = "ExternalResource_capOverride",
joinColumns =
@JoinColumn(name = "resource_id", referencedColumnName = "id"))
private Set<ConnectorCapability> capabilitiesOverride = new HashSet<>();
/**
* (Optional) classes for PropagationAction.
*/
@ElementCollection(fetch = FetchType.EAGER)
@Column(name = "actionClassName")
@CollectionTable(name = "ExternalResource_PropActions",
joinColumns =
@JoinColumn(name = "resource_id", referencedColumnName = "id"))
private List<String> propagationActionsClassNames = new ArrayList<>();
public JPAExternalResource() {
super();
enforceMandatoryCondition = getBooleanAsInteger(false);
propagationPriority = 0;
randomPwdIfNotProvided = 0;
overrideCapabilities = 0;
createTraceLevel = TraceLevel.FAILURES;
updateTraceLevel = TraceLevel.FAILURES;
deleteTraceLevel = TraceLevel.FAILURES;
provisioningTraceLevel = TraceLevel.FAILURES;
}
@Override
public boolean isEnforceMandatoryCondition() {
return isBooleanAsInteger(enforceMandatoryCondition);
}
@Override
public void setEnforceMandatoryCondition(final boolean enforceMandatoryCondition) {
this.enforceMandatoryCondition = getBooleanAsInteger(enforceMandatoryCondition);
}
@Override
public ConnInstance getConnector() {
return connector;
}
@Override
public void setConnector(final ConnInstance connector) {
checkType(connector, JPAConnInstance.class);
this.connector = (JPAConnInstance) connector;
}
@Override
public boolean add(final Provision provision) {
checkType(provision, JPAProvision.class);
return this.provisions.add((JPAProvision) provision);
}
@Override
public Provision getProvision(final ObjectClass objectClass) {
return IterableUtils.find(provisions, new Predicate<Provision>() {
@Override
public boolean evaluate(final Provision provision) {
return provision.getObjectClass().equals(objectClass);
}
});
}
@Override
public Provision getProvision(final AnyType anyType) {
return IterableUtils.find(provisions, new Predicate<Provision>() {
@Override
public boolean evaluate(final Provision provision) {
return provision.getAnyType().equals(anyType);
}
});
}
@Override
public List<? extends Provision> getProvisions() {
return provisions;
}
@Override
public OrgUnit getOrgUnit() {
return orgUnit;
}
@Override
public void setOrgUnit(final OrgUnit orgUnit) {
checkType(orgUnit, JPAOrgUnit.class);
this.orgUnit = (JPAOrgUnit) orgUnit;
}
@Override
public Integer getPropagationPriority() {
return propagationPriority;
}
@Override
public void setPropagationPriority(final Integer propagationPriority) {
if (propagationPriority != null) {
this.propagationPriority = propagationPriority;
}
}
@Override
public boolean isRandomPwdIfNotProvided() {
return isBooleanAsInteger(randomPwdIfNotProvided);
}
@Override
public void setRandomPwdIfNotProvided(final boolean randomPwdIfNotProvided) {
this.randomPwdIfNotProvided = getBooleanAsInteger(randomPwdIfNotProvided);
}
@Override
public TraceLevel getCreateTraceLevel() {
return createTraceLevel;
}
@Override
public void setCreateTraceLevel(final TraceLevel createTraceLevel) {
this.createTraceLevel = createTraceLevel;
}
@Override
public TraceLevel getDeleteTraceLevel() {
return deleteTraceLevel;
}
@Override
public void setDeleteTraceLevel(final TraceLevel deleteTraceLevel) {
this.deleteTraceLevel = deleteTraceLevel;
}
@Override
public TraceLevel getUpdateTraceLevel() {
return updateTraceLevel;
}
@Override
public void setUpdateTraceLevel(final TraceLevel updateTraceLevel) {
this.updateTraceLevel = updateTraceLevel;
}
@Override
public TraceLevel getProvisioningTraceLevel() {
return provisioningTraceLevel;
}
@Override
public void setProvisioningTraceLevel(final TraceLevel provisioningTraceLevel) {
this.provisioningTraceLevel = provisioningTraceLevel;
}
@Override
public AccountPolicy getAccountPolicy() {
return accountPolicy;
}
@Override
public void setAccountPolicy(final AccountPolicy accountPolicy) {
checkType(accountPolicy, JPAAccountPolicy.class);
this.accountPolicy = (JPAAccountPolicy) accountPolicy;
}
@Override
public PasswordPolicy getPasswordPolicy() {
return passwordPolicy;
}
@Override
public void setPasswordPolicy(final PasswordPolicy passwordPolicy) {
checkType(passwordPolicy, JPAPasswordPolicy.class);
this.passwordPolicy = (JPAPasswordPolicy) passwordPolicy;
}
@Override
public PullPolicy getPullPolicy() {
return pullPolicy;
}
@Override
public void setPullPolicy(final PullPolicy pullPolicy) {
checkType(pullPolicy, JPAPullPolicy.class);
this.pullPolicy = (JPAPullPolicy) pullPolicy;
}
@Override
public Set<ConnConfProperty> getConfOverride() {
Set<ConnConfProperty> confOverride = new HashSet<>();
if (!StringUtils.isBlank(jsonConf)) {
CollectionUtils.addAll(confOverride, POJOHelper.deserialize(jsonConf, ConnConfProperty[].class));
}
return confOverride;
}
@Override
public void setConfOverride(final Set<ConnConfProperty> confOverride) {
jsonConf = POJOHelper.serialize(new HashSet<>(confOverride));
}
@Override
public boolean isOverrideCapabilities() {
return isBooleanAsInteger(overrideCapabilities);
}
@Override
public void setOverrideCapabilities(final boolean overrideCapabilities) {
this.overrideCapabilities = getBooleanAsInteger(overrideCapabilities);
}
@Override
public Set<ConnectorCapability> getCapabilitiesOverride() {
return capabilitiesOverride;
}
@Override
public List<String> getPropagationActionsClassNames() {
return propagationActionsClassNames;
}
}