Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Jul 6, 2021
2 parents 4c26231 + 5b89d34 commit a70ed50
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 14 deletions.
2 changes: 1 addition & 1 deletion repo/repo-sqale/sql/pgnew-repo.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ CREATE TABLE m_task (
CHECK (objectType = 'TASK'),
taskIdentifier TEXT,
binding TaskBindingType,
category TEXT,
category TEXT, -- TODO revise, deprecated, probably can go away soon
completionTimestamp TIMESTAMPTZ,
executionStatus TaskExecutionStateType,
fullResult BYTEA,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,18 @@ public Integer processCacheableRelation(QName qName) {
QNameUtil.qNameToUri(normalizeRelation(qName)));
}

public String resolveIdToUri(Integer uriId) {
return uriId != null
? uriCache.resolveToUri(uriId)
: null;
}

public QName resolveUriIdToQName(Integer uriId) {
return uriId != null
? QNameUtil.uriToQName(uriCache.resolveToUri(uriId))
: null;
}

public @NotNull MExtItem resolveExtensionItem(@NotNull MExtItem.Key extItemKey) {
return extItemCache.resolveExtensionItem(extItemKey);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ protected ItemSqlMapper<Q, R> multiUriMapper(
((SqaleRepoContext) ctx.repositoryContext())::processCacheableUri));
}

/**
* Implemented for searchable containers that do not use fullObject for their recreation.
*/
@Override
public S toSchemaObject(R row) {
throw new UnsupportedOperationException("Use toSchemaObject(Tuple,...)");
Expand Down Expand Up @@ -256,8 +259,8 @@ protected void processExtensionColumns(S schemaObject, Tuple tuple, Q entityPath
* Fails if OID is not null and {@code repoObjectType} is null.
*/
@Nullable
protected ObjectReferenceType objectReferenceType(
@Nullable String oid, MObjectType repoObjectType, String targetName) {
protected ObjectReferenceType objectReference(
@Nullable UUID oid, MObjectType repoObjectType, Integer relationId) {
if (oid == null) {
return null;
}
Expand All @@ -267,10 +270,9 @@ protected ObjectReferenceType objectReferenceType(
}

return new ObjectReferenceType()
.oid(oid)
.oid(oid.toString())
.type(repositoryContext().schemaClassToQName(repoObjectType.getSchemaType()))
.description(targetName)
.targetName(targetName);
.relation(resolveUriIdToQName(relationId));
}

/**
Expand Down Expand Up @@ -321,6 +323,14 @@ protected Integer[] processCacheableUris(List<String> uris) {
.toArray(Integer[]::new);
}

public String resolveIdToUri(Integer uriId) {
return repositoryContext().resolveIdToUri(uriId);
}

public QName resolveUriIdToQName(Integer uriId) {
return repositoryContext().resolveUriIdToQName(uriId);
}

protected @Nullable UUID oidToUUid(@Nullable String oid) {
return oid != null ? UUID.fromString(oid) : null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,70 @@ private QAssignmentMapping(
repositoryContext));
}

@Override
public AssignmentType toSchemaObject(MAssignment row) {
AssignmentType assignment = new AssignmentType();
// TODO is there any place we can put row.ownerOid reasonably?
// repositoryContext().prismContext().itemFactory().createObject(... definition?)
// assignment.asPrismContainerValue().setParent(new ObjectType().oid(own)); abstract not possible
// For assignments we can use ownerType, but this is not general for all containers.
assignment.id(row.cid)
.lifecycleState(row.lifecycleState)
.order(row.orderValue)
.orgRef(objectReference(row.orgRefTargetOid,
row.orgRefTargetType, row.orgRefRelationId))
.targetRef(objectReference(row.targetRefTargetOid,
row.targetRefTargetType, row.targetRefRelationId))
.tenantRef(objectReference(row.tenantRefTargetOid,
row.tenantRefTargetType, row.tenantRefRelationId));

// TODO extId/extOid - if meaningful for new repo

// TODO ext... wouldn't serialized fullObject part of the assignment be better after all?

if (row.policySituations != null) {
for (Integer policySituationId : row.policySituations) {
assignment.policySituation(resolveIdToUri(policySituationId));
}
}

if (row.resourceRefTargetOid != null) {
assignment.construction(new ConstructionType(prismContext())
.resourceRef(objectReference(row.resourceRefTargetOid,
row.resourceRefTargetType, row.resourceRefRelationId)));
}

ActivationType activation = new ActivationType(prismContext());
activation.administrativeStatus(row.administrativeStatus);
activation.effectiveStatus(row.effectiveStatus);
activation.enableTimestamp(MiscUtil.asXMLGregorianCalendar(row.enableTimestamp));
activation.disableTimestamp(MiscUtil.asXMLGregorianCalendar(row.disableTimestamp));
activation.disableReason(row.disableReason);
activation.validityStatus(row.validityStatus);
activation.validFrom(MiscUtil.asXMLGregorianCalendar(row.validFrom));
activation.validTo(MiscUtil.asXMLGregorianCalendar(row.validTo));
activation.validityChangeTimestamp(MiscUtil.asXMLGregorianCalendar(row.validityChangeTimestamp));
activation.archiveTimestamp(MiscUtil.asXMLGregorianCalendar(row.archiveTimestamp));
if (!activation.asPrismContainerValue().isEmpty()) {
assignment.activation(activation);
}

MetadataType metadata = new MetadataType(prismContext());
metadata.creatorRef(objectReference(row.creatorRefTargetOid,
row.creatorRefTargetType, row.creatorRefRelationId));
metadata.createChannel(resolveIdToUri(row.createChannelId));
metadata.createTimestamp(MiscUtil.asXMLGregorianCalendar(row.createTimestamp));
metadata.modifierRef(objectReference(row.modifierRefTargetOid,
row.modifierRefTargetType, row.modifierRefRelationId));
metadata.modifyChannel(resolveIdToUri(row.modifyChannelId));
metadata.modifyTimestamp(MiscUtil.asXMLGregorianCalendar(row.modifyTimestamp));
if (!metadata.asPrismContainerValue().isEmpty()) {
assignment.metadata(metadata);
}

return assignment;
}

@Override
protected QAssignment<OR> newAliasInstance(String alias) {
return new QAssignment<>(alias);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
*/
package com.evolveum.midpoint.repo.sqale.qmodel.common;

import com.evolveum.midpoint.util.exception.SchemaException;

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.mapping.QOwnedByMapping;
import com.evolveum.midpoint.repo.sqale.mapping.SqaleTableMapping;
import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.util.exception.SchemaException;

/**
* Mapping between {@link QContainer} and {@link Containerable}.
Expand Down Expand Up @@ -48,6 +47,12 @@ protected QContainerMapping(
// CID is not mapped directly, it is used by path resolver elsewhere
}

/** Implemented for searchable containers. */
@Override
public S toSchemaObject(R row) {
throw new UnsupportedOperationException("Implemented in subclasses only");
}

@Override
protected Q newAliasInstance(String alias) {
//noinspection unchecked
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,14 @@ protected void setName(MObject object, String origName) {
object.nameNorm = prismContext.getDefaultPolyStringNormalizer().normalize(origName);
}

protected java.util.function.Predicate<? super Referencable> refMatcher(UUID targetOid, QName relation) {
protected java.util.function.Predicate<? super Referencable> refMatcher(
UUID targetOid, QName relation) {
return ref -> ref.getOid().equals(targetOid.toString())
&& ref.getRelation().equals(relation);
}

protected java.util.function.Predicate<? super MReference> refRowMatcher(UUID targetOid, QName relation) {
protected java.util.function.Predicate<? super MReference> refRowMatcher(
UUID targetOid, QName relation) {
return ref -> ref.targetOid.equals(targetOid)
&& cachedUriById(ref.relationId).equals(QNameUtil.qNameToUri(relation));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismConstants;
import com.evolveum.midpoint.prism.path.ItemName;
Expand Down Expand Up @@ -151,11 +152,14 @@ public void initObjects() throws Exception {
.validFrom("2021-07-04T00:00:00Z")
.validTo("2022-07-04T00:00:00Z"))
.assignment(new AssignmentType(prismContext)
.lifecycleState("assignment1")
.lifecycleState("assignment1-1")
.orgRef(org1Oid, OrgType.COMPLEX_TYPE, relation1)
.activation(new ActivationType(prismContext)
.validFrom("2021-03-01T00:00:00Z")
.validTo("2022-07-04T00:00:00Z")))
.assignment(new AssignmentType(prismContext)
.lifecycleState("assignment1-2")
.order(1))
.extension(new ExtensionType(prismContext));
ExtensionType user1Extension = user1.getExtension();
addExtensionValue(user1Extension, "string", "string-value");
Expand Down Expand Up @@ -183,7 +187,7 @@ public void initObjects() throws Exception {

ExtensionType user1AssignmentExtension = new ExtensionType(prismContext);
user1.assignment(new AssignmentType(prismContext)
.lifecycleState("activationExt")
.lifecycleState("assignment1-3-ext")
.extension(user1AssignmentExtension));
addExtensionValue(user1AssignmentExtension, "integer", 47);
user1Oid = repositoryService.addObject(user1.asPrismObject(), null, result);
Expand Down Expand Up @@ -865,7 +869,7 @@ public void test316QueryWithTypeFilterForUnrelatedType() throws SchemaException
public void test320QueryWithExistsFilter() throws SchemaException {
searchUsersTest("matching the exists filter for assignment",
f -> f.exists(UserType.F_ASSIGNMENT)
.item(AssignmentType.F_LIFECYCLE_STATE).eq("assignment1"),
.item(AssignmentType.F_LIFECYCLE_STATE).eq("assignment1-1"),
user1Oid);
}

Expand Down Expand Up @@ -1535,6 +1539,28 @@ public void test595SearchObjectByNotIndexedExtensionFails() {
.hasMessageContaining("not indexed");
}

@Test
public void test600SearchContainersByOwnerId() throws SchemaException {
SearchResultList<AssignmentType> result = searchContainerTest(
"assignments by owner OID", AssignmentType.class, f -> f.ownerId(user1Oid));
assertThat(result)
.extracting(a -> a.getLifecycleState())
.containsExactlyInAnyOrder("assignment1-1", "assignment1-2", "assignment1-3-ext");
// more extensive test of one assignment instance
assertThat(result).filteredOn(a -> a.getLifecycleState().equals("assignment1-1"))
.singleElement()
.matches(a -> a.getConstruction() == null)
.matches(a -> a.getActivation().getValidFrom().equals(
createXMLGregorianCalendar("2021-03-01T00:00:00Z")))
.matches(a -> a.getActivation().getValidTo().equals(
createXMLGregorianCalendar("2022-07-04T00:00:00Z")))
.matches(a -> a.getOrgRef().getOid().equals(org1Oid))
.matches(a -> a.getOrgRef().getType().equals(OrgType.COMPLEX_TYPE))
.matches(a -> a.getOrgRef().getRelation().equals(relation1))
.matches(a -> a.getMetadata() == null);

}

// TODO multi-value EQ filter (IN semantics) is not supported YET (except for refs)
// endregion

Expand Down Expand Up @@ -1682,10 +1708,11 @@ private <T extends ObjectType> SearchResultList<T> searchObjects(
OperationResult operationResult,
SelectorOptions<GetOperationOptions>... selectorOptions)
throws SchemaException {
display("QUERY: " + query);
QueryType queryType = prismContext.getQueryConverter().createQueryType(query);
String serializedQuery = prismContext.xmlSerializer().serializeAnyData(
queryType, SchemaConstants.MODEL_EXTENSION_OBJECT_QUERY);
display("QUERY: " + serializedQuery);
display("Serialized QUERY: " + serializedQuery);

// sanity check if it's re-parsable
assertThat(prismContext.parserFor(serializedQuery).parseRealValue(QueryType.class))
Expand All @@ -1697,4 +1724,44 @@ private <T extends ObjectType> SearchResultList<T> searchObjects(
operationResult)
.map(p -> p.asObjectable());
}

private <T extends Containerable> SearchResultList<T> searchContainerTest(
String description, Class<T> type, Function<S_FilterEntryOrEmpty, S_FilterExit> filter)
throws SchemaException {
String typeName = type.getSimpleName().replaceAll("Type$", "").toLowerCase();
when("searching for " + typeName + "(s) " + description);
OperationResult operationResult = createOperationResult();
SearchResultList<T> result = searchContainers(type,
filter.apply(prismContext.queryFor(type)).build(),
operationResult);

then(typeName + "(s) " + description + " are returned");
assertThatOperationResult(operationResult).isSuccess();
return result;
}

/** Search containers using {@link ObjectQuery}. */
@SafeVarargs
@NotNull
private <T extends Containerable> SearchResultList<T> searchContainers(
@NotNull Class<T> type,
ObjectQuery query,
OperationResult operationResult,
SelectorOptions<GetOperationOptions>... selectorOptions)
throws SchemaException {
display("QUERY: " + query);
QueryType queryType = prismContext.getQueryConverter().createQueryType(query);
String serializedQuery = prismContext.xmlSerializer().serializeAnyData(
queryType, SchemaConstants.MODEL_EXTENSION_OBJECT_QUERY);
display("Serialized QUERY: " + serializedQuery);

// sanity check if it's re-parsable
assertThat(prismContext.parserFor(serializedQuery).parseRealValue(QueryType.class))
.isNotNull();
return repositoryService.searchContainers(
type,
query,
Arrays.asList(selectorOptions),
operationResult);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.repo.sqlbase.QueryException;
import com.evolveum.midpoint.repo.sqlbase.RepositoryException;
Expand Down Expand Up @@ -211,6 +212,10 @@ public SqlRepoContext repositoryContext() {
return repositoryContext;
}

public PrismContext prismContext() {
return repositoryContext.prismContext();
}

/**
* Creates new alias (entity path instance) with a defined name.
* You can also use {@link #defaultAlias()} if one alias in a query is enough.
Expand Down

0 comments on commit a70ed50

Please sign in to comment.