Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed Sep 11, 2018
2 parents 83f856c + 9e6c439 commit 109434f
Show file tree
Hide file tree
Showing 16 changed files with 220 additions and 89 deletions.
Expand Up @@ -50,21 +50,26 @@ public RelationDefinitionType getRelationDefinition(QName relation) {

@Override
public boolean isOfKind(QName relation, RelationKindType kind) {
return kind == RelationKindType.MEMBERSHIP && (relation == null || QNameUtil.match(relation, ORG_DEFAULT));
return kind == RelationKindType.MEMBER && (relation == null || QNameUtil.match(relation, ORG_DEFAULT));
}

@Override
public boolean processRelationOnLogin(QName relation) {
public boolean isProcessedOnLogin(QName relation) {
return false;
}

@Override
public boolean processRelationOnRecompute(QName relation) {
public boolean isProcessedOnRecompute(QName relation) {
return false;
}

@Override
public boolean includeIntoParentOrgRef(QName relation) {
public boolean isStoredIntoParentOrgRef(QName relation) {
return false;
}

@Override
public boolean isAutomaticallyMatched(QName relation) {
return false;
}

Expand All @@ -76,12 +81,12 @@ public QName getDefaultRelation() {
@NotNull
@Override
public Collection<QName> getAllRelationsFor(RelationKindType kind) {
return kind == RelationKindType.MEMBERSHIP ? singletonList(ORG_DEFAULT) : emptyList();
return kind == RelationKindType.MEMBER ? singletonList(ORG_DEFAULT) : emptyList();
}

@Override
public QName getDefaultRelationFor(RelationKindType kind) {
return kind == RelationKindType.MEMBERSHIP ? ORG_DEFAULT : null;
return kind == RelationKindType.MEMBER ? ORG_DEFAULT : null;
}

@NotNull
Expand Down
Expand Up @@ -1233,7 +1233,8 @@ private <T> T unmarshalEnumFromPrimitive(PrimitiveXNode prim, Class<T> beanClass
}
}
if (javaEnumString == null) {
throw new SchemaException("Cannot find enum value for string '"+primValue+"' in "+beanClass);
pc.warnOrThrow(LOGGER, "Cannot find enum value for string '"+primValue+"' in "+beanClass);
return null;
}

@SuppressWarnings("unchecked")
Expand Down
Expand Up @@ -379,8 +379,11 @@ private <T> PrismPropertyValue<T> parsePropertyValue(@NotNull XNode node,
if (expression != null) {
PrismPropertyValue<T> ppv = new PrismPropertyValue<>(null, prismContext, null, null, expression);
return ppv;

}
} else {
// There's no point in returning PPV(null) as it would soon fail on internal PP check.
// We are probably recovering from an error in COMPAT mode here, so let's just skip this value.
return null;
}
}
PrismPropertyValue<T> ppv = new PrismPropertyValue<>(realValue);
ppv.setPrismContext(prismContext);
Expand Down
Expand Up @@ -55,14 +55,18 @@ public interface RelationRegistry {
*/
boolean isOfKind(QName relation, RelationKindType kind);

default boolean isMembership(QName relation) {
return isOfKind(relation, RelationKindType.MEMBERSHIP);
default boolean isMember(QName relation) {
return isOfKind(relation, RelationKindType.MEMBER);
}

default boolean isManager(QName relation) {
return isOfKind(relation, RelationKindType.MANAGER);
}

default boolean isMeta(QName relation) {
return isOfKind(relation, RelationKindType.META);
}

default boolean isDelegation(QName relation) {
return isOfKind(relation, RelationKindType.DELEGATION);
}
Expand All @@ -78,22 +82,25 @@ default boolean isOwner(QName relation) {
}

/**
* Whether this kind of relations is processed on login. Currently only relations of MEMBERSHIP and DELEGATION kinds are.
* This is to be configured in the future (MID-3581).
* Whether this kind of relations is processed on login. By default, only relations of MEMBER and DELEGATION kinds are.
*/
boolean isProcessedOnLogin(QName relation);

/**
* Whether this kind of relations is processed on recompute. By default, only relations of MEMBER, MANAGER and DELEGATION kinds are.
*/
boolean processRelationOnLogin(QName relation);
boolean isProcessedOnRecompute(QName relation);

/**
* Whether this kind of relations is processed on recompute. Currently only relations of MEMBERSHIP, MANAGER and DELEGATION kinds are.
* This is to be configured in the future (MID-3581).
* Whether this kind of relations is stored in parentOrgRef. By default, only relations of MEMBER are.
*/
boolean processRelationOnRecompute(QName relation);
boolean isStoredIntoParentOrgRef(QName relation);

/**
* Whether this kind of relations is included in parentOrgRef. Currently only relations of MEMBERSHIP but *not* META kinds are.
* This is to be configured in the future (MID-3581).
* Whether this kind of relations is automatically matched by order constraints. By default, only relations of MEMBER,
* META and DELEGATION kinds are.
*/
boolean includeIntoParentOrgRef(QName relation);
boolean isAutomaticallyMatched(QName relation);

/**
* Returns the default relation i.e. the one that is equivalent to the null relation name.
Expand Down
Expand Up @@ -34,9 +34,9 @@
*/
public enum RelationTypes {

MEMBER(SchemaConstants.ORG_DEFAULT, "", RelationKindType.MEMBERSHIP, null, ADMINISTRATION, ORGANIZATION, SELF_SERVICE),
MANAGER(SchemaConstants.ORG_MANAGER, "Manager", RelationKindType.MANAGER, singletonList(RelationKindType.MEMBERSHIP), ADMINISTRATION, GOVERNANCE, ORGANIZATION, SELF_SERVICE),
META(SchemaConstants.ORG_META, "Meta", RelationKindType.META, singletonList(RelationKindType.MEMBERSHIP), POLICY),
MEMBER(SchemaConstants.ORG_DEFAULT, "", RelationKindType.MEMBER, null, ADMINISTRATION, ORGANIZATION, SELF_SERVICE),
MANAGER(SchemaConstants.ORG_MANAGER, "Manager", RelationKindType.MANAGER, singletonList(RelationKindType.MEMBER), ADMINISTRATION, GOVERNANCE, ORGANIZATION, SELF_SERVICE),
META(SchemaConstants.ORG_META, "Meta", RelationKindType.META, null, POLICY),
DEPUTY(SchemaConstants.ORG_DEPUTY, "Deputy", RelationKindType.DELEGATION, null /* no values */),
APPROVER(SchemaConstants.ORG_APPROVER, "Approver", RelationKindType.APPROVER, null, ADMINISTRATION, GOVERNANCE, ORGANIZATION, SELF_SERVICE),
OWNER(SchemaConstants.ORG_OWNER, "Owner", RelationKindType.OWNER, null, ADMINISTRATION, GOVERNANCE, ORGANIZATION, SELF_SERVICE),
Expand Down
Expand Up @@ -150,7 +150,7 @@ public abstract class SchemaConstants {

/**
* Default membership relation. Used as a relation value in object references.
* See RelationKind.MEMBERSHIP for more details.
* See RelationKind.MEMBER for more details.
*/
public static final QName ORG_DEFAULT = new QName(NS_ORG, "default");

Expand Down
Expand Up @@ -78,11 +78,19 @@ class IndexedRelationDefinitions {
/**
* Relations to be processed on login. Each relation is listed here under all its names.
*/
@NotNull private final Set<QName> relationsToProcessOnLogin;
@NotNull private final Set<QName> relationsProcessedOnLogin;
/**
* Relations to be processed on recompute. Each relation is listed here under all its names.
*/
@NotNull private final Set<QName> relationsToProcessOnRecompute;
@NotNull private final Set<QName> relationsProcessedOnRecompute;
/**
* Relations to be stored into parentOrgRef item. Each relation is listed here under all its names.
*/
@NotNull private final Set<QName> relationsStoredIntoParentOrgRef;
/**
* Relations to be automatically matched by order constraints. Each relation is listed here under all its names.
*/
@NotNull private final Set<QName> relationsAutomaticallyMatched;
/**
* Aliases for each normalized relation QName.
*/
Expand All @@ -99,16 +107,17 @@ class IndexedRelationDefinitions {
defaultRelationByKind = computeDefaultRelationByKind();

addDefaultRelationToMaps();

relationsToProcessOnLogin = computeRelationsToProcessOnLogin();
relationsToProcessOnRecompute = computeRelationsToProcessOnRecompute();

aliases = computeAliases();

relationsProcessedOnLogin = computeRelationsProcessedOnLogin();
relationsProcessedOnRecompute = computeRelationsProcessedOnRecompute();
relationsStoredIntoParentOrgRef = computeRelationsStoredIntoParentOrgRef();
relationsAutomaticallyMatched = computeRelationsAutomaticallyMatched();
logState();
}

private void addDefaultRelationToMaps() {
QName defaultRelation = defaultRelationByKind.get(RelationKindType.MEMBERSHIP);
QName defaultRelation = defaultRelationByKind.get(RelationKindType.MEMBER);
if (defaultRelation != null) {
relationDefinitionsByRelationName.put(null, relationDefinitionsByRelationName.get(defaultRelation));
kindsByRelationName.putAll(null, kindsByRelationName.get(defaultRelation));
Expand All @@ -121,15 +130,17 @@ private void logState() {
LOGGER.trace("relationDefinitionsByRelationName = {}", relationDefinitionsByRelationName);
LOGGER.trace("relationsByKind = {}", relationsByKind);
LOGGER.trace("defaultRelationByKind = {}", defaultRelationByKind);
LOGGER.trace("relationsToProcessOnLogin = {}", relationsToProcessOnLogin);
LOGGER.trace("relationsToProcessOnRecompute = {}", relationsToProcessOnRecompute);
LOGGER.trace("aliases = {}", aliases);
LOGGER.trace("relationsProcessedOnLogin = {}", relationsProcessedOnLogin);
LOGGER.trace("relationsProcessedOnRecompute = {}", relationsProcessedOnRecompute);
LOGGER.trace("relationsStoredIntoParentOrgRef = {}", relationsStoredIntoParentOrgRef);
LOGGER.trace("relationsAutomaticallyMatched = {}", relationsAutomaticallyMatched);
}
}

private List<RelationDefinitionType> validateDefinitions(@NotNull List<RelationDefinitionType> definitions) {
List<RelationDefinitionType> validatedDefinitions = new ArrayList<>(definitions.size());
boolean membershipRelationExists = false;
boolean memberRelationExists = false;
for (RelationDefinitionType definition : definitions) {
if (definition.getRef() == null) {
LOGGER.error("Relation definition with null ref; ignoring: {}", definition);
Expand All @@ -138,12 +149,12 @@ private List<RelationDefinitionType> validateDefinitions(@NotNull List<RelationD
LOGGER.warn("Unqualified relation name '{}'; please fix it as soon as possible; in {}", definition.getRef(), definition);
}
validatedDefinitions.add(definition);
if (!membershipRelationExists && definition.getKind().contains(RelationKindType.MEMBERSHIP)) {
membershipRelationExists = true;
if (!memberRelationExists && definition.getKind().contains(RelationKindType.MEMBER)) {
memberRelationExists = true;
}
}
}
if (!membershipRelationExists) {
if (!memberRelationExists) {
LOGGER.error("No 'member' relation was defined. This would be a fatal condition, so we define one.");
validatedDefinitions.add(RelationRegistryImpl.createRelationDefinitionFromStaticDefinition(RelationTypes.MEMBER));
}
Expand Down Expand Up @@ -219,6 +230,7 @@ private SetValuedMap<RelationKindType, QName> computeRelationsByKind() {
}

// not optimized for speed
@SuppressWarnings("unused")
@NotNull
private Collection<QName> getAllRelationNamesFor(RelationKindType kind) {
Set<QName> rv = new HashSet<>();
Expand Down Expand Up @@ -262,23 +274,73 @@ private Map<RelationKindType, QName> computeDefaultRelationByKind() {
return rv;
}

// We want to make this configurable in the future MID-3581
private Set<QName> computeRelationsToProcessOnLogin() {
private Set<QName> computeRelationsProcessedOnLogin() {
HashSet<QName> rv = new HashSet<>();
rv.addAll(getAllRelationNamesFor(RelationKindType.MEMBERSHIP));
rv.addAll(getAllRelationNamesFor(RelationKindType.DELEGATION));
for (Map.Entry<QName, RelationDefinitionType> entry : relationDefinitionsByRelationName.entrySet()) {
Boolean configured = entry.getValue().isProcessedOnLogin();
if (Boolean.TRUE.equals(configured) || configured == null && isProcessedOnLoginByDefault(entry.getValue().getRef())) {
rv.addAll(getAliases(entry.getKey()));
}
}
return rv;
}

// We want to make this configurable in the future MID-3581
private Set<QName> computeRelationsToProcessOnRecompute() {
private boolean isProcessedOnLoginByDefault(QName relation) {
return isOfKind(relation, RelationKindType.MEMBER)
|| isOfKind(relation, RelationKindType.META)
|| isOfKind(relation, RelationKindType.DELEGATION);
}

private Set<QName> computeRelationsProcessedOnRecompute() {
HashSet<QName> rv = new HashSet<>();
rv.addAll(getAllRelationsFor(RelationKindType.MEMBERSHIP));
rv.addAll(getAllRelationsFor(RelationKindType.MANAGER));
rv.addAll(getAllRelationsFor(RelationKindType.DELEGATION));
for (Map.Entry<QName, RelationDefinitionType> entry : relationDefinitionsByRelationName.entrySet()) {
Boolean configured = entry.getValue().isProcessedOnRecompute();
if (Boolean.TRUE.equals(configured) || configured == null && isProcessedOnRecomputeByDefault(entry.getValue().getRef())) {
rv.addAll(getAliases(entry.getKey()));
}
}
return rv;
}

private boolean isProcessedOnRecomputeByDefault(QName relation) {
return isOfKind(relation, RelationKindType.MEMBER)
|| isOfKind(relation, RelationKindType.META)
|| isOfKind(relation, RelationKindType.MANAGER) // ok?
|| isOfKind(relation, RelationKindType.DELEGATION);
}

private Set<QName> computeRelationsStoredIntoParentOrgRef() {
HashSet<QName> rv = new HashSet<>();
for (Map.Entry<QName, RelationDefinitionType> entry : relationDefinitionsByRelationName.entrySet()) {
Boolean configured = entry.getValue().isStoredIntoParentOrgRef();
if (Boolean.TRUE.equals(configured) || configured == null && isStoredIntoParentOrgRefByDefault(entry.getValue().getRef())) {
rv.addAll(getAliases(entry.getKey()));
}
}
return rv;
}

private boolean isStoredIntoParentOrgRefByDefault(QName relation) {
return isOfKind(relation, RelationKindType.MEMBER);
}

private Set<QName> computeRelationsAutomaticallyMatched() {
HashSet<QName> rv = new HashSet<>();
for (Map.Entry<QName, RelationDefinitionType> entry : relationDefinitionsByRelationName.entrySet()) {
Boolean configured = entry.getValue().isAutomaticallyMatched();
if (Boolean.TRUE.equals(configured) || configured == null && isAutomaticallyMatchedByDefault(entry.getValue().getRef())) {
rv.addAll(getAliases(entry.getKey()));
}
}
return rv;
}

private boolean isAutomaticallyMatchedByDefault(QName relation) {
return isOfKind(relation, RelationKindType.MEMBER)
|| isOfKind(relation, RelationKindType.META)
|| isOfKind(relation, RelationKindType.DELEGATION);
}

private SetValuedMap<QName, QName> computeAliases() {
SetValuedMap<QName, QName> rv = new HashSetValuedHashMap<>();
for (Map.Entry<QName, RelationDefinitionType> entry : relationDefinitionsByRelationName.entrySet()) {
Expand All @@ -304,17 +366,20 @@ boolean isOfKind(QName relation, RelationKindType kind) {
return relationKinds != null && relationKinds.contains(kind);
}

boolean processRelationOnLogin(QName relation) {
return relationsToProcessOnLogin.contains(relation);
boolean isProcessedOnLogin(QName relation) {
return relationsProcessedOnLogin.contains(relation);
}

boolean isProcessedOnRecompute(QName relation) {
return relationsProcessedOnRecompute.contains(relation);
}

boolean processRelationOnRecompute(QName relation) {
return relationsToProcessOnRecompute.contains(relation);
boolean isStoredIntoParentOrgRef(QName relation) {
return relationsStoredIntoParentOrgRef.contains(relation);
}

// We want to make this configurable in the future MID-3581
public boolean includeIntoParentOrgRef(QName relation) {
return isOfKind(relation, RelationKindType.MEMBERSHIP) && !isOfKind(relation, RelationKindType.META);
boolean isAutomaticallyMatched(QName relation) {
return relationsAutomaticallyMatched.contains(relation);
}

QName getDefaultRelationFor(RelationKindType kind) {
Expand Down
Expand Up @@ -56,7 +56,7 @@ public void applyRelationConfiguration(SystemConfigurationType systemConfigurati
RelationsDefinitionType relationsDef = roleManagement != null ? roleManagement.getRelations() : null;
LOGGER.info("Applying relation configuration ({} entries)", relationsDef != null ? relationsDef.getRelation().size() : 0);
indexedRelationDefinitions = createAndIndexRelationDefinitions(relationsDef);
prismContext.setDefaultRelation(indexedRelationDefinitions.getDefaultRelationFor(RelationKindType.MEMBERSHIP));
prismContext.setDefaultRelation(indexedRelationDefinitions.getDefaultRelationFor(RelationKindType.MEMBER));
}

public List<RelationDefinitionType> getRelationDefinitions() {
Expand Down Expand Up @@ -125,18 +125,23 @@ public boolean isOfKind(QName relation, RelationKindType kind) {
}

@Override
public boolean processRelationOnLogin(QName relation) {
return indexedRelationDefinitions.processRelationOnLogin(relation);
public boolean isProcessedOnLogin(QName relation) {
return indexedRelationDefinitions.isProcessedOnLogin(relation);
}

@Override
public boolean processRelationOnRecompute(QName relation) {
return indexedRelationDefinitions.processRelationOnRecompute(relation);
public boolean isProcessedOnRecompute(QName relation) {
return indexedRelationDefinitions.isProcessedOnRecompute(relation);
}

@Override
public boolean includeIntoParentOrgRef(QName relation) {
return indexedRelationDefinitions.includeIntoParentOrgRef(relation);
public boolean isStoredIntoParentOrgRef(QName relation) {
return indexedRelationDefinitions.isStoredIntoParentOrgRef(relation);
}

@Override
public boolean isAutomaticallyMatched(QName relation) {
return indexedRelationDefinitions.isAutomaticallyMatched(relation);
}

@Override
Expand All @@ -152,7 +157,7 @@ public Collection<QName> getAllRelationsFor(RelationKindType kind) {

@Override
public QName getDefaultRelation() {
return getDefaultRelationFor(RelationKindType.MEMBERSHIP);
return getDefaultRelationFor(RelationKindType.MEMBER);
}

@NotNull
Expand Down

0 comments on commit 109434f

Please sign in to comment.