From 30eac25eb030243810cfddbb25050ba308534809 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Thu, 29 Apr 2021 15:08:23 +0200 Subject: [PATCH 01/33] repo-sqale: implemented deletion of container by value + test Solution is different then in old repo but very simple, new method RootUpdateContext#resolveContainerIdsForDeletedValues adds the IDs so the DB related code handles only "by CID" case. --- .../update/ContainerTableUpdateContext.java | 7 +-- .../update/NestedContainerUpdateContext.java | 2 +- .../repo/sqale/update/RootUpdateContext.java | 27 ++++++++- .../sqale/func/SqaleRepoModifyObjectTest.java | 59 +++++++++++++++---- 4 files changed, 76 insertions(+), 19 deletions(-) diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/ContainerTableUpdateContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/ContainerTableUpdateContext.java index e65089b48cd..4162e18a188 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/ContainerTableUpdateContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/ContainerTableUpdateContext.java @@ -16,13 +16,10 @@ import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping; /** - * Update context for owned containers stored in tables. + * Update context for multi-value containers stored in separate table. * This can be owned by the root object or another container. - * TODO - this is theory, before implementation: - * Updates are collected as the modifications are processed and then executed by the root context. - * Inserts are executed immediately to allow nested inserts (e.g. container inside the container). * - * @param schema type of the object stored in the owned (child) table + * @param schema type of the container stored in the owned table * @param type of entity path for the owned (child) table * @param row type related to the {@link Q} * @param owner row type diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/NestedContainerUpdateContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/NestedContainerUpdateContext.java index dac0ac2f7b9..cfed67e7bf7 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/NestedContainerUpdateContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/NestedContainerUpdateContext.java @@ -16,7 +16,7 @@ /** * Update context for nested containers stored in the same table used by the parent context. * - * @param schema type of the object mapped by nested mapping + * @param schema type of the container mapped by the nested mapping * @param entity query type that holds the data for the mapped attributes * @param row type related to the {@link Q} */ diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java index b2df16978a3..2e801abf9b8 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java @@ -14,7 +14,7 @@ import com.querydsl.core.types.Path; import com.querydsl.sql.dml.SQLUpdateClause; -import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy; import com.evolveum.midpoint.repo.sqale.ContainerValueIdGenerator; @@ -32,8 +32,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; /** - * TODO - * Adds execute that processes the modifications and finalizes the update of root entity. + * Root context of the update context tree, see {@link SqaleUpdateContext} for more information. * * @param schema type * @param type of entity path @@ -111,11 +110,33 @@ public QueryTableMapping mapping() { private void processModification(ItemDelta modification) throws RepositoryException, SchemaException { cidGenerator.processModification(modification); + resolveContainerIdsForDeletedValues(modification); modification.applyTo(getPrismObject()); new DelegatingItemDeltaProcessor(this).process(modification); } + private void resolveContainerIdsForDeletedValues(ItemDelta modification) { + if (!modification.isDelete()) { + return; + } + + PrismContainer container = + getPrismObject().findContainer(modification.getPath()); + if (container != null) { + for (PrismValue value : modification.getValuesToDelete()) { + //noinspection unchecked + PrismContainerValue pcv = (PrismContainerValue) value; + if (pcv.getId() == null) { + PrismContainerValue existingValue = container.findValue( + pcv, EquivalenceStrategy.REAL_VALUE_CONSIDER_DIFFERENT_IDS); + // We will set CID and use that for DB updates. + pcv.setId(existingValue.getId()); + } + } + } + } + /** * Executes all necessary SQL updates (including sub-entity inserts/deletes) * for the enclosed {@link #object}. diff --git a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoModifyObjectTest.java b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoModifyObjectTest.java index 84b41cb7ae5..7253b01ba32 100644 --- a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoModifyObjectTest.java +++ b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoModifyObjectTest.java @@ -1881,7 +1881,46 @@ public void test304MultipleModificationsOfExistingAssignment() } @Test - public void test305AddingAssignmentWithNewPrefilledCid() + public void test305DeleteAssignmentByContent() + throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException { + OperationResult result = createOperationResult(); + MUser originalRow = selectObjectByOid(QUser.class, user1Oid); + + given("delta deleting assignments without CID by equality for user 1"); + ObjectDelta delta = prismContext.deltaFor(UserType.class) + .item(UserType.F_ASSIGNMENT) + .delete(new AssignmentType(prismContext).order(50)) + .asObjectDelta(user1Oid); + + when("modifyObject is called"); + repositoryService.modifyObject(UserType.class, user1Oid, delta.getModifications(), result); + + then("operation is successful"); + assertThatOperationResult(result).isSuccess(); + + and("serialized form (fullObject) is updated and assignments with only order 50"); + UserType userObject = repositoryService.getObject(UserType.class, user1Oid, null, result) + .asObjectable(); + assertThat(userObject.getVersion()).isEqualTo(String.valueOf(originalRow.version + 1)); + List assignments = userObject.getAssignment(); + assertThat(assignments).hasSize(2) + .anyMatch(a -> a.getOrder().equals(47)) + // this one had order AND target ref, so it's no match + .anyMatch(ass -> ass.getOrder() == 50 && ass.getTargetRef() != null); + + and("corresponding assignment row is deleted"); + MUser row = selectObjectByOid(QUser.class, user1Oid); + assertThat(row.version).isEqualTo(originalRow.version + 1); + + QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + List aRows = select(a, a.ownerOid.eq(UUID.fromString(user1Oid))); + assertThat(aRows).hasSize(2) + .anyMatch(aRow -> aRow.orderValue.equals(47)) + .anyMatch(ass -> ass.orderValue == 50 && ass.targetRefTargetOid != null); + } + + @Test + public void test310AddingAssignmentWithNewPrefilledCid() throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException { OperationResult result = createOperationResult(); MUser originalRow = selectObjectByOid(QUser.class, user1Oid); @@ -1905,7 +1944,7 @@ public void test305AddingAssignmentWithNewPrefilledCid() .asObjectable(); assertThat(userObject.getVersion()).isEqualTo(String.valueOf(originalRow.version + 1)); List assignments = userObject.getAssignment(); - assertThat(assignments).hasSize(4) + assertThat(assignments).hasSize(3) .anyMatch(a -> a.getId().equals(originalRow.containerIdSeq)); and("new assignment row is created"); @@ -1915,13 +1954,13 @@ public void test305AddingAssignmentWithNewPrefilledCid() QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); List aRows = select(a, a.ownerOid.eq(UUID.fromString(user1Oid))); - assertThat(aRows).hasSize(4) + assertThat(aRows).hasSize(3) .anyMatch(aRow -> aRow.cid.equals(originalRow.containerIdSeq) && aRow.orderValue == 1); } @Test - public void test306DeleteAssignmentByCid() + public void test311DeleteAssignmentByCid() throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException { OperationResult result = createOperationResult(); MUser originalRow = selectObjectByOid(QUser.class, user1Oid); @@ -1944,7 +1983,7 @@ public void test306DeleteAssignmentByCid() .asObjectable(); assertThat(userObject.getVersion()).isEqualTo(String.valueOf(originalRow.version + 1)); List assignments = userObject.getAssignment(); - assertThat(assignments).hasSize(3) + assertThat(assignments).hasSize(2) .noneMatch(a -> a.getId().equals(originalRow.containerIdSeq - 1)); and("new assignment row is created"); @@ -1954,12 +1993,12 @@ public void test306DeleteAssignmentByCid() QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); List aRows = select(a, a.ownerOid.eq(UUID.fromString(user1Oid))); - assertThat(aRows).hasSize(3) + assertThat(aRows).hasSize(2) .noneMatch(aRow -> aRow.cid.equals(originalRow.containerIdSeq - 1)); } @Test - public void test307AddingAssignmentWithUsedBytFreeCid() + public void test312AddingAssignmentWithUsedBytFreeCid() throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException { OperationResult result = createOperationResult(); MUser originalRow = selectObjectByOid(QUser.class, user1Oid); @@ -1984,7 +2023,7 @@ public void test307AddingAssignmentWithUsedBytFreeCid() .asObjectable(); assertThat(userObject.getVersion()).isEqualTo(String.valueOf(originalRow.version + 1)); List assignments = userObject.getAssignment(); - assertThat(assignments).hasSize(4) + assertThat(assignments).hasSize(3) .anyMatch(a -> a.getId().equals(originalRow.containerIdSeq - 1)); and("new assignment row is created"); @@ -1994,7 +2033,7 @@ public void test307AddingAssignmentWithUsedBytFreeCid() QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); List aRows = select(a, a.ownerOid.eq(UUID.fromString(user1Oid))); - assertThat(aRows).hasSize(4) + assertThat(aRows).hasSize(3) .anyMatch(aRow -> aRow.cid.equals(originalRow.containerIdSeq - 1) && aRow.orderValue == 1); } @@ -2002,7 +2041,7 @@ public void test307AddingAssignmentWithUsedBytFreeCid() // TODO delete by pattern - as per ItemImpl.remove(V, EquivalenceStrategy) @Test - public void test309DeleteAllAssignments() + public void test319DeleteAllAssignments() throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException { OperationResult result = createOperationResult(); MUser originalRow = selectObjectByOid(QUser.class, user1Oid); From f84cc55286eebebd0a7cf9b4f987212640fb7ff1 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Thu, 29 Apr 2021 21:35:11 +0200 Subject: [PATCH 02/33] repo-sqale: implemented inducements in the assignment table + tests --- repo/repo-sqale/sql/pgnew-repo.sql | 47 +---- .../qmodel/ObjectTemplateSqlTransformer.java | 3 - .../qmodel/assignment/QAssignmentMapping.java | 23 ++- .../qmodel/focus/FocusSqlTransformer.java | 12 +- .../role/AbstractRoleSqlTransformer.java | 23 +++ .../repo/sqale/qmodel/role/MAbstractRole.java | 2 +- .../qmodel/role/QAbstractRoleMapping.java | 11 ++ .../repo/sqale/update/RootUpdateContext.java | 4 +- .../func/SqaleRepoAddDeleteObjectTest.java | 177 ++++++++++++++++-- 9 files changed, 236 insertions(+), 66 deletions(-) diff --git a/repo/repo-sqale/sql/pgnew-repo.sql b/repo/repo-sqale/sql/pgnew-repo.sql index 1e11f1f6dff..8523c04f5f8 100644 --- a/repo/repo-sqale/sql/pgnew-repo.sql +++ b/repo/repo-sqale/sql/pgnew-repo.sql @@ -1198,19 +1198,17 @@ CREATE INDEX m_form_name_orig_idx ON m_form (name_orig); ALTER TABLE m_form ADD CONSTRAINT m_form_name_norm_key UNIQUE (name_norm); -- endregion --- region Assignment/Inducement tables +-- region Assignment/Inducement table -- Represents AssignmentType, see https://wiki.evolveum.com/display/midPoint/Assignment -- and also https://wiki.evolveum.com/display/midPoint/Assignment+vs+Inducement --- TODO: if we never need mix of inducements and assignments then let's have two separate tables --- consult with Rado/Katka/Palo --- TODO: partitioning, not by object type, it's not even... hash-something? +-- TODO: partitioning, probably not by object type, it's not even... hash-something? -- select assignmentowner, count(*) From m_assignment group by assignmentowner; --1 45 (inducements) --0 48756229 --- abstract common structure for m_assignment and m_inducement -CREATE TABLE m_assignment_type ( - -- owner_oid + containerType from m_container, final specification in sub-tables - -- new column may avoid join to object for some queries +CREATE TABLE m_assignment ( + owner_oid UUID NOT NULL REFERENCES m_object_oid(oid) ON DELETE CASCADE, + -- this is different from other containers, this is not generated, app must provide it + containerType ContainerType NOT NULL CHECK (containerType IN ('ASSIGNMENT', 'INDUCEMENT')), owner_type ObjectType NOT NULL, lifecycleState TEXT/*VARCHAR(255)*/, orderValue INTEGER, @@ -1255,21 +1253,9 @@ CREATE TABLE m_assignment_type ( modifyChannel_id INTEGER, modifyTimestamp TIMESTAMPTZ, - -- create PRIMARY KEY (owner_oid, cid) on sub-tables - -- no need to index owner_oid, it's part of the PK index - - CHECK (FALSE) NO INHERIT -) - INHERITS(m_container); - -CREATE TABLE m_assignment ( - owner_oid UUID NOT NULL REFERENCES m_object_oid(oid) ON DELETE CASCADE, - containerType ContainerType GENERATED ALWAYS AS ('ASSIGNMENT') STORED, - PRIMARY KEY (owner_oid, cid) - -- no need to index owner_oid, it's part of the PK index ) - INHERITS(m_assignment_type); + INHERITS(m_container); CREATE INDEX m_assignment_policySituation_idx ON m_assignment USING GIN(policysituations gin__int_ops); CREATE INDEX m_assignment_ext_idx ON m_assignment USING gin (ext); @@ -1313,25 +1299,6 @@ ALTER TABLE m_assignment_ref_modify_approver ADD CONSTRAINT m_assignment_ref_mod FOREIGN KEY (owner_oid, assignment_cid) REFERENCES m_assignment (owner_oid, cid); -- TODO index targetOid, relation_id? - -CREATE TABLE m_inducement ( - owner_oid UUID NOT NULL REFERENCES m_object_oid(oid) ON DELETE CASCADE, - containerType ContainerType GENERATED ALWAYS AS ('INDUCEMENT') STORED, - - PRIMARY KEY (owner_oid, cid) - -- no need to index owner_oid, it's part of the PK index -) - INHERITS(m_assignment_type); - -CREATE INDEX m_inducement_ext_idx ON m_inducement USING gin (ext); -CREATE INDEX m_inducement_validFrom_idx ON m_inducement (validFrom); -CREATE INDEX m_inducement_validTo_idx ON m_inducement (validTo); -CREATE INDEX m_inducement_targetRef_targetOid_idx ON m_inducement (targetRef_targetOid); -CREATE INDEX m_inducement_tenantRef_targetOid_idx ON m_inducement (tenantRef_targetOid); -CREATE INDEX m_inducement_orgRef_targetOid_idx ON m_inducement (orgRef_targetOid); -CREATE INDEX m_inducement_resourceRef_targetOid_idx ON m_inducement (resourceRef_targetOid); - --- TODO other tables like for assignments needed? policy situations, refs? -- endregion -- region Other object containers diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java index d63494567a3..b4f23b44494 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java @@ -18,12 +18,9 @@ public class ObjectTemplateSqlTransformer extends ObjectSqlTransformer { - private final QObjectTemplateMapping mapping; - public ObjectTemplateSqlTransformer( SqlTransformerSupport transformerSupport, QObjectTemplateMapping mapping) { super(transformerSupport, mapping); - this.mapping = mapping; } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java index 35efcf9ae88..100b9b37c3a 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java @@ -8,9 +8,11 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType.*; +import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainerType; import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping; +import com.evolveum.midpoint.repo.sqale.qmodel.role.MAbstractRole; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; @@ -19,6 +21,10 @@ /** * Mapping between {@link QAssignment} and {@link AssignmentType}. + * There are separate instances for assignments and inducements and the instance also knows + * the {@link MAssignment#containerType} it should set. + * Only the instance for assignments is registered for queries as there is no way to distinguish + * between assignments and inducements when searching containers in the Query API anyway. * * @param type of the owner row */ @@ -27,13 +33,22 @@ public class QAssignmentMapping public static final String DEFAULT_ALIAS_NAME = "a"; - public static final QAssignmentMapping INSTANCE = new QAssignmentMapping<>(); + /** Default assignment mapping instance, for queries it works for inducements too. */ + public static final QAssignmentMapping INSTANCE = + new QAssignmentMapping<>(MContainerType.ASSIGNMENT); + + /** Inducement mapping instance, this must be used for inserting inducements. */ + public static final QAssignmentMapping INSTANCE_INDUCEMENT = + new QAssignmentMapping<>(MContainerType.INDUCEMENT); + + private final MContainerType containerType; // We can't declare Class>.class, so we cheat a bit. @SuppressWarnings({ "unchecked", "rawtypes" }) - private QAssignmentMapping() { + private QAssignmentMapping(MContainerType containerType) { super(QAssignment.TABLE_NAME, DEFAULT_ALIAS_NAME, AssignmentType.class, (Class) QAssignment.class); + this.containerType = containerType; // TODO OWNER_TYPE is new thing and can help avoid join to concrete object table // But this will likely require special treatment/heuristic. @@ -121,7 +136,9 @@ public AssignmentSqlTransformer createTransformer(SqlTransformerSupport tran @Override public MAssignment newRowObject() { - return new MAssignment(); + MAssignment row = new MAssignment(); + row.containerType = this.containerType; + return row; } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java index 266b2e10789..b37ea75b6f5 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java @@ -17,12 +17,14 @@ public class FocusSqlTransformer, R extends MFocus> extends ObjectSqlTransformer { - private final QFocusMapping mapping; - public FocusSqlTransformer( SqlTransformerSupport transformerSupport, QFocusMapping mapping) { super(transformerSupport, mapping); - this.mapping = mapping; + } + + @Override + protected QFocusMapping mapping() { + return (QFocusMapping) super.mapping(); } @SuppressWarnings("DuplicatedCode") // activation code duplicated with assignment @@ -79,8 +81,8 @@ public void storeRelatedEntities( super.storeRelatedEntities(row, schemaObject, jdbcSession); storeRefs(row, schemaObject.getLinkRef(), - mapping.projectionReferenceMapping(), jdbcSession); + mapping().projectionReferenceMapping(), jdbcSession); storeRefs(row, schemaObject.getPersonaRef(), - mapping.personaReferenceMapping(), jdbcSession); + mapping().personaReferenceMapping(), jdbcSession); } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/AbstractRoleSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/AbstractRoleSqlTransformer.java index 18ed811255f..6b7c83f22d0 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/AbstractRoleSqlTransformer.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/AbstractRoleSqlTransformer.java @@ -6,12 +6,16 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.role; +import java.util.List; + import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.qmodel.assignment.AssignmentSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.focus.FocusSqlTransformer; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AutoassignSpecificationType; public class AbstractRoleSqlTransformer< @@ -38,4 +42,23 @@ public AbstractRoleSqlTransformer( row.riskLevel = abstractRole.getRiskLevel(); return row; } + + @Override + public void storeRelatedEntities( + @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) { + super.storeRelatedEntities(row, schemaObject, jdbcSession); + + List inducement = schemaObject.getInducement(); + if (!inducement.isEmpty()) { + AssignmentSqlTransformer transformer = + mapping().inducementMapping().createTransformer(transformerSupport); + inducement.forEach(assignment -> + transformer.insert(assignment, row, jdbcSession)); + } + } + + @Override + protected QAbstractRoleMapping mapping() { + return (QAbstractRoleMapping) super.mapping(); + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/MAbstractRole.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/MAbstractRole.java index 3eed513b4aa..402cfa6f2ee 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/MAbstractRole.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/MAbstractRole.java @@ -13,7 +13,7 @@ */ public class MAbstractRole extends MFocus { - public Boolean autoAssignEnabled; + public Boolean autoAssignEnabled; // autoassign/enabled public String displayNameOrig; public String displayNameNorm; public String identifier; diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java index d85e5248d56..b0abeb426ef 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentMapping; import com.evolveum.midpoint.repo.sqale.qmodel.focus.QFocusMapping; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; @@ -48,6 +49,16 @@ protected QAbstractRoleMapping( addItemMapping(F_IDENTIFIER, stringMapper(q -> q.identifier)); addItemMapping(F_REQUESTABLE, booleanMapper(q -> q.requestable)); addItemMapping(F_RISK_LEVEL, stringMapper(q -> q.riskLevel)); + + addContainerTableMapping(F_INDUCEMENT, inducementMapping(), + joinOn((o, a) -> o.oid.eq(a.ownerOid))); + } + + /** Fixes rigid parametric types of static mapping instance to this instance. */ + @NotNull + public QAssignmentMapping inducementMapping() { + //noinspection unchecked + return (QAssignmentMapping) QAssignmentMapping.INSTANCE_INDUCEMENT; } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java index 2e801abf9b8..e5bf09f6a98 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java @@ -110,13 +110,13 @@ public QueryTableMapping mapping() { private void processModification(ItemDelta modification) throws RepositoryException, SchemaException { cidGenerator.processModification(modification); - resolveContainerIdsForDeletedValues(modification); + resolveContainerIdsForValuesToDelete(modification); modification.applyTo(getPrismObject()); new DelegatingItemDeltaProcessor(this).process(modification); } - private void resolveContainerIdsForDeletedValues(ItemDelta modification) { + private void resolveContainerIdsForValuesToDelete(ItemDelta modification) { if (!modification.isDelete()) { return; } diff --git a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java index 0a306423b86..5c4fcca0a18 100644 --- a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java +++ b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java @@ -24,9 +24,7 @@ import com.evolveum.midpoint.repo.sqale.SqaleRepoBaseTest; import com.evolveum.midpoint.repo.sqale.qmodel.accesscert.MAccessCertificationDefinition; import com.evolveum.midpoint.repo.sqale.qmodel.accesscert.QAccessCertificationDefinition; -import com.evolveum.midpoint.repo.sqale.qmodel.assignment.MAssignmentReference; -import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentReference; -import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentReferenceMapping; +import com.evolveum.midpoint.repo.sqale.qmodel.assignment.*; import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainer; import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainerType; import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainer; @@ -48,6 +46,8 @@ import com.evolveum.midpoint.repo.sqale.qmodel.report.QReportData; import com.evolveum.midpoint.repo.sqale.qmodel.resource.MResource; import com.evolveum.midpoint.repo.sqale.qmodel.resource.QResource; +import com.evolveum.midpoint.repo.sqale.qmodel.role.MArchetype; +import com.evolveum.midpoint.repo.sqale.qmodel.role.QArchetype; import com.evolveum.midpoint.repo.sqale.qmodel.shadow.MShadow; import com.evolveum.midpoint.repo.sqale.qmodel.shadow.QShadow; import com.evolveum.midpoint.repo.sqale.qmodel.system.QSystemConfiguration; @@ -75,14 +75,15 @@ public void test100AddNamedUserWithoutOidWorksOk() .name(userName); when("adding it to the repository"); - repositoryService.addObject(userType.asPrismObject(), null, result); + String returnedOid = repositoryService.addObject(userType.asPrismObject(), null, result); then("operation is successful and user row for it is created"); assertThatOperationResult(result).isSuccess(); + assertThat(returnedOid).isEqualTo(userType.getOid()); QUser u = aliasFor(QUser.class); MUser row = selectOne(u, u.nameOrig.eq(userName)); - assertThat(row.oid).isNotNull(); + assertThat(row.oid).isEqualTo(UUID.fromString(returnedOid)); assertThat(row.nameNorm).isNotNull(); // normalized name is stored assertThat(row.version).isEqualTo(1); // initial version is set // read-only column with value generated/stored in the database @@ -402,7 +403,7 @@ public void test800SystemConfigurationBasicObjectAttributes() throws Exception { .creatorRef(creatorRefOid.toString(), UserType.COMPLEX_TYPE, relation1) .createChannel("create-channel") .createTimestamp(MiscUtil.asXMLGregorianCalendar(1L)) - .modifierRef(modifierRefOid.toString(), ServiceType.COMPLEX_TYPE, relation2) + .modifierRef(modifierRefOid.toString(), UserType.COMPLEX_TYPE, relation2) .modifyChannel("modify-channel") .modifyTimestamp(MiscUtil.asXMLGregorianCalendar(2L))); @@ -433,7 +434,7 @@ public void test800SystemConfigurationBasicObjectAttributes() throws Exception { assertCachedUri(row.createChannelId, "create-channel"); assertThat(row.createTimestamp).isEqualTo(Instant.ofEpochMilli(1)); assertThat(row.modifierRefTargetOid).isEqualTo(modifierRefOid); - assertThat(row.modifierRefTargetType).isEqualTo(MObjectType.SERVICE); + assertThat(row.modifierRefTargetType).isEqualTo(MObjectType.USER); assertCachedUri(row.modifierRefRelationId, relation2); assertCachedUri(row.modifyChannelId, "modify-channel"); assertThat(row.modifyTimestamp).isEqualTo(Instant.ofEpochMilli(2)); @@ -536,6 +537,114 @@ public void test802ContainerOperationExecution() throws Exception { // this time we didn't test assigned CID or CID SEQ value on owner (see test801) } + @Test + public void test803ContainerAssignment() throws Exception { + OperationResult result = createOperationResult(); + + given("object with assignments"); + String objectName = "sc" + getTestNumber(); + UUID orgRefOid = UUID.randomUUID(); + UUID targetRefOid = UUID.randomUUID(); + UUID tenantRefOid = UUID.randomUUID(); + UUID resourceRefOid = UUID.randomUUID(); + UUID creatorRefOid = UUID.randomUUID(); + UUID modifierRefOid = UUID.randomUUID(); + QName relation1 = QName.valueOf("{https://random.org/ns}random-rel-1"); + QName relation2 = QName.valueOf("{https://random.org/ns}random-rel-2"); + SystemConfigurationType object = new SystemConfigurationType(prismContext) + .name(objectName) + .assignment(new AssignmentType(prismContext) + .lifecycleState("lifecycle-state") + .order(47) + .orgRef(orgRefOid.toString(), OrgType.COMPLEX_TYPE, relation1) + .targetRef(targetRefOid.toString(), RoleType.COMPLEX_TYPE, relation2) + .tenantRef(tenantRefOid.toString(), OrgType.COMPLEX_TYPE, relation2) + // TODO extId, extOid, ext? + .policySituation("policy-situation-1") + .policySituation("policy-situation-2") + .construction(new ConstructionType() + .resourceRef(resourceRefOid.toString(), + ResourceType.COMPLEX_TYPE, relation1)) + .activation(new ActivationType() + .administrativeStatus(ActivationStatusType.ENABLED) + .effectiveStatus(ActivationStatusType.DISABLED) + .enableTimestamp(MiscUtil.asXMLGregorianCalendar(3L)) + .disableTimestamp(MiscUtil.asXMLGregorianCalendar(4L)) + .disableReason("disable-reason") + .validityStatus(TimeIntervalStatusType.IN) + .validFrom(MiscUtil.asXMLGregorianCalendar(5L)) + .validTo(MiscUtil.asXMLGregorianCalendar(6L)) + .validityChangeTimestamp(MiscUtil.asXMLGregorianCalendar(7L)) + .archiveTimestamp(MiscUtil.asXMLGregorianCalendar(8L))) + .metadata(new MetadataType() + // multi-value approver refs are tested elsewhere + .creatorRef(creatorRefOid.toString(), UserType.COMPLEX_TYPE, relation1) + .createChannel("create-channel") + .createTimestamp(MiscUtil.asXMLGregorianCalendar(1L)) + .modifierRef(modifierRefOid.toString(), UserType.COMPLEX_TYPE, relation2) + .modifyChannel("modify-channel") + .modifyTimestamp(MiscUtil.asXMLGregorianCalendar(2L)))) + // one more just to see it stores multiple assignments + .assignment(new AssignmentType().order(1)); + + when("adding it to the repository"); + repositoryService.addObject(object.asPrismObject(), null, result); + + then("it is stored and rows to child tables are inserted"); + assertThatOperationResult(result).isSuccess(); + + QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + List aRows = select(a, a.ownerOid.eq(UUID.fromString(object.getOid()))); + assertThat(aRows).hasSize(2) + .allMatch(ar -> ar.orderValue != null); + + MAssignment row = aRows.stream() + .filter(ar -> ar.orderValue == 47) + .findFirst().orElseThrow(); + + assertThat(row.lifecycleState).isEqualTo("lifecycle-state"); + assertThat(row.orderValue).isEqualTo(47); + assertThat(row.orgRefTargetOid).isEqualTo(orgRefOid); + assertThat(row.orgRefTargetType).isEqualTo(MObjectType.ORG); + assertCachedUri(row.orgRefRelationId, relation1); + assertThat(row.targetRefTargetOid).isEqualTo(targetRefOid); + assertThat(row.targetRefTargetType).isEqualTo(MObjectType.ROLE); + assertCachedUri(row.targetRefRelationId, relation2); + assertThat(row.tenantRefTargetOid).isEqualTo(tenantRefOid); + assertThat(row.tenantRefTargetType).isEqualTo(MObjectType.ORG); + assertCachedUri(row.tenantRefRelationId, relation2); + // complex DB columns + // TODO EXT + assertThat(resolveCachedUriIds(row.policySituations)) + .containsExactlyInAnyOrder("policy-situation-1", "policy-situation-2"); + // construction + assertThat(row.resourceRefTargetOid).isEqualTo(resourceRefOid); + assertThat(row.resourceRefTargetType).isEqualTo(MObjectType.RESOURCE); + assertCachedUri(row.resourceRefRelationId, relation1); + // activation + assertThat(row.administrativeStatus).isEqualTo(ActivationStatusType.ENABLED); + assertThat(row.effectiveStatus).isEqualTo(ActivationStatusType.DISABLED); + assertThat(row.enableTimestamp).isEqualTo(Instant.ofEpochMilli(3)); + assertThat(row.disableTimestamp).isEqualTo(Instant.ofEpochMilli(4)); + assertThat(row.disableReason).isEqualTo("disable-reason"); + assertThat(row.validityStatus).isEqualTo(TimeIntervalStatusType.IN); + assertThat(row.validFrom).isEqualTo(Instant.ofEpochMilli(5)); + assertThat(row.validTo).isEqualTo(Instant.ofEpochMilli(6)); + assertThat(row.validityChangeTimestamp).isEqualTo(Instant.ofEpochMilli(7)); + assertThat(row.archiveTimestamp).isEqualTo(Instant.ofEpochMilli(8)); + // metadata + assertThat(row.creatorRefTargetOid).isEqualTo(creatorRefOid); + assertThat(row.creatorRefTargetType).isEqualTo(MObjectType.USER); + assertCachedUri(row.creatorRefRelationId, relation1); + assertCachedUri(row.createChannelId, "create-channel"); + assertThat(row.createTimestamp).isEqualTo(Instant.ofEpochMilli(1)); + assertThat(row.modifierRefTargetOid).isEqualTo(modifierRefOid); + assertThat(row.modifierRefTargetType).isEqualTo(MObjectType.USER); + assertCachedUri(row.modifierRefRelationId, relation2); + assertCachedUri(row.modifyChannelId, "modify-channel"); + assertThat(row.modifyTimestamp).isEqualTo(Instant.ofEpochMilli(2)); + } + @Test public void test808LookupTable() throws Exception { OperationResult result = createOperationResult(); @@ -587,10 +696,6 @@ public void test808LookupTable() throws Exception { assertThat(containerRow.key).isEqualTo("row3"); } - // TODO test for object's related entities? - // - trigger - // - operation execution - @Test public void test810ResourceAndItsBusinessApproverReferences() throws Exception { OperationResult result = createOperationResult(); @@ -795,7 +900,7 @@ public void test818Shadow() throws Exception { assertThat(row.synchronizationTimestamp).isEqualTo(Instant.ofEpochMilli(2)); } - // this covers mapping of attributes in FocusSqlTransformer + GenericObject + // This covers mapping of attributes in FocusSqlTransformer + GenericObject. @Test public void test820GenericObject() throws Exception { OperationResult result = createOperationResult(); @@ -869,6 +974,54 @@ public void test820GenericObject() throws Exception { assertCachedUri(row.genericObjectTypeId, "some-custom-object-type-uri"); } + // This covers mapping of attributes in AbstractRole + Archetype + inducement mapping. + // There is no focus on FocusSqlTransformer that is covered above. + @Test + public void test821ArchetypeAndInducement() throws Exception { + OperationResult result = createOperationResult(); + + given("archetype object"); + String objectName = "arch" + getTestNumber(); + ArchetypeType archetype = new ArchetypeType(prismContext) + .name(objectName) + .autoassign(new AutoassignSpecificationType().enabled(true)) + .displayName("display-name") + .identifier("identifier") + .requestable(false) + .riskLevel("extremely-high") + // we don't need all attributes here, this is tested in TODO + .inducement(new AssignmentType() + .order(2) + .targetRef(UUID.randomUUID().toString(), RoleType.COMPLEX_TYPE)) + .inducement(new AssignmentType() + .order(3) + .targetRef(UUID.randomUUID().toString(), RoleType.COMPLEX_TYPE)); + // this is no additional attribute specific for archetype + + when("adding it to the repository"); + repositoryService.addObject(archetype.asPrismObject(), null, result); + + then("it is stored and relevant attributes are in columns"); + assertThatOperationResult(result).isSuccess(); + + UUID archetypeOid = UUID.fromString(archetype.getOid()); + MArchetype row = selectObjectByOid(QArchetype.class, archetypeOid); + // all attributes from MAbstractRole + assertThat(row.autoAssignEnabled).isTrue(); + assertThat(row.displayNameOrig).isEqualTo("display-name"); + assertThat(row.displayNameNorm).isEqualTo("displayname"); + assertThat(row.identifier).isEqualTo("identifier"); + assertThat(row.requestable).isFalse(); + assertThat(row.riskLevel).isEqualTo("extremely-high"); + + QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + assertThat(select(a, a.ownerOid.eq(archetypeOid))).hasSize(2) + .anyMatch(ar -> ar.orderValue.equals(2)) + .anyMatch(ar -> ar.orderValue.equals(3)) + .allMatch(ar -> ar.targetRefTargetOid != null + && ar.targetRefTargetType == MObjectType.ROLE); + } + // TODO test for focus' related entities? @Test From a27ceba488c69d75bd7402082abf82481ee570a5 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Thu, 29 Apr 2021 23:12:49 +0200 Subject: [PATCH 03/33] Add parameterized system performance test This is just an initial draft. --- .../test/AbstractModelIntegrationTest.java | 2 +- .../story/sysperf/ExtensionSchemaVariant.java | 51 + .../story/sysperf/PopulationVariant.java | 53 + .../story/sysperf/SourceInitializer.java | 80 + .../testing/story/sysperf/SourceVariant.java | 100 + .../story/sysperf/TemplateVariant.java | 43 + .../story/sysperf/TestSystemPerformance.java | 238 + .../story/sysperf/ThreadingVariant.java | 57 + .../system-perf/resource-source-ms0002.xml | 129 + .../system-perf/resource-source-ms0020.xml | 363 + .../system-perf/resource-source-ms0110.xml | 1535 ++++ .../schema-basic/user-extension-basic.xsd | 795 ++ .../user-extension-big-global.xsd | 7106 +++++++++++++++++ .../schema-big/user-extension-big.xsd | 7105 ++++++++++++++++ .../schema-indexed/user-extension-indexed.xsd | 795 ++ .../system-perf/system-configuration.xml | 94 + .../resources/system-perf/task-import-16t.xml | 28 + .../resources/system-perf/task-import-1t.xml | 27 + .../resources/system-perf/task-import-4t.xml | 28 + 19 files changed, 18628 insertions(+), 1 deletion(-) create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceInitializer.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TemplateVariant.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java create mode 100644 testing/story/src/test/resources/system-perf/resource-source-ms0002.xml create mode 100644 testing/story/src/test/resources/system-perf/resource-source-ms0020.xml create mode 100644 testing/story/src/test/resources/system-perf/resource-source-ms0110.xml create mode 100644 testing/story/src/test/resources/system-perf/schema-basic/user-extension-basic.xsd create mode 100644 testing/story/src/test/resources/system-perf/schema-big-global/user-extension-big-global.xsd create mode 100644 testing/story/src/test/resources/system-perf/schema-big/user-extension-big.xsd create mode 100644 testing/story/src/test/resources/system-perf/schema-indexed/user-extension-indexed.xsd create mode 100644 testing/story/src/test/resources/system-perf/system-configuration.xml create mode 100644 testing/story/src/test/resources/system-perf/task-import-16t.xml create mode 100644 testing/story/src/test/resources/system-perf/task-import-1t.xml create mode 100644 testing/story/src/test/resources/system-perf/task-import-4t.xml diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index e23743dec49..adbbdaa0f7d 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -269,7 +269,7 @@ protected DummyResourceContoller initDummyResource(String name, File resourceFil return dummyResourceCollection.initDummyResource(name, resourceFile, resourceOid, controllerInitLambda, task, result); } - protected DummyResourceContoller initDummyResource(DummyTestResource resource, Task task, OperationResult result) throws Exception { + public DummyResourceContoller initDummyResource(DummyTestResource resource, Task task, OperationResult result) throws Exception { resource.controller = dummyResourceCollection.initDummyResource(resource.name, resource.file, resource.oid, resource.controllerInitLambda, task, result); return resource.controller; diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java new file mode 100644 index 00000000000..5870a608bc8 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +enum ExtensionSchemaVariant { + + BASIC("basic"), + BIG("big"), + BIG_GLOBAL("big-global"), + INDEXED("indexed"); + + private static final String PROP_EXTENSION_SCHEMA = "schema"; + + private final String name; + + ExtensionSchemaVariant(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public String getExtensionSchemaDir() { + return "./src/test/resources/system-perf/schema-" + name; + } + + public static ExtensionSchemaVariant setup() { + String configuredSchemaVariant = System.getProperty(PROP_EXTENSION_SCHEMA, BASIC.name); + ExtensionSchemaVariant schemaVariant = fromName(configuredSchemaVariant); + System.out.println("Extension schema variant: " + schemaVariant); + String extensionSchemaDir = schemaVariant.getExtensionSchemaDir(); + System.out.println("Extension schema directory: " + extensionSchemaDir); + System.setProperty("midpoint.global.extensionDir", extensionSchemaDir); + return schemaVariant; + } + + private static ExtensionSchemaVariant fromName(String name) { + for (ExtensionSchemaVariant value : values()) { + if (value.name.equals(name)) { + return value; + } + } + throw new IllegalArgumentException("Unknown extension schema variant: " + name); + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java new file mode 100644 index 00000000000..fc5971206eb --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import com.evolveum.midpoint.test.DummyTestResource; + +enum PopulationVariant { + + P10("10", 10), + P1K("1k", 1000), + P10K("10k", 10000), + P100K("100k", 100_000), + P1M("1m", 1_000_000); + + private static final String PROP_POPULATION = "population"; + + private final String name; + private final int accounts; + + PopulationVariant(String name, int accounts) { + this.name = name; + this.accounts = accounts; + } + + public String getName() { + return name; + } + + public int getAccounts() { + return accounts; + } + + public static PopulationVariant setup() { + String configuredName = System.getProperty(PROP_POPULATION, P10.name); + PopulationVariant variant = fromName(configuredName); + System.out.println("Population variant: " + variant); + return variant; + } + + private static PopulationVariant fromName(String name) { + for (PopulationVariant value : values()) { + if (value.name.equals(name)) { + return value; + } + } + throw new IllegalArgumentException("Unknown population variant: " + name); + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceInitializer.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceInitializer.java new file mode 100644 index 00000000000..3d0f006426e --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceInitializer.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import com.evolveum.icf.dummy.resource.ConflictException; +import com.evolveum.icf.dummy.resource.DummyAccount; +import com.evolveum.icf.dummy.resource.ObjectAlreadyExistsException; +import com.evolveum.icf.dummy.resource.SchemaViolationException; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.DummyTestResource; + +import org.apache.commons.lang3.RandomStringUtils; + +import java.io.FileNotFoundException; +import java.net.ConnectException; + +public class SourceInitializer { + + private final TestSystemPerformance test; + private final DummyTestResource resource; + private final SourceVariant sourceVariant; + private final PopulationVariant populationVariant; + private final Task initTask; + + private static final String ACCOUNT_NAME = "u-%08d"; + + SourceInitializer(TestSystemPerformance test, DummyTestResource resource, SourceVariant sourceVariant, + PopulationVariant populationVariant, Task initTask) { + this.test = test; + this.resource = resource; + this.sourceVariant = sourceVariant; + this.populationVariant = populationVariant; + this.initTask = initTask; + } + + public void run(OperationResult result) throws Exception { + initializeResource(result); + createAccounts(); + } + + private void initializeResource(OperationResult result) throws Exception { + test.initDummyResource(resource, initTask, result); + } + + private void createAccounts() throws ConflictException, FileNotFoundException, SchemaViolationException, + ObjectAlreadyExistsException, InterruptedException, ConnectException { + for (int u = 0; u < populationVariant.getAccounts(); u++) { + createAccount(u); + } + } + + private void createAccount(int u) throws ObjectAlreadyExistsException, SchemaViolationException, ConnectException, + FileNotFoundException, ConflictException, InterruptedException { + String name = getAccountName(u); + DummyAccount account = resource.controller.addAccount(name); + addAttributes(account, SourceVariant.A_SINGLE_NAME, sourceVariant.getSingleValuedAttributes(), 1); + addAttributes(account, SourceVariant.A_MULTI_NAME, sourceVariant.getMultiValuedAttributes(), + sourceVariant.getAttributeValues()); + } + + String getAccountName(int u) { + return String.format(ACCOUNT_NAME, u); + } + + private void addAttributes(DummyAccount account, String namePattern, int attrs, int values) throws ConflictException, + FileNotFoundException, SchemaViolationException, InterruptedException, ConnectException { + for (int a = 0; a < attrs; a++) { + String attrName = String.format(namePattern, a); + for (int v = 0; v < values; v++) { + account.addAttributeValue(attrName, RandomStringUtils.random(10, true, true)); + } + } + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java new file mode 100644 index 00000000000..396ba8e503c --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import com.evolveum.icf.dummy.resource.ConflictException; +import com.evolveum.icf.dummy.resource.DummyObjectClass; +import com.evolveum.icf.dummy.resource.SchemaViolationException; +import com.evolveum.midpoint.test.DummyResourceContoller; +import com.evolveum.midpoint.test.DummyTestResource; + +import java.io.FileNotFoundException; +import java.net.ConnectException; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TEST_DIR; + +enum SourceVariant { + + MS2_5("ms2-5", "resource-source-ms0002.xml", 1, 1, 5), + MS20_5("ms20-5", "resource-source-ms0020.xml", 10, 10, 5), + MS110_5("ms110-5", "resource-source-ms0110.xml", 100, 10, 5), + MS110_1000("ms110-1000", "resource-source-ms0110.xml", 100, 10, 1000); + + private static final String PROP_SOURCE = "source"; + + public static final String RESOURCE_INSTANCE = "source"; + private static final String RESOURCE_OID = "7eb3a16c-3a33-4ef0-8523-98f0ef7291ba"; + public static final String A_SINGLE_NAME = "a-single-%04d"; + public static final String A_MULTI_NAME = "a-multi-%04d"; + + private final String name; + private final String fileName; + private final int singleValuedAttributes; + private final int multiValuedAttributes; + private final int attributeValues; + + SourceVariant(String name, String fileName, int singleValuedAttributes, int multiValuedAttributes, int attributeValues) { + this.name = name; + this.fileName = fileName; + this.singleValuedAttributes = singleValuedAttributes; + this.multiValuedAttributes = multiValuedAttributes; + this.attributeValues = attributeValues; + } + + public String getName() { + return name; + } + + public String getFileName() { + return fileName; + } + + public int getSingleValuedAttributes() { + return singleValuedAttributes; + } + + public int getMultiValuedAttributes() { + return multiValuedAttributes; + } + + public int getAttributeValues() { + return attributeValues; + } + + public static SourceVariant setup() { + String configuredName = System.getProperty(PROP_SOURCE, MS2_5.name); + SourceVariant sourceVariant = fromName(configuredName); + System.out.println("Source variant: " + sourceVariant); + return sourceVariant; + } + + private static SourceVariant fromName(String name) { + for (SourceVariant value : values()) { + if (value.name.equals(name)) { + return value; + } + } + throw new IllegalArgumentException("Unknown source resource variant: " + name); + } + + public DummyTestResource createDummyTestResource() { + return new DummyTestResource(TEST_DIR, fileName, RESOURCE_OID, RESOURCE_INSTANCE, + controller -> { + createAttributes(controller, A_SINGLE_NAME, singleValuedAttributes, false); + createAttributes(controller, A_MULTI_NAME, multiValuedAttributes, true); + }); + } + + private void createAttributes(DummyResourceContoller controller, String name, int number, boolean multi) + throws ConflictException, FileNotFoundException, SchemaViolationException, InterruptedException, ConnectException { + DummyObjectClass objectClass = controller.getDummyResource().getAccountObjectClass(); + for (int i = 0; i < number; i++) { + controller.addAttrDef(objectClass, String.format(name, i), String.class, false, multi); + } + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TemplateVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TemplateVariant.java new file mode 100644 index 00000000000..e969496753e --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TemplateVariant.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +enum TemplateVariant { + + NONE("none"), + T0010("t0010"), + T0100("t0100"); + + private static final String PROP_TEMPLATE = "template"; + + private final String name; + + TemplateVariant(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static TemplateVariant setup() { + String configuredName = System.getProperty(PROP_TEMPLATE, NONE.name); + TemplateVariant variant = fromName(configuredName); + System.out.println("Template variant: " + variant); + return variant; + } + + private static TemplateVariant fromName(String name) { + for (TemplateVariant value : values()) { + if (value.name.equals(name)) { + return value; + } + } + throw new IllegalArgumentException("Unknown template variant: " + name); + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java new file mode 100644 index 00000000000..c9273dd4e81 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.util.Date; + +import com.google.common.base.MoreObjects; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; + +import com.evolveum.midpoint.prism.PrismContainerDefinition; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismObjectDefinition; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.schema.internals.InternalsConfig; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.task.TaskOperationStatsUtil; +import com.evolveum.midpoint.schema.util.task.TaskPerformanceInformation; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.DummyAuditService; +import com.evolveum.midpoint.test.DummyTestResource; +import com.evolveum.midpoint.test.TestResource; +import com.evolveum.midpoint.test.util.MidPointTestConstants; +import com.evolveum.midpoint.testing.story.AbstractStoryTest; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationStatsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; + +/** + * Tests the overall system performance. Can be parameterized using Java properties. + * + * Examples: + * + * -Dpopulation=10k -Dthreading=16t -Dschema=basic -Dsource=ms2-5 + * -Dpopulation=100k -Dthreading=4t -Dschema=indexed -Dsource=ms110-5 + * -Dpopulation=10k -Dthreading=16t -Dschema=big-global -Dsource=ms110-1000 + */ +@ContextConfiguration(locations = { "classpath:ctx-story-test-main.xml" }) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +public class TestSystemPerformance extends AbstractStoryTest { + + public static final File TEST_DIR = new File(MidPointTestConstants.TEST_RESOURCES_DIR, "system-perf"); + + private static final File SYSTEM_CONFIGURATION_FILE = new File(TEST_DIR, "system-configuration.xml"); + + private static final ExtensionSchemaVariant EXTENSION_SCHEMA_VARIANT; + private static final SourceVariant SOURCE_VARIANT; + private static final ThreadingVariant THREADING_VARIANT; + private static final TemplateVariant TEMPLATE_VARIANT; + private static final PopulationVariant POPULATION_VARIANT; + + private static final DummyTestResource RESOURCE_SOURCE; + private static final TestResource TASK_IMPORT; + + private static final long START = System.currentTimeMillis(); + + private static final File SUMMARY_FILE = new File("./target", START + "-summary.txt"); + private PrintWriter summary; + + private static final File PROGRESS_FILE = new File("./target", START + "-progress.csv"); + private PrintWriter progress; + + private long lastProgress; + + private SourceInitializer sourceInitializer; + + static { + EXTENSION_SCHEMA_VARIANT = ExtensionSchemaVariant.setup(); + SOURCE_VARIANT = SourceVariant.setup(); + THREADING_VARIANT = ThreadingVariant.setup(); + TEMPLATE_VARIANT = TemplateVariant.setup(); + POPULATION_VARIANT = PopulationVariant.setup(); + + RESOURCE_SOURCE = SOURCE_VARIANT.createDummyTestResource(); + TASK_IMPORT = THREADING_VARIANT.getImportTaskResource(); + } + + @Override + public void initSystem(Task initTask, OperationResult initResult) throws Exception { + super.initSystem(initTask, initResult); + + DummyAuditService.getInstance().setEnabled(false); + + InternalsConfig.turnOffAllChecks(); + + sourceInitializer = new SourceInitializer(this, RESOURCE_SOURCE, SOURCE_VARIANT, POPULATION_VARIANT, initTask); + sourceInitializer.run(initResult); + + summary = new PrintWriter(new FileWriter(SUMMARY_FILE)); + + progress = new PrintWriter(new FileWriter(PROGRESS_FILE)); + progress.println("time;progress"); + + logStart(); + } + + @Override + protected boolean isAvoidLoggingChange() { + return false; // we want logging from our system config + } + + @Override + protected File getSystemConfigurationFile() { + return SYSTEM_CONFIGURATION_FILE; + } + + @Override + protected void importSystemTasks(OperationResult initResult) { + // nothing here + } + + @Test + public void test001DumpExtensionSchema() { + PrismObjectDefinition userDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); + PrismContainerDefinition userExtDef = userDef.getExtensionDefinition(); + System.out.println(userExtDef.debugDump()); + } + + @Test + public void test100Import() throws Exception { + given(); + + Task task = getTestTask(); + OperationResult result = task.getResult(); + + int usersBefore = repositoryService.countObjects(UserType.class, null, null, result); + + when(); + + addTask(TASK_IMPORT, result); + waitForTaskFinish(TASK_IMPORT.oid, false, 0, 1000000, false, 0, + builder -> builder.taskConsumer(this::recordProgress)); + + then(); + + int usersAfter = repositoryService.countObjects(UserType.class, null, null, result); + assertThat(usersAfter - usersBefore).as("users created").isEqualTo(POPULATION_VARIANT.getAccounts()); + + assertUserAfterByUsername(sourceInitializer.getAccountName(0)) + .assertLinks(1, 0) + .extension() + .assertSize(SOURCE_VARIANT.getSingleValuedAttributes() + SOURCE_VARIANT.getMultiValuedAttributes()) + .property(ItemPath.create(getSingleValuedPropertyName(0))) + .assertSize(1) + .end() + .property(ItemPath.create(getMultiValuedPropertyName(0))) + .assertSize(SOURCE_VARIANT.getAttributeValues()); + + PrismObject taskAfter = assertTask(TASK_IMPORT.oid, "after") + .display() + .getObject(); + + logFinish(taskAfter); + } + + private long getExecutionTime(PrismObject taskAfter) { + long start = XmlTypeConverter.toMillis(taskAfter.asObjectable().getLastRunStartTimestamp()); + long end = XmlTypeConverter.toMillis(taskAfter.asObjectable().getLastRunFinishTimestamp()); + return end - start; + } + + private String getSingleValuedPropertyName(int i) { + return String.format("p-single-%04d", i); + } + + private String getMultiValuedPropertyName(int i) { + return String.format("p-multi-%04d", i); + } + + private void logStart() { + logger.info("********** STARTED **********\n"); + logger.info("Extension schema variant: {}", EXTENSION_SCHEMA_VARIANT); + logger.info("Source variant: {}", SOURCE_VARIANT); + logger.info("Threading variant: {}", THREADING_VARIANT); + logger.info("Population variant: {}", POPULATION_VARIANT); + logger.info("Progress file: {}", PROGRESS_FILE); + + summary.println("Started: " + new Date(START) + " (" + START + ")"); + summary.printf("Extension schema variant: %s\n", EXTENSION_SCHEMA_VARIANT); + summary.printf("Source variant: %s\n", SOURCE_VARIANT); + summary.printf("Threading variant: %s\n", THREADING_VARIANT); + summary.printf("Population variant: %s\n", POPULATION_VARIANT); + summary.printf("Progress file: %s\n\n", PROGRESS_FILE); + summary.flush(); + } + + private void logFinish(PrismObject taskAfter) { + TaskPerformanceInformation performanceInformation = TaskPerformanceInformation.fromTaskTree(taskAfter.asObjectable()); + long executionTime = getExecutionTime(taskAfter); + + logger.info("********** FINISHED **********\n"); + logger.info("{}", String.format("Task execution time: %,d ms", executionTime)); + logger.info("{}", String.format("Time per account: %,.1f ms", (double) executionTime / (double) POPULATION_VARIANT.getAccounts())); + logger.info("{}", (TaskOperationStatsUtil.format(taskAfter.asObjectable().getOperationStats()))); + logger.info("{}", performanceInformation.debugDump()); + + summary.printf("********** FINISHED **********\n"); + summary.printf("Task execution time: %,d ms\n", executionTime); + summary.printf("Time per account: %,.1f ms\n", (double) executionTime / (double) POPULATION_VARIANT.getAccounts()); + summary.println(TaskOperationStatsUtil.format(taskAfter.asObjectable().getOperationStats())); + summary.println(performanceInformation.debugDump()); + summary.flush(); + } + + private void recordProgress(Task task) { + Long start = task.getLastRunStartTimestamp(); + long progress = task.getProgress(); + + if (start == null || progress == lastProgress) { + return; + } + lastProgress = progress; + + long end = MoreObjects.firstNonNull(task.getLastRunFinishTimestamp(), System.currentTimeMillis()); + long running = end - start; + this.progress.println(running + ";" + progress); + this.progress.flush(); + + OperationStatsType stats = task.getStoredOperationStatsOrClone(); + logger.info("\n{}", TaskOperationStatsUtil.format(stats)); + + TaskPerformanceInformation performanceInformation = TaskPerformanceInformation.fromTaskTree( + task.getRawTaskObjectClone().asObjectable()); + displayDumpable("performance", performanceInformation); + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java new file mode 100644 index 00000000000..9fabb6b0793 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import com.evolveum.midpoint.test.TestResource; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TEST_DIR; + +enum ThreadingVariant { + + T1("1t"), + T4("4t"), + T16("16t"), + T40_N4("40t-4n"); + + private static final String PROP_THREADING = "threading"; + + private static final String IMPORT_TASK_OID = "c32d4da6-bdd3-481d-931a-60ca8a5a01ba"; + private static final String TASK_FILE_NAME_PATTERN = "task-import-%s.xml"; + + private final String name; + + ThreadingVariant(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static ThreadingVariant setup() { + String configuredName = System.getProperty(PROP_THREADING, T1.name); + ThreadingVariant variant = fromName(configuredName); + System.out.println("Threading variant: " + variant); + return variant; + } + + public TestResource getImportTaskResource() { + String fileName = String.format(TASK_FILE_NAME_PATTERN, name); + return new TestResource<>(TEST_DIR, fileName, IMPORT_TASK_OID); + } + + private static ThreadingVariant fromName(String name) { + for (ThreadingVariant value : values()) { + if (value.name.equals(name)) { + return value; + } + } + throw new IllegalArgumentException("Unknown threading variant: " + name); + } +} diff --git a/testing/story/src/test/resources/system-perf/resource-source-ms0002.xml b/testing/story/src/test/resources/system-perf/resource-source-ms0002.xml new file mode 100644 index 00000000000..ac76a8f97c8 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/resource-source-ms0002.xml @@ -0,0 +1,129 @@ + + + + + + Dummy Resource + + + + + connectorType + com.evolveum.icf.dummy.connector.DummyConnector + + + connectorVersion + 2.0 + + + + + + + source + + + false + false + false + + + + + account + default + Default Account + true + ri:AccountObjectClass + + icfs:name + + + name + + + + + ri:a-single-0000 + + + + + + extension/p-single-0000 + + + + + ri:a-multi-0000 + + + + + + extension/p-multi-0000 + + + + + + + + + ri:AccountObjectClass + account + true + + + name + + $projection/attributes/icfs:name + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + diff --git a/testing/story/src/test/resources/system-perf/resource-source-ms0020.xml b/testing/story/src/test/resources/system-perf/resource-source-ms0020.xml new file mode 100644 index 00000000000..147f561b878 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/resource-source-ms0020.xml @@ -0,0 +1,363 @@ + + + + + + Dummy Resource + + + + + connectorType + com.evolveum.icf.dummy.connector.DummyConnector + + + connectorVersion + 2.0 + + + + + + + source + + + false + false + false + + + + + account + default + Default Account + true + ri:AccountObjectClass + + icfs:name + + + name + + + + + ri:a-single-0000 + + + + + + extension/p-single-0000 + + + + + ri:a-single-0001 + + + + + + extension/p-single-0001 + + + + + ri:a-single-0002 + + + + + + extension/p-single-0002 + + + + + ri:a-single-0003 + + + + + + extension/p-single-0003 + + + + + ri:a-single-0004 + + + + + + extension/p-single-0004 + + + + + ri:a-single-0005 + + + + + + extension/p-single-0005 + + + + + ri:a-single-0006 + + + + + + extension/p-single-0006 + + + + + ri:a-single-0007 + + + + + + extension/p-single-0007 + + + + + ri:a-single-0008 + + + + + + extension/p-single-0008 + + + + + ri:a-single-0009 + + + + + + extension/p-single-0009 + + + + + ri:a-multi-0000 + + + + + + extension/p-multi-0000 + + + + + ri:a-multi-0001 + + + + + + extension/p-multi-0001 + + + + + ri:a-multi-0002 + + + + + + extension/p-multi-0002 + + + + + ri:a-multi-0003 + + + + + + extension/p-multi-0003 + + + + + ri:a-multi-0004 + + + + + + extension/p-multi-0004 + + + + + ri:a-multi-0005 + + + + + + extension/p-multi-0005 + + + + + ri:a-multi-0006 + + + + + + extension/p-multi-0006 + + + + + ri:a-multi-0007 + + + + + + extension/p-multi-0007 + + + + + ri:a-multi-0008 + + + + + + extension/p-multi-0008 + + + + + ri:a-multi-0009 + + + + + + extension/p-multi-0009 + + + + + + + + + ri:AccountObjectClass + account + true + + + name + + $projection/attributes/icfs:name + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + diff --git a/testing/story/src/test/resources/system-perf/resource-source-ms0110.xml b/testing/story/src/test/resources/system-perf/resource-source-ms0110.xml new file mode 100644 index 00000000000..ae0e929ecc7 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/resource-source-ms0110.xml @@ -0,0 +1,1535 @@ + + + + + + Dummy Resource + + + + + connectorType + com.evolveum.icf.dummy.connector.DummyConnector + + + connectorVersion + 2.0 + + + + + + + source + + + false + false + false + + + + + account + default + Default Account + true + ri:AccountObjectClass + + icfs:name + + + name + + + + + ri:a-single-0000 + + + + + + extension/p-single-0000 + + + + + ri:a-single-0001 + + + + + + extension/p-single-0001 + + + + + ri:a-single-0002 + + + + + + extension/p-single-0002 + + + + + ri:a-single-0003 + + + + + + extension/p-single-0003 + + + + + ri:a-single-0004 + + + + + + extension/p-single-0004 + + + + + ri:a-single-0005 + + + + + + extension/p-single-0005 + + + + + ri:a-single-0006 + + + + + + extension/p-single-0006 + + + + + ri:a-single-0007 + + + + + + extension/p-single-0007 + + + + + ri:a-single-0008 + + + + + + extension/p-single-0008 + + + + + ri:a-single-0009 + + + + + + extension/p-single-0009 + + + + + ri:a-single-0010 + + + + + + extension/p-single-0010 + + + + + ri:a-single-0011 + + + + + + extension/p-single-0011 + + + + + ri:a-single-0012 + + + + + + extension/p-single-0012 + + + + + ri:a-single-0013 + + + + + + extension/p-single-0013 + + + + + ri:a-single-0014 + + + + + + extension/p-single-0014 + + + + + ri:a-single-0015 + + + + + + extension/p-single-0015 + + + + + ri:a-single-0016 + + + + + + extension/p-single-0016 + + + + + ri:a-single-0017 + + + + + + extension/p-single-0017 + + + + + ri:a-single-0018 + + + + + + extension/p-single-0018 + + + + + ri:a-single-0019 + + + + + + extension/p-single-0019 + + + + + ri:a-single-0020 + + + + + + extension/p-single-0020 + + + + + ri:a-single-0021 + + + + + + extension/p-single-0021 + + + + + ri:a-single-0022 + + + + + + extension/p-single-0022 + + + + + ri:a-single-0023 + + + + + + extension/p-single-0023 + + + + + ri:a-single-0024 + + + + + + extension/p-single-0024 + + + + + ri:a-single-0025 + + + + + + extension/p-single-0025 + + + + + ri:a-single-0026 + + + + + + extension/p-single-0026 + + + + + ri:a-single-0027 + + + + + + extension/p-single-0027 + + + + + ri:a-single-0028 + + + + + + extension/p-single-0028 + + + + + ri:a-single-0029 + + + + + + extension/p-single-0029 + + + + + ri:a-single-0030 + + + + + + extension/p-single-0030 + + + + + ri:a-single-0031 + + + + + + extension/p-single-0031 + + + + + ri:a-single-0032 + + + + + + extension/p-single-0032 + + + + + ri:a-single-0033 + + + + + + extension/p-single-0033 + + + + + ri:a-single-0034 + + + + + + extension/p-single-0034 + + + + + ri:a-single-0035 + + + + + + extension/p-single-0035 + + + + + ri:a-single-0036 + + + + + + extension/p-single-0036 + + + + + ri:a-single-0037 + + + + + + extension/p-single-0037 + + + + + ri:a-single-0038 + + + + + + extension/p-single-0038 + + + + + ri:a-single-0039 + + + + + + extension/p-single-0039 + + + + + + ri:a-single-0040 + + + + + + extension/p-single-0040 + + + + + ri:a-single-0041 + + + + + + extension/p-single-0041 + + + + + ri:a-single-0042 + + + + + + extension/p-single-0042 + + + + + ri:a-single-0043 + + + + + + extension/p-single-0043 + + + + + ri:a-single-0044 + + + + + + extension/p-single-0044 + + + + + ri:a-single-0045 + + + + + + extension/p-single-0045 + + + + + ri:a-single-0046 + + + + + + extension/p-single-0046 + + + + + ri:a-single-0047 + + + + + + extension/p-single-0047 + + + + + ri:a-single-0048 + + + + + + extension/p-single-0048 + + + + + ri:a-single-0049 + + + + + + extension/p-single-0049 + + + + + + ri:a-single-0050 + + + + + + extension/p-single-0050 + + + + + ri:a-single-0051 + + + + + + extension/p-single-0051 + + + + + ri:a-single-0052 + + + + + + extension/p-single-0052 + + + + + ri:a-single-0053 + + + + + + extension/p-single-0053 + + + + + ri:a-single-0054 + + + + + + extension/p-single-0054 + + + + + ri:a-single-0055 + + + + + + extension/p-single-0055 + + + + + ri:a-single-0056 + + + + + + extension/p-single-0056 + + + + + ri:a-single-0057 + + + + + + extension/p-single-0057 + + + + + ri:a-single-0058 + + + + + + extension/p-single-0058 + + + + + ri:a-single-0059 + + + + + + extension/p-single-0059 + + + + + ri:a-single-0060 + + + + + + extension/p-single-0060 + + + + + ri:a-single-0061 + + + + + + extension/p-single-0061 + + + + + ri:a-single-0062 + + + + + + extension/p-single-0062 + + + + + ri:a-single-0063 + + + + + + extension/p-single-0063 + + + + + ri:a-single-0064 + + + + + + extension/p-single-0064 + + + + + ri:a-single-0065 + + + + + + extension/p-single-0065 + + + + + ri:a-single-0066 + + + + + + extension/p-single-0066 + + + + + ri:a-single-0067 + + + + + + extension/p-single-0067 + + + + + ri:a-single-0068 + + + + + + extension/p-single-0068 + + + + + ri:a-single-0069 + + + + + + extension/p-single-0069 + + + + + ri:a-single-0070 + + + + + + extension/p-single-0070 + + + + + ri:a-single-0071 + + + + + + extension/p-single-0071 + + + + + ri:a-single-0072 + + + + + + extension/p-single-0072 + + + + + ri:a-single-0073 + + + + + + extension/p-single-0073 + + + + + ri:a-single-0074 + + + + + + extension/p-single-0074 + + + + + ri:a-single-0075 + + + + + + extension/p-single-0075 + + + + + ri:a-single-0076 + + + + + + extension/p-single-0076 + + + + + ri:a-single-0077 + + + + + + extension/p-single-0077 + + + + + ri:a-single-0078 + + + + + + extension/p-single-0078 + + + + + ri:a-single-0079 + + + + + + extension/p-single-0079 + + + + + ri:a-single-0080 + + + + + + extension/p-single-0080 + + + + + ri:a-single-0081 + + + + + + extension/p-single-0081 + + + + + ri:a-single-0082 + + + + + + extension/p-single-0082 + + + + + ri:a-single-0083 + + + + + + extension/p-single-0083 + + + + + ri:a-single-0084 + + + + + + extension/p-single-0084 + + + + + ri:a-single-0085 + + + + + + extension/p-single-0085 + + + + + ri:a-single-0086 + + + + + + extension/p-single-0086 + + + + + ri:a-single-0087 + + + + + + extension/p-single-0087 + + + + + ri:a-single-0088 + + + + + + extension/p-single-0088 + + + + + ri:a-single-0089 + + + + + + extension/p-single-0089 + + + + + ri:a-single-0090 + + + + + + extension/p-single-0090 + + + + + ri:a-single-0091 + + + + + + extension/p-single-0091 + + + + + ri:a-single-0092 + + + + + + extension/p-single-0092 + + + + + ri:a-single-0093 + + + + + + extension/p-single-0093 + + + + + ri:a-single-0094 + + + + + + extension/p-single-0094 + + + + + ri:a-single-0095 + + + + + + extension/p-single-0095 + + + + + ri:a-single-0096 + + + + + + extension/p-single-0096 + + + + + ri:a-single-0097 + + + + + + extension/p-single-0097 + + + + + ri:a-single-0098 + + + + + + extension/p-single-0098 + + + + + ri:a-single-0099 + + + + + + extension/p-single-0099 + + + + + ri:a-multi-0000 + + + + + + extension/p-multi-0000 + + + + + ri:a-multi-0001 + + + + + + extension/p-multi-0001 + + + + + ri:a-multi-0002 + + + + + + extension/p-multi-0002 + + + + + ri:a-multi-0003 + + + + + + extension/p-multi-0003 + + + + + ri:a-multi-0004 + + + + + + extension/p-multi-0004 + + + + + ri:a-multi-0005 + + + + + + extension/p-multi-0005 + + + + + ri:a-multi-0006 + + + + + + extension/p-multi-0006 + + + + + ri:a-multi-0007 + + + + + + extension/p-multi-0007 + + + + + ri:a-multi-0008 + + + + + + extension/p-multi-0008 + + + + + ri:a-multi-0009 + + + + + + extension/p-multi-0009 + + + + + + + + + ri:AccountObjectClass + account + true + + + name + + $projection/attributes/icfs:name + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + diff --git a/testing/story/src/test/resources/system-perf/schema-basic/user-extension-basic.xsd b/testing/story/src/test/resources/system-perf/schema-basic/user-extension-basic.xsd new file mode 100644 index 00000000000..e7172421506 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/schema-basic/user-extension-basic.xsd @@ -0,0 +1,795 @@ + + + + + + + + + + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + diff --git a/testing/story/src/test/resources/system-perf/schema-big-global/user-extension-big-global.xsd b/testing/story/src/test/resources/system-perf/schema-big-global/user-extension-big-global.xsd new file mode 100644 index 00000000000..3da4de2d541 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/schema-big-global/user-extension-big-global.xsd @@ -0,0 +1,7106 @@ + + + + + + + + + + false + unbounded + + + + + + + false + unbounded + + + + + + + false + unbounded + + + + + + + false + unbounded + + + + + + + false + unbounded + + + + + + + false + unbounded + + + + + + + false + unbounded + + + + + + + false + unbounded + + + + + + + false + unbounded + + + + + + + false + unbounded + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + diff --git a/testing/story/src/test/resources/system-perf/schema-big/user-extension-big.xsd b/testing/story/src/test/resources/system-perf/schema-big/user-extension-big.xsd new file mode 100644 index 00000000000..67bdfd0634f --- /dev/null +++ b/testing/story/src/test/resources/system-perf/schema-big/user-extension-big.xsd @@ -0,0 +1,7105 @@ + + + + + + + + + + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + diff --git a/testing/story/src/test/resources/system-perf/schema-indexed/user-extension-indexed.xsd b/testing/story/src/test/resources/system-perf/schema-indexed/user-extension-indexed.xsd new file mode 100644 index 00000000000..a53535dee37 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/schema-indexed/user-extension-indexed.xsd @@ -0,0 +1,795 @@ + + + + + + + + + + + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + + true + + + + + + diff --git a/testing/story/src/test/resources/system-perf/system-configuration.xml b/testing/story/src/test/resources/system-perf/system-configuration.xml new file mode 100644 index 00000000000..654c998f43f --- /dev/null +++ b/testing/story/src/test/resources/system-perf/system-configuration.xml @@ -0,0 +1,94 @@ + + + + + SystemConfiguration + + File Appender + INFO + + OFF + org.hibernate.engine.jdbc.spi.SqlExceptionHelper + + + OFF + org.hibernate.internal.ExceptionMapperStandardImpl + + + OFF + org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl + + + OFF + org.hibernate.engine.jdbc.batch.internal.BatchingBatch + + + %date [%thread] %-5level \(%logger{46}\): %message%n + target/test.log + true + + + + + true + true + + + true + true + + + true + + + true + + + true + + + + true + + false + 60 + + perCacheAndObjectType + + + SystemConfigurationType + ArchetypeType + ObjectTemplateType + SecurityPolicyType + ValuePolicyType + ResourceType + RoleType + ShadowType + + + + + perCacheAndObjectType + + + + + + + globallyAndLocally + perOperationAndObjectType + + + + + never + never + + diff --git a/testing/story/src/test/resources/system-perf/task-import-16t.xml b/testing/story/src/test/resources/system-perf/task-import-16t.xml new file mode 100644 index 00000000000..4e99715237f --- /dev/null +++ b/testing/story/src/test/resources/system-perf/task-import-16t.xml @@ -0,0 +1,28 @@ + + + + + + Import + + + ri:AccountObjectClass + 16 + + + + runnable + + http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/import/handler-3 + + + single + diff --git a/testing/story/src/test/resources/system-perf/task-import-1t.xml b/testing/story/src/test/resources/system-perf/task-import-1t.xml new file mode 100644 index 00000000000..fad1852f6f2 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/task-import-1t.xml @@ -0,0 +1,27 @@ + + + + + + Import + + + ri:AccountObjectClass + + + + runnable + + http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/import/handler-3 + + + single + diff --git a/testing/story/src/test/resources/system-perf/task-import-4t.xml b/testing/story/src/test/resources/system-perf/task-import-4t.xml new file mode 100644 index 00000000000..1f5fd3eeced --- /dev/null +++ b/testing/story/src/test/resources/system-perf/task-import-4t.xml @@ -0,0 +1,28 @@ + + + + + + Import + + + ri:AccountObjectClass + 4 + + + + runnable + + http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/import/handler-3 + + + single + From 2f5baeb946bc839c39200ba9633365e127873fc0 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Thu, 29 Apr 2021 23:41:57 +0200 Subject: [PATCH 04/33] Add missing dependency --- testing/story/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/testing/story/pom.xml b/testing/story/pom.xml index 31af5e5bab1..c6bd553c231 100644 --- a/testing/story/pom.xml +++ b/testing/story/pom.xml @@ -181,6 +181,10 @@ ch.qos.logback logback-classic + + com.google.guava + guava + From a070797529c920b582667a76e8665e5f27f1dd3c Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Fri, 30 Apr 2021 11:54:10 +0200 Subject: [PATCH 05/33] repo-sqale: all transformers merged into Q*Mapping classes Mapping returned new transformer every time, but in the end transformer was stateless too (most of the state is in other context objects). Transformer support is now accessible statically to make this easier. While some "abstract" mappers like QObjectMapping got bigger, it is much easier to have just one concept instead of two. Audit (non-sqale) part is not part of this commit. --- .../repo/sqale/SqaleTransformerSupport.java | 7 + .../sqale/operations/AddObjectOperation.java | 22 +- .../qmodel/ObjectTemplateSqlTransformer.java | 34 --- .../sqale/qmodel/QObjectTemplateMapping.java | 16 +- .../repo/sqale/qmodel/QOwnedByMapping.java | 4 +- .../repo/sqale/qmodel/SqaleTableMapping.java | 186 +++++++++++++- .../sqale/qmodel/SqaleTransformerBase.java | 220 ---------------- .../sqale/qmodel/TransformerForOwnedBy.java | 1 - ...CertificationDefinitionSqlTransformer.java | 45 ---- ...QAccessCertificationDefinitionMapping.java | 27 +- .../assignment/AssignmentSqlTransformer.java | 106 -------- .../qmodel/assignment/QAssignmentMapping.java | 88 ++++++- .../repo/sqale/qmodel/cases/QCaseMapping.java | 11 +- .../qmodel/common/QContainerMapping.java | 23 +- .../ConnectorHostSqlTransformer.java | 34 --- .../connector/ConnectorSqlTransformer.java | 43 ---- .../connector/QConnectorHostMapping.java | 18 +- .../qmodel/connector/QConnectorMapping.java | 27 +- .../qmodel/focus/FocusSqlTransformer.java | 88 ------- .../focus/GenericObjectSqlTransformer.java | 32 --- .../sqale/qmodel/focus/QFocusMapping.java | 68 ++++- .../qmodel/focus/QGenericObjectMapping.java | 18 +- .../repo/sqale/qmodel/focus/QUserMapping.java | 34 ++- .../qmodel/focus/UserSqlTransformer.java | 48 ---- .../LookupTableRowSqlTransformer.java | 36 --- .../LookupTableSqlTransformer.java | 41 --- .../lookuptable/QLookupTableMapping.java | 24 +- .../lookuptable/QLookupTableRowMapping.java | 22 +- .../sqale/qmodel/node/NodeSqlTransformer.java | 31 --- .../repo/sqale/qmodel/node/QNodeMapping.java | 16 +- .../object/ContainerSqlTransformer.java | 56 ----- .../qmodel/object/ObjectSqlTransformer.java | 236 ------------------ .../OperationExecutionSqlTransformer.java | 42 ---- .../sqale/qmodel/object/QObjectMapping.java | 204 ++++++++++++++- .../object/QOperationExecutionMapping.java | 30 ++- .../sqale/qmodel/object/QTriggerMapping.java | 19 +- .../qmodel/object/TriggerSqlTransformer.java | 32 --- .../sqale/qmodel/other/QDashboardMapping.java | 9 - .../repo/sqale/qmodel/other/QFormMapping.java | 9 - .../qmodel/other/QFunctionLibraryMapping.java | 9 - .../other/QObjectCollectionMapping.java | 9 - .../sqale/qmodel/other/QSequenceMapping.java | 9 - .../sqale/qmodel/ref/QReferenceMapping.java | 24 +- .../qmodel/ref/ReferenceSqlTransformer.java | 55 ---- .../qmodel/report/QReportDataMapping.java | 20 +- .../sqale/qmodel/report/QReportMapping.java | 21 +- .../report/ReportDataSqlTransformer.java | 36 --- .../qmodel/report/ReportSqlTransformer.java | 38 --- .../qmodel/resource/QResourceMapping.java | 44 +++- .../resource/ResourceSqlTransformer.java | 63 ----- .../role/AbstractRoleSqlTransformer.java | 64 ----- .../qmodel/role/QAbstractRoleMapping.java | 33 ++- .../sqale/qmodel/role/QArchetypeMapping.java | 8 - .../repo/sqale/qmodel/role/QRoleMapping.java | 17 +- .../sqale/qmodel/role/QServiceMapping.java | 17 +- .../sqale/qmodel/role/RoleSqlTransformer.java | 32 --- .../qmodel/role/ServiceSqlTransformer.java | 32 --- .../sqale/qmodel/shadow/QShadowMapping.java | 35 ++- .../qmodel/shadow/ShadowSqlTransformer.java | 51 ---- .../qmodel/system/QSecurityPolicyMapping.java | 9 - .../system/QSystemConfigurationMapping.java | 9 - .../qmodel/system/QValuePolicyMapping.java | 9 - .../repo/sqale/qmodel/task/QTaskMapping.java | 41 ++- .../sqale/qmodel/task/TaskSqlTransformer.java | 55 ---- .../repo/sqale/update/RootUpdateContext.java | 9 +- .../repo/sqale/update/SqaleUpdateContext.java | 5 +- .../repo/sqlbase/SqlTransformerSupport.java | 7 + .../sqlbase/mapping/QueryTableMapping.java | 1 + 68 files changed, 995 insertions(+), 1774 deletions(-) delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTransformerBase.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/AccessCertificationDefinitionSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/AssignmentSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorHostSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/GenericObjectSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/UserSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableRowSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/NodeSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ContainerSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ObjectSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/OperationExecutionSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/TriggerSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/ReferenceSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/ReportDataSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/ReportSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/ResourceSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/AbstractRoleSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/RoleSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/ServiceSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/ShadowSqlTransformer.java delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/TaskSqlTransformer.java diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerSupport.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerSupport.java index 0bf18204c9b..7674440d99c 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerSupport.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerSupport.java @@ -20,8 +20,15 @@ */ public class SqaleTransformerSupport extends SqlTransformerSupport { + private static SqaleTransformerSupport instance; + public SqaleTransformerSupport(SchemaService schemaService, SqaleRepoContext sqaleRepoContext) { super(schemaService, sqaleRepoContext); + instance = this; + } + + public static SqaleTransformerSupport getInstance() { + return instance; } private SqaleRepoContext sqaleRepoContext() { diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java index 4e07ff7847e..fff4d6ecdf3 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java @@ -19,11 +19,10 @@ import com.evolveum.midpoint.repo.api.RepoAddOptions; import com.evolveum.midpoint.repo.sqale.ContainerValueIdGenerator; import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport; -import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObject; +import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.schema.result.OperationResult; @@ -49,7 +48,7 @@ public class AddObjectOperation, R ex private SqlRepoContext sqlRepoContext; private Q root; - private ObjectSqlTransformer transformer; + private QObjectMapping rootMapping; private MObjectType objectType; public AddObjectOperation(@NotNull PrismObject object, @@ -67,11 +66,8 @@ public String execute(SqaleTransformerSupport transformerSupport) sqlRepoContext = transformerSupport.sqlRepoContext(); Class schemaObjectClass = object.getCompileTimeClass(); objectType = MObjectType.fromSchemaType(schemaObjectClass); - SqaleTableMapping rootMapping = - sqlRepoContext.getMappingBySchemaType(schemaObjectClass); + rootMapping = sqlRepoContext.getMappingBySchemaType(schemaObjectClass); root = rootMapping.defaultAlias(); - transformer = (ObjectSqlTransformer) - rootMapping.createTransformer(transformerSupport); // we don't want CID generation here, because overwrite works different then normal add @@ -100,9 +96,9 @@ private String addObjectWithOid() throws SchemaException { long lastCid = new ContainerValueIdGenerator().generateForNewObject(object); try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) { S schemaObject = object.asObjectable(); - R row = transformer.toRowObjectWithoutFullObject(schemaObject, jdbcSession); + R row = rootMapping.toRowObjectWithoutFullObject(schemaObject, jdbcSession); row.containerIdSeq = lastCid + 1; - transformer.setFullObject(row, schemaObject); + rootMapping.setFullObject(row, schemaObject); UUID oid = jdbcSession.newInsert(root) // default populate mapper ignores null, that's good, especially for objectType @@ -110,7 +106,7 @@ private String addObjectWithOid() throws SchemaException { .executeWithKey(root.oid); row.objectType = objectType; // sub-entities can use it, now it's safe to set it - transformer.storeRelatedEntities(row, schemaObject, jdbcSession); + rootMapping.storeRelatedEntities(row, schemaObject, jdbcSession); jdbcSession.commit(); return Objects.requireNonNull(oid, "OID of inserted object can't be null") @@ -121,7 +117,7 @@ private String addObjectWithOid() throws SchemaException { private String addObjectWithoutOid() throws SchemaException { try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) { S schemaObject = object.asObjectable(); - R row = transformer.toRowObjectWithoutFullObject(schemaObject, jdbcSession); + R row = rootMapping.toRowObjectWithoutFullObject(schemaObject, jdbcSession); // first insert without full object, because we don't know the OID yet UUID oid = jdbcSession.newInsert(root) @@ -136,7 +132,7 @@ private String addObjectWithoutOid() throws SchemaException { long lastCid = new ContainerValueIdGenerator().generateForNewObject(object); // now to update full object with known OID - transformer.setFullObject(row, schemaObject); + rootMapping.setFullObject(row, schemaObject); jdbcSession.newUpdate(root) .set(root.fullObject, row.fullObject) .set(root.containerIdSeq, lastCid + 1) @@ -145,7 +141,7 @@ private String addObjectWithoutOid() throws SchemaException { row.oid = oid; row.objectType = objectType; // sub-entities can use it, now it's safe to set it - transformer.storeRelatedEntities(row, schemaObject, jdbcSession); + rootMapping.storeRelatedEntities(row, schemaObject, jdbcSession); jdbcSession.commit(); return oidString; diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java deleted file mode 100644 index b4f23b44494..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType; - -public class ObjectTemplateSqlTransformer - extends ObjectSqlTransformer { - - public ObjectTemplateSqlTransformer( - SqlTransformerSupport transformerSupport, QObjectTemplateMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public void storeRelatedEntities(@NotNull MObject row, - @NotNull ObjectTemplateType schemaObject, @NotNull JdbcSession jdbcSession) { - super.storeRelatedEntities(row, schemaObject, jdbcSession); - - storeRefs(row, schemaObject.getIncludeRef(), - QObjectReferenceMapping.INSTANCE_INCLUDE, jdbcSession); - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java index 674c523ccd8..c97b359d9e0 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java @@ -8,9 +8,12 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType.F_INCLUDE_REF; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType; @@ -37,13 +40,22 @@ protected QObjectTemplate newAliasInstance(String alias) { } @Override - public ObjectTemplateSqlTransformer createTransformer( + public QObjectTemplateMapping createTransformer( SqlTransformerSupport transformerSupport) { - return new ObjectTemplateSqlTransformer(transformerSupport, this); + return this; } @Override public MObject newRowObject() { return new MObject(); } + + @Override + public void storeRelatedEntities(@NotNull MObject row, + @NotNull ObjectTemplateType schemaObject, @NotNull JdbcSession jdbcSession) { + super.storeRelatedEntities(row, schemaObject, jdbcSession); + + storeRefs(row, schemaObject.getIncludeRef(), + QObjectReferenceMapping.INSTANCE_INCLUDE, jdbcSession); + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QOwnedByMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QOwnedByMapping.java index b9b1c1ec9db..6345dca8ff4 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QOwnedByMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QOwnedByMapping.java @@ -6,7 +6,7 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; /** * Marks mappings for {@link QOwnedBy} entities. @@ -21,5 +21,5 @@ public interface QOwnedByMapping { /** Returns a row with foreign key fields referencing the provided owner row. */ R newRowObject(OR ownerRow); - TransformerForOwnedBy createTransformer(SqlTransformerSupport transformerSupport); + R insert(S schemaObject, OR ownerRow, JdbcSession jdbcSession); } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java index 81b5cbdb34b..0b2d5986a9c 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java @@ -6,24 +6,47 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel; +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import java.util.function.Consumer; import java.util.function.Function; +import javax.xml.namespace.QName; +import com.querydsl.core.Tuple; import com.querydsl.core.types.dsl.*; +import com.querydsl.sql.ColumnMetadata; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport; import com.evolveum.midpoint.repo.sqale.delta.item.*; import com.evolveum.midpoint.repo.sqale.filtering.RefItemFilterProcessor; import com.evolveum.midpoint.repo.sqale.filtering.UriItemFilterProcessor; import com.evolveum.midpoint.repo.sqale.mapping.SqaleItemSqlMapper; +import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObject; +import com.evolveum.midpoint.repo.sqale.qmodel.ref.MReference; +import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.filtering.item.EnumItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.PolyStringItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.SimpleItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.TimestampItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; +import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.repo.sqlbase.querydsl.UuidPath; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.util.MiscUtil; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; /** * Mapping superclass with common functions for {@link QObject} and non-objects (e.g. containers). @@ -36,7 +59,9 @@ */ public abstract class SqaleTableMapping, R> extends QueryTableMapping - implements SqaleMappingMixin { + implements SqaleMappingMixin, SqlTransformer { + + protected final Logger logger = LoggerFactory.getLogger(getClass()); protected SqaleTableMapping( @NotNull String tableName, @@ -169,4 +194,163 @@ public > SqaleItemSqlMapper enumMapper( ctx -> new EnumItemDeltaProcessor<>(ctx, rootToQueryItem), rootToQueryItem); } + + // Previously transformer code from here down + // TODO inline later + protected QueryTableMapping mapping() { + return this; + } + + @Override + public S toSchemaObject(R row) { + throw new UnsupportedOperationException("Use toSchemaObject(Tuple,...)"); + } + + /** + * Transforms row Tuple containing {@link R} under entity path and extension columns. + */ + @Override + public S toSchemaObject(Tuple tuple, Q entityPath, + Collection> options) + throws SchemaException { + S schemaObject = toSchemaObject(tuple.get(entityPath)); + processExtensionColumns(schemaObject, tuple, entityPath); + return schemaObject; + } + + @SuppressWarnings("unused") + protected void processExtensionColumns(S schemaObject, Tuple tuple, Q entityPath) { + // empty by default, can be overridden + } + + /** + * Returns {@link ObjectReferenceType} with specified oid, proper type based on + * {@link MObjectType} and, optionally, target name/description. + * Returns {@code null} if OID is null. + * Fails if OID is not null and {@code repoObjectType} is null. + */ + @Nullable + protected ObjectReferenceType objectReferenceType( + @Nullable String oid, MObjectType repoObjectType, String targetName) { + if (oid == null) { + return null; + } + if (repoObjectType == null) { + throw new IllegalArgumentException( + "NULL object type provided for object reference with OID " + oid); + } + + return new ObjectReferenceType() + .oid(oid) + .type(SqaleTransformerSupport.getInstance().schemaClassToQName(repoObjectType.getSchemaType())) + .description(targetName) + .targetName(targetName); + } + + /** + * Trimming the value to the column size from column metadata (must be specified). + */ + protected @Nullable String trim( + @Nullable String value, @NotNull ColumnMetadata columnMetadata) { + if (!columnMetadata.hasSize()) { + throw new IllegalArgumentException( + "trimString with column metadata without specified size: " + columnMetadata); + } + return MiscUtil.trimString(value, columnMetadata.getSize()); + } + + protected @NotNull Integer searchCachedRelationId(QName qName) { + return SqaleTransformerSupport.getInstance().searchCachedRelationId(qName); + } + + /** Returns ID for cached URI without going to the database. */ + protected Integer resolveUriToId(String uri) { + return SqaleTransformerSupport.getInstance().resolveUriToId(uri); + } + + /** + * Returns ID for relation QName creating new {@link QUri} row in DB as needed. + * Relation is normalized before consulting the cache. + * Never returns null, returns default ID for configured default relation. + */ + protected Integer processCacheableRelation(QName qName) { + return SqaleTransformerSupport.getInstance().processCacheableRelation(qName); + } + + /** Returns ID for URI creating new cache row in DB as needed. */ + protected Integer processCacheableUri(String uri) { + return uri != null + ? SqaleTransformerSupport.getInstance().processCacheableUri(uri) + : null; + } + + /** Returns ID for URI creating new cache row in DB as needed. */ + protected Integer processCacheableUri(QName qName) { + return qName != null + ? SqaleTransformerSupport.getInstance().processCacheableUri(QNameUtil.qNameToUri(qName)) + : null; + } + + /** + * Returns IDs as Integer array for URI strings creating new cache row in DB as needed. + * Returns null for null or empty list on input. + */ + protected Integer[] processCacheableUris(List uris) { + if (uris == null || uris.isEmpty()) { + return null; + } + return uris.stream() + .map(uri -> processCacheableUri(uri)) + .toArray(Integer[]::new); + } + + protected @Nullable UUID oidToUUid(@Nullable String oid) { + return oid != null ? UUID.fromString(oid) : null; + } + + protected MObjectType schemaTypeToObjectType(QName schemaType) { + return schemaType == null ? null : + MObjectType.fromSchemaType( + SqaleTransformerSupport.getInstance().qNameToSchemaClass(schemaType)); + } + + protected void setPolyString(PolyStringType polyString, + Consumer origConsumer, Consumer normConsumer) { + if (polyString != null) { + origConsumer.accept(polyString.getOrig()); + normConsumer.accept(polyString.getNorm()); + } + } + + protected void setReference(ObjectReferenceType ref, + Consumer targetOidConsumer, Consumer targetTypeConsumer, + Consumer relationIdConsumer) { + if (ref != null) { + targetOidConsumer.accept(oidToUUid(ref.getOid())); + targetTypeConsumer.accept(schemaTypeToObjectType(ref.getType())); + relationIdConsumer.accept(processCacheableRelation(ref.getRelation())); + } + } + + protected , OR> void storeRefs( + @NotNull OR ownerRow, @NotNull List refs, + @NotNull QReferenceMapping mapping, @NotNull JdbcSession jdbcSession) { + if (!refs.isEmpty()) { + refs.forEach(ref -> mapping.insert(ref, ownerRow, jdbcSession)); + } + } + + protected String[] arrayFor(List strings) { + if (strings == null || strings.isEmpty()) { + return null; + } + return strings.toArray(String[]::new); + } + + /** Convenient insert shortcut when the row is fully populated. */ + protected void insert(R row, JdbcSession jdbcSession) { + jdbcSession.newInsert(mapping().defaultAlias()) + .populate(row) + .execute(); + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTransformerBase.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTransformerBase.java deleted file mode 100644 index 9e86853cf9e..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTransformerBase.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel; - -import java.util.Collection; -import java.util.List; -import java.util.UUID; -import java.util.function.Consumer; -import javax.xml.namespace.QName; - -import com.querydsl.core.Tuple; -import com.querydsl.sql.ColumnMetadata; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport; -import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri; -import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType; -import com.evolveum.midpoint.repo.sqale.qmodel.ref.MReference; -import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping; -import com.evolveum.midpoint.repo.sqale.qmodel.ref.ReferenceSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; -import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.SelectorOptions; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.util.QNameUtil; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; - -/** - * @param schema type - * @param type of entity path - * @param type of the row bean for the table - */ -public abstract class SqaleTransformerBase, R> - implements SqlTransformer { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - protected final SqaleTransformerSupport transformerSupport; - - /** - * Constructor uses {@link SqlTransformerSupport} type even when it really is - * {@link SqaleTransformerSupport}, but this way we can cast it just once here; otherwise cast - * would be needed in each implementation of {@link QueryTableMapping#createTransformer)}. - * (Alternative is to parametrize {@link QueryTableMapping} with various {@link SqlTransformer} - * types which is not convenient at all. This little downcast is low price to pay.) - */ - protected SqaleTransformerBase(SqlTransformerSupport transformerSupport) { - this.transformerSupport = (SqaleTransformerSupport) transformerSupport; - } - - protected abstract QueryTableMapping mapping(); - - @Override - public S toSchemaObject(R row) { - throw new UnsupportedOperationException("Use toSchemaObject(Tuple,...)"); - } - - /** - * Transforms row Tuple containing {@link R} under entity path and extension columns. - */ - @Override - public S toSchemaObject(Tuple tuple, Q entityPath, - Collection> options) - throws SchemaException { - S schemaObject = toSchemaObject(tuple.get(entityPath)); - processExtensionColumns(schemaObject, tuple, entityPath); - return schemaObject; - } - - @SuppressWarnings("unused") - protected void processExtensionColumns(S schemaObject, Tuple tuple, Q entityPath) { - // empty by default, can be overridden - } - - /** - * Returns {@link ObjectReferenceType} with specified oid, proper type based on - * {@link MObjectType} and, optionally, target name/description. - * Returns {@code null} if OID is null. - * Fails if OID is not null and {@code repoObjectType} is null. - */ - @Nullable - protected ObjectReferenceType objectReferenceType( - @Nullable String oid, MObjectType repoObjectType, String targetName) { - if (oid == null) { - return null; - } - if (repoObjectType == null) { - throw new IllegalArgumentException( - "NULL object type provided for object reference with OID " + oid); - } - - return new ObjectReferenceType() - .oid(oid) - .type(transformerSupport.schemaClassToQName(repoObjectType.getSchemaType())) - .description(targetName) - .targetName(targetName); - } - - /** - * Trimming the value to the column size from column metadata (must be specified). - */ - protected @Nullable String trim( - @Nullable String value, @NotNull ColumnMetadata columnMetadata) { - if (!columnMetadata.hasSize()) { - throw new IllegalArgumentException( - "trimString with column metadata without specified size: " + columnMetadata); - } - return MiscUtil.trimString(value, columnMetadata.getSize()); - } - - protected @NotNull Integer searchCachedRelationId(QName qName) { - return transformerSupport.searchCachedRelationId(qName); - } - - /** Returns ID for cached URI without going to the database. */ - protected Integer resolveUriToId(String uri) { - return transformerSupport.resolveUriToId(uri); - } - - /** - * Returns ID for relation QName creating new {@link QUri} row in DB as needed. - * Relation is normalized before consulting the cache. - * Never returns null, returns default ID for configured default relation. - */ - protected Integer processCacheableRelation(QName qName) { - return transformerSupport.processCacheableRelation(qName); - } - - /** Returns ID for URI creating new cache row in DB as needed. */ - protected Integer processCacheableUri(String uri) { - return uri != null - ? transformerSupport.processCacheableUri(uri) - : null; - } - - /** Returns ID for URI creating new cache row in DB as needed. */ - protected Integer processCacheableUri(QName qName) { - return qName != null - ? transformerSupport.processCacheableUri(QNameUtil.qNameToUri(qName)) - : null; - } - - /** - * Returns IDs as Integer array for URI strings creating new cache row in DB as needed. - * Returns null for null or empty list on input. - */ - protected Integer[] processCacheableUris(List uris) { - if (uris == null || uris.isEmpty()) { - return null; - } - return uris.stream() - .map(uri -> processCacheableUri(uri)) - .toArray(Integer[]::new); - } - - protected @Nullable UUID oidToUUid(@Nullable String oid) { - return oid != null ? UUID.fromString(oid) : null; - } - - protected MObjectType schemaTypeToObjectType(QName schemaType) { - return schemaType == null ? null : - MObjectType.fromSchemaType( - transformerSupport.qNameToSchemaClass(schemaType)); - } - - protected void setPolyString(PolyStringType polyString, - Consumer origConsumer, Consumer normConsumer) { - if (polyString != null) { - origConsumer.accept(polyString.getOrig()); - normConsumer.accept(polyString.getNorm()); - } - } - - protected void setReference(ObjectReferenceType ref, - Consumer targetOidConsumer, Consumer targetTypeConsumer, - Consumer relationIdConsumer) { - if (ref != null) { - targetOidConsumer.accept(oidToUUid(ref.getOid())); - targetTypeConsumer.accept(schemaTypeToObjectType(ref.getType())); - relationIdConsumer.accept(processCacheableRelation(ref.getRelation())); - } - } - - protected , OR> void storeRefs( - @NotNull OR ownerRow, @NotNull List refs, - @NotNull QReferenceMapping mapping, @NotNull JdbcSession jdbcSession) { - if (!refs.isEmpty()) { - ReferenceSqlTransformer transformer = - mapping.createTransformer(transformerSupport); - refs.forEach(ref -> transformer.insert(ref, ownerRow, jdbcSession)); - } - } - - protected String[] arrayFor(List strings) { - if (strings == null || strings.isEmpty()) { - return null; - } - return strings.toArray(String[]::new); - } - - /** Convenient insert shortcut when the row is fully populated. */ - protected void insert(R row, JdbcSession jdbcSession) { - jdbcSession.newInsert(mapping().defaultAlias()) - .populate(row) - .execute(); - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java index b760c78d907..a50f328a136 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java @@ -18,5 +18,4 @@ public interface TransformerForOwnedBy { /** Contract for insertion of row of type {@link R} owned by {@link OR}. */ - R insert(S schemaObject, OR ownerRow, JdbcSession jdbcSession); } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/AccessCertificationDefinitionSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/AccessCertificationDefinitionSqlTransformer.java deleted file mode 100644 index 52570a81a0d..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/AccessCertificationDefinitionSqlTransformer.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.accesscert; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionType; - -public class AccessCertificationDefinitionSqlTransformer - extends ObjectSqlTransformer { - - public AccessCertificationDefinitionSqlTransformer( - SqlTransformerSupport transformerSupport, - QAccessCertificationDefinitionMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MAccessCertificationDefinition toRowObjectWithoutFullObject( - AccessCertificationDefinitionType schemaObject, JdbcSession jdbcSession) { - MAccessCertificationDefinition row = - super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); - - row.handlerUriId = processCacheableUri(schemaObject.getHandlerUri()); - row.lastCampaignStartedTimestamp = - MiscUtil.asInstant(schemaObject.getLastCampaignStartedTimestamp()); - row.lastCampaignClosedTimestamp = - MiscUtil.asInstant(schemaObject.getLastCampaignClosedTimestamp()); - setReference(schemaObject.getOwnerRef(), - o -> row.ownerRefTargetOid = o, - t -> row.ownerRefTargetType = t, - r -> row.ownerRefRelationId = r); - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java index e302547d70f..450f04ee3e3 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java @@ -8,8 +8,11 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractAccessCertificationDefinitionType.*; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; +import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionType; /** @@ -46,12 +49,26 @@ protected QAccessCertificationDefinition newAliasInstance(String alias) { } @Override - public AccessCertificationDefinitionSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new AccessCertificationDefinitionSqlTransformer(transformerSupport, this); + public MAccessCertificationDefinition newRowObject() { + return new MAccessCertificationDefinition(); } @Override - public MAccessCertificationDefinition newRowObject() { - return new MAccessCertificationDefinition(); + public @NotNull MAccessCertificationDefinition toRowObjectWithoutFullObject( + AccessCertificationDefinitionType schemaObject, JdbcSession jdbcSession) { + MAccessCertificationDefinition row = + super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); + + row.handlerUriId = processCacheableUri(schemaObject.getHandlerUri()); + row.lastCampaignStartedTimestamp = + MiscUtil.asInstant(schemaObject.getLastCampaignStartedTimestamp()); + row.lastCampaignClosedTimestamp = + MiscUtil.asInstant(schemaObject.getLastCampaignClosedTimestamp()); + setReference(schemaObject.getOwnerRef(), + o -> row.ownerRefTargetOid = o, + t -> row.ownerRefTargetType = t, + r -> row.ownerRefRelationId = r); + + return row; } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/AssignmentSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/AssignmentSqlTransformer.java deleted file mode 100644 index e69e2d1fab4..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/AssignmentSqlTransformer.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.assignment; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ContainerSqlTransformer; -import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; - -public class AssignmentSqlTransformer - extends ContainerSqlTransformer, MAssignment, OR> { - - public AssignmentSqlTransformer( - SqlTransformerSupport transformerSupport, QAssignmentMapping mapping) { - super(transformerSupport, mapping); - } - - // about duplication see the comment in ObjectSqlTransformer.toRowObjectWithoutFullObject - @SuppressWarnings("DuplicatedCode") - @Override - public MAssignment insert(AssignmentType assignment, OR ownerRow, JdbcSession jdbcSession) { - MAssignment row = initRowObject(assignment, ownerRow); - - row.ownerType = ownerRow.objectType; - row.lifecycleState = assignment.getLifecycleState(); - row.orderValue = assignment.getOrder(); - setReference(assignment.getOrgRef(), - o -> row.orgRefTargetOid = o, - t -> row.orgRefTargetType = t, - r -> row.orgRefRelationId = r); - setReference(assignment.getTargetRef(), - o -> row.targetRefTargetOid = o, - t -> row.targetRefTargetType = t, - r -> row.targetRefRelationId = r); - setReference(assignment.getTenantRef(), - o -> row.tenantRefTargetOid = o, - t -> row.tenantRefTargetType = t, - r -> row.tenantRefRelationId = r); - - // TODO no idea how to do this yet, somehow related to RAssignment.extension -// row.extId = assignment.getExtension()...id?; -// row.extOid =; - row.policySituations = processCacheableUris(assignment.getPolicySituation()); - // TODO extensions stored inline (JSON) - - ConstructionType construction = assignment.getConstruction(); - if (construction != null) { - setReference(construction.getResourceRef(), - o -> row.resourceRefTargetOid = o, - t -> row.resourceRefTargetType = t, - r -> row.resourceRefRelationId = r); - } - - ActivationType activation = assignment.getActivation(); - if (activation != null) { - row.administrativeStatus = activation.getAdministrativeStatus(); - row.effectiveStatus = activation.getEffectiveStatus(); - row.enableTimestamp = MiscUtil.asInstant(activation.getEnableTimestamp()); - row.disableTimestamp = MiscUtil.asInstant(activation.getDisableTimestamp()); - row.disableReason = activation.getDisableReason(); - row.validityStatus = activation.getValidityStatus(); - row.validFrom = MiscUtil.asInstant(activation.getValidFrom()); - row.validTo = MiscUtil.asInstant(activation.getValidTo()); - row.validityChangeTimestamp = MiscUtil.asInstant(activation.getValidityChangeTimestamp()); - row.archiveTimestamp = MiscUtil.asInstant(activation.getArchiveTimestamp()); - } - - MetadataType metadata = assignment.getMetadata(); - if (metadata != null) { - setReference(metadata.getCreatorRef(), - o -> row.creatorRefTargetOid = o, - t -> row.creatorRefTargetType = t, - r -> row.creatorRefRelationId = r); - row.createChannelId = processCacheableUri(metadata.getCreateChannel()); - row.createTimestamp = MiscUtil.asInstant(metadata.getCreateTimestamp()); - - setReference(metadata.getModifierRef(), - o -> row.modifierRefTargetOid = o, - t -> row.modifierRefTargetType = t, - r -> row.modifierRefRelationId = r); - row.modifyChannelId = processCacheableUri(metadata.getModifyChannel()); - row.modifyTimestamp = MiscUtil.asInstant(metadata.getModifyTimestamp()); - } - - // insert before treating sub-entities - insert(row, jdbcSession); - - if (metadata != null) { - storeRefs(row, metadata.getCreateApproverRef(), - QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_CREATE_APPROVER, jdbcSession); - storeRefs(row, metadata.getModifyApproverRef(), - QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_MODIFY_APPROVER, jdbcSession); - } - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java index 100b9b37c3a..a8da39f7a7d 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java @@ -13,7 +13,8 @@ import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping; import com.evolveum.midpoint.repo.sqale.qmodel.role.MAbstractRole; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; +import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType; @@ -129,11 +130,6 @@ protected QAssignment newAliasInstance(String alias) { return new QAssignment<>(alias); } - @Override - public AssignmentSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new AssignmentSqlTransformer<>(transformerSupport, this); - } - @Override public MAssignment newRowObject() { MAssignment row = new MAssignment(); @@ -147,4 +143,84 @@ public MAssignment newRowObject(OR ownerRow) { row.ownerOid = ownerRow.oid; return row; } + + // about duplication see the comment in ObjectSqlTransformer.toRowObjectWithoutFullObject + @SuppressWarnings("DuplicatedCode") + @Override + public MAssignment insert(AssignmentType assignment, OR ownerRow, JdbcSession jdbcSession) { + MAssignment row = initRowObject(assignment, ownerRow); + + row.ownerType = ownerRow.objectType; + row.lifecycleState = assignment.getLifecycleState(); + row.orderValue = assignment.getOrder(); + setReference(assignment.getOrgRef(), + o -> row.orgRefTargetOid = o, + t -> row.orgRefTargetType = t, + r -> row.orgRefRelationId = r); + setReference(assignment.getTargetRef(), + o -> row.targetRefTargetOid = o, + t -> row.targetRefTargetType = t, + r -> row.targetRefRelationId = r); + setReference(assignment.getTenantRef(), + o -> row.tenantRefTargetOid = o, + t -> row.tenantRefTargetType = t, + r -> row.tenantRefRelationId = r); + + // TODO no idea how to do this yet, somehow related to RAssignment.extension +// row.extId = assignment.getExtension()...id?; +// row.extOid =; + row.policySituations = processCacheableUris(assignment.getPolicySituation()); + // TODO extensions stored inline (JSON) + + ConstructionType construction = assignment.getConstruction(); + if (construction != null) { + setReference(construction.getResourceRef(), + o -> row.resourceRefTargetOid = o, + t -> row.resourceRefTargetType = t, + r -> row.resourceRefRelationId = r); + } + + ActivationType activation = assignment.getActivation(); + if (activation != null) { + row.administrativeStatus = activation.getAdministrativeStatus(); + row.effectiveStatus = activation.getEffectiveStatus(); + row.enableTimestamp = MiscUtil.asInstant(activation.getEnableTimestamp()); + row.disableTimestamp = MiscUtil.asInstant(activation.getDisableTimestamp()); + row.disableReason = activation.getDisableReason(); + row.validityStatus = activation.getValidityStatus(); + row.validFrom = MiscUtil.asInstant(activation.getValidFrom()); + row.validTo = MiscUtil.asInstant(activation.getValidTo()); + row.validityChangeTimestamp = MiscUtil.asInstant(activation.getValidityChangeTimestamp()); + row.archiveTimestamp = MiscUtil.asInstant(activation.getArchiveTimestamp()); + } + + MetadataType metadata = assignment.getMetadata(); + if (metadata != null) { + setReference(metadata.getCreatorRef(), + o -> row.creatorRefTargetOid = o, + t -> row.creatorRefTargetType = t, + r -> row.creatorRefRelationId = r); + row.createChannelId = processCacheableUri(metadata.getCreateChannel()); + row.createTimestamp = MiscUtil.asInstant(metadata.getCreateTimestamp()); + + setReference(metadata.getModifierRef(), + o -> row.modifierRefTargetOid = o, + t -> row.modifierRefTargetType = t, + r -> row.modifierRefRelationId = r); + row.modifyChannelId = processCacheableUri(metadata.getModifyChannel()); + row.modifyTimestamp = MiscUtil.asInstant(metadata.getModifyTimestamp()); + } + + // insert before treating sub-entities + insert(row, jdbcSession); + + if (metadata != null) { + storeRefs(row, metadata.getCreateApproverRef(), + QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_CREATE_APPROVER, jdbcSession); + storeRefs(row, metadata.getModifyApproverRef(), + QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_MODIFY_APPROVER, jdbcSession); + } + + return row; + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java index 92d6f162b04..39c63f052f8 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java @@ -8,9 +8,7 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.CaseType.*; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.CaseType; /** @@ -52,15 +50,10 @@ protected QCase newAliasInstance(String alias) { return new QCase(alias); } - @Override - public ObjectSqlTransformer - createTransformer(SqlTransformerSupport transformerSupport) { - // no special class needed, no additional columns - return new ObjectSqlTransformer<>(transformerSupport, this); - } - @Override public MCase newRowObject() { return new MCase(); } + + // TODO transformation code } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java index 793303094a8..58fbe74beb4 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java @@ -11,7 +11,7 @@ import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.repo.sqale.qmodel.QOwnedByMapping; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ContainerSqlTransformer; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; /** @@ -55,10 +55,8 @@ public R newRowObject(OR ownerRow) { "Container bean creation for owner row called on abstract container mapping"); } - @Override - public ContainerSqlTransformer createTransformer( - SqlTransformerSupport transformerSupport) { - return new ContainerSqlTransformer<>(transformerSupport, this); + public QContainerMapping createTransformer(SqlTransformerSupport transformerSupport) { + return this; } @Override @@ -66,4 +64,19 @@ public R newRowObject() { //noinspection unchecked return (R) new MContainer(); } + + /** + * This creates the right type of object and fills in the base {@link MContainer} attributes. + */ + public R initRowObject(S schemaObject, OR ownerRow) { + R row = newRowObject(ownerRow); + row.cid = schemaObject.asPrismContainerValue().getId(); + // containerType is generated in DB, must be left null! + return row; + } + + @Override + public R insert(S schemaObject, OR ownerRow, JdbcSession jdbcSession) { + throw new UnsupportedOperationException("insert not implemented in the subclass"); + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorHostSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorHostSqlTransformer.java deleted file mode 100644 index 10479473c4e..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorHostSqlTransformer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.connector; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType; - -public class ConnectorHostSqlTransformer - extends ObjectSqlTransformer { - - public ConnectorHostSqlTransformer( - SqlTransformerSupport transformerSupport, QConnectorHostMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MConnectorHost toRowObjectWithoutFullObject( - ConnectorHostType schemaObject, JdbcSession jdbcSession) { - MConnectorHost row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); - - row.hostname = schemaObject.getHostname(); - row.port = schemaObject.getPort(); - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorSqlTransformer.java deleted file mode 100644 index 8d36432ed34..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorSqlTransformer.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.connector; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType; - -public class ConnectorSqlTransformer - extends ObjectSqlTransformer { - - public ConnectorSqlTransformer( - SqlTransformerSupport transformerSupport, QConnectorMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MConnector toRowObjectWithoutFullObject( - ConnectorType schemaObject, JdbcSession jdbcSession) { - MConnector row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); - - row.connectorBundle = schemaObject.getConnectorBundle(); - row.connectorType = schemaObject.getConnectorType(); - row.connectorVersion = schemaObject.getConnectorVersion(); - row.frameworkId = processCacheableUri(schemaObject.getFramework()); - - setReference(schemaObject.getConnectorHostRef(), - o -> row.connectorHostRefTargetOid = o, - t -> row.connectorHostRefTargetType = t, - r -> row.connectorHostRefRelationId = r); - - row.targetSystemTypes = arrayFor(schemaObject.getTargetSystemType()); - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java index 2eb116abebf..66e8ccf2cbe 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java @@ -9,8 +9,10 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType.F_HOSTNAME; import static com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType.F_PORT; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType; /** @@ -37,12 +39,18 @@ protected QConnectorHost newAliasInstance(String alias) { } @Override - public ConnectorHostSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new ConnectorHostSqlTransformer(transformerSupport, this); + public MConnectorHost newRowObject() { + return new MConnectorHost(); } @Override - public MConnectorHost newRowObject() { - return new MConnectorHost(); + public @NotNull MConnectorHost toRowObjectWithoutFullObject( + ConnectorHostType schemaObject, JdbcSession jdbcSession) { + MConnectorHost row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); + + row.hostname = schemaObject.getHostname(); + row.port = schemaObject.getPort(); + + return row; } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java index 2b550bb8fc5..ef9fc1aeb81 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java @@ -8,8 +8,10 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType.*; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType; /** @@ -43,12 +45,27 @@ protected QConnector newAliasInstance(String alias) { } @Override - public ConnectorSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new ConnectorSqlTransformer(transformerSupport, this); + public MConnector newRowObject() { + return new MConnector(); } @Override - public MConnector newRowObject() { - return new MConnector(); + public @NotNull MConnector toRowObjectWithoutFullObject( + ConnectorType schemaObject, JdbcSession jdbcSession) { + MConnector row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); + + row.connectorBundle = schemaObject.getConnectorBundle(); + row.connectorType = schemaObject.getConnectorType(); + row.connectorVersion = schemaObject.getConnectorVersion(); + row.frameworkId = processCacheableUri(schemaObject.getFramework()); + + setReference(schemaObject.getConnectorHostRef(), + o -> row.connectorHostRefTargetOid = o, + t -> row.connectorHostRefTargetType = t, + r -> row.connectorHostRefRelationId = r); + + row.targetSystemTypes = arrayFor(schemaObject.getTargetSystemType()); + + return row; } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java deleted file mode 100644 index b37ea75b6f5..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.focus; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; - -public class FocusSqlTransformer, R extends MFocus> - extends ObjectSqlTransformer { - - public FocusSqlTransformer( - SqlTransformerSupport transformerSupport, QFocusMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - protected QFocusMapping mapping() { - return (QFocusMapping) super.mapping(); - } - - @SuppressWarnings("DuplicatedCode") // activation code duplicated with assignment - @Override - public @NotNull R toRowObjectWithoutFullObject(S focus, JdbcSession jdbcSession) { - R row = super.toRowObjectWithoutFullObject(focus, jdbcSession); - - row.costCenter = focus.getCostCenter(); - row.emailAddress = focus.getEmailAddress(); - row.photo = focus.getJpegPhoto(); - row.locale = focus.getLocale(); - setPolyString(focus.getLocality(), o -> row.localityOrig = o, n -> row.localityNorm = n); - row.preferredLanguage = focus.getPreferredLanguage(); - row.telephoneNumber = focus.getTelephoneNumber(); - row.timezone = focus.getTimezone(); - - // credential/password/metadata (sorry for nesting, but the gets may not be so cheap) - CredentialsType credentials = focus.getCredentials(); - if (credentials != null) { - PasswordType password = credentials.getPassword(); - if (password != null) { - MetadataType passwordMetadata = password.getMetadata(); - if (passwordMetadata != null) { - row.passwordCreateTimestamp = - MiscUtil.asInstant(passwordMetadata.getCreateTimestamp()); - row.passwordModifyTimestamp = - MiscUtil.asInstant(passwordMetadata.getModifyTimestamp()); - } - } - } - - // activation - ActivationType activation = focus.getActivation(); - if (activation != null) { - row.administrativeStatus = activation.getAdministrativeStatus(); - row.effectiveStatus = activation.getEffectiveStatus(); - row.enableTimestamp = MiscUtil.asInstant(activation.getEnableTimestamp()); - row.disableTimestamp = MiscUtil.asInstant(activation.getDisableTimestamp()); - row.disableReason = activation.getDisableReason(); - row.validityStatus = activation.getValidityStatus(); - row.validFrom = MiscUtil.asInstant(activation.getValidFrom()); - row.validTo = MiscUtil.asInstant(activation.getValidTo()); - row.validityChangeTimestamp = MiscUtil.asInstant(activation.getValidityChangeTimestamp()); - row.archiveTimestamp = MiscUtil.asInstant(activation.getArchiveTimestamp()); - row.lockoutStatus = activation.getLockoutStatus(); - } - - return row; - } - - @Override - public void storeRelatedEntities( - @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) { - super.storeRelatedEntities(row, schemaObject, jdbcSession); - - storeRefs(row, schemaObject.getLinkRef(), - mapping().projectionReferenceMapping(), jdbcSession); - storeRefs(row, schemaObject.getPersonaRef(), - mapping().personaReferenceMapping(), jdbcSession); - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/GenericObjectSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/GenericObjectSqlTransformer.java deleted file mode 100644 index 8bfc9143b02..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/GenericObjectSqlTransformer.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.focus; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.GenericObjectType; - -public class GenericObjectSqlTransformer - extends FocusSqlTransformer { - - public GenericObjectSqlTransformer( - SqlTransformerSupport transformerSupport, QGenericObjectMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MGenericObject toRowObjectWithoutFullObject( - GenericObjectType genericObject, JdbcSession jdbcSession) { - MGenericObject row = super.toRowObjectWithoutFullObject(genericObject, jdbcSession); - - row.genericObjectTypeId = processCacheableUri(genericObject.getObjectType()); - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java index fd69cf7246b..d9f64fa0011 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java @@ -15,9 +15,10 @@ import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; /** @@ -113,15 +114,68 @@ protected Q newAliasInstance(String alias) { return (Q) new QFocus<>(MFocus.class, alias); } - @Override - public FocusSqlTransformer createTransformer( - SqlTransformerSupport transformerSupport) { - return new FocusSqlTransformer<>(transformerSupport, this); - } - @Override public R newRowObject() { //noinspection unchecked return (R) new MFocus(); } + + @SuppressWarnings("DuplicatedCode") // activation code duplicated with assignment + @Override + public @NotNull R toRowObjectWithoutFullObject(S focus, JdbcSession jdbcSession) { + R row = super.toRowObjectWithoutFullObject(focus, jdbcSession); + + row.costCenter = focus.getCostCenter(); + row.emailAddress = focus.getEmailAddress(); + row.photo = focus.getJpegPhoto(); + row.locale = focus.getLocale(); + setPolyString(focus.getLocality(), o -> row.localityOrig = o, n -> row.localityNorm = n); + row.preferredLanguage = focus.getPreferredLanguage(); + row.telephoneNumber = focus.getTelephoneNumber(); + row.timezone = focus.getTimezone(); + + // credential/password/metadata (sorry for nesting, but the gets may not be so cheap) + CredentialsType credentials = focus.getCredentials(); + if (credentials != null) { + PasswordType password = credentials.getPassword(); + if (password != null) { + MetadataType passwordMetadata = password.getMetadata(); + if (passwordMetadata != null) { + row.passwordCreateTimestamp = + MiscUtil.asInstant(passwordMetadata.getCreateTimestamp()); + row.passwordModifyTimestamp = + MiscUtil.asInstant(passwordMetadata.getModifyTimestamp()); + } + } + } + + // activation + ActivationType activation = focus.getActivation(); + if (activation != null) { + row.administrativeStatus = activation.getAdministrativeStatus(); + row.effectiveStatus = activation.getEffectiveStatus(); + row.enableTimestamp = MiscUtil.asInstant(activation.getEnableTimestamp()); + row.disableTimestamp = MiscUtil.asInstant(activation.getDisableTimestamp()); + row.disableReason = activation.getDisableReason(); + row.validityStatus = activation.getValidityStatus(); + row.validFrom = MiscUtil.asInstant(activation.getValidFrom()); + row.validTo = MiscUtil.asInstant(activation.getValidTo()); + row.validityChangeTimestamp = MiscUtil.asInstant(activation.getValidityChangeTimestamp()); + row.archiveTimestamp = MiscUtil.asInstant(activation.getArchiveTimestamp()); + row.lockoutStatus = activation.getLockoutStatus(); + } + + return row; + } + + @Override + public void storeRelatedEntities( + @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) { + super.storeRelatedEntities(row, schemaObject, jdbcSession); + + storeRefs(row, schemaObject.getLinkRef(), + projectionReferenceMapping(), jdbcSession); + storeRefs(row, schemaObject.getPersonaRef(), + personaReferenceMapping(), jdbcSession); + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java index 4b60efbb6f2..0bf0c08e794 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java @@ -6,7 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.focus; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.GenericObjectType; /** @@ -30,13 +32,17 @@ protected QGenericObject newAliasInstance(String alias) { } @Override - public GenericObjectSqlTransformer createTransformer( - SqlTransformerSupport transformerSupport) { - return new GenericObjectSqlTransformer(transformerSupport, this); + public MGenericObject newRowObject() { + return new MGenericObject(); } @Override - public MGenericObject newRowObject() { - return new MGenericObject(); + public @NotNull MGenericObject toRowObjectWithoutFullObject( + GenericObjectType genericObject, JdbcSession jdbcSession) { + MGenericObject row = super.toRowObjectWithoutFullObject(genericObject, jdbcSession); + + row.genericObjectTypeId = processCacheableUri(genericObject.getObjectType()); + + return row; } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java index bb47b491e48..0458fc83e95 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java @@ -8,7 +8,9 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.UserType.*; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; /** @@ -50,13 +52,33 @@ protected QUser newAliasInstance(String alias) { } @Override - public UserSqlTransformer createTransformer( - SqlTransformerSupport transformerSupport) { - return new UserSqlTransformer(transformerSupport, this); + public MUser newRowObject() { + return new MUser(); } @Override - public MUser newRowObject() { - return new MUser(); + public @NotNull MUser toRowObjectWithoutFullObject( + UserType user, JdbcSession jdbcSession) { + MUser row = super.toRowObjectWithoutFullObject(user, jdbcSession); + + setPolyString(user.getAdditionalName(), + o -> row.additionalNameOrig = o, n -> row.additionalNameNorm = n); + row.employeeNumber = user.getEmployeeNumber(); + setPolyString(user.getFamilyName(), + o -> row.familyNameOrig = o, n -> row.familyNameNorm = n); + setPolyString(user.getFullName(), o -> row.fullNameOrig = o, n -> row.fullNameNorm = n); + setPolyString(user.getGivenName(), o -> row.givenNameOrig = o, n -> row.givenNameNorm = n); + setPolyString(user.getHonorificPrefix(), + o -> row.honorificPrefixOrig = o, n -> row.honorificPrefixNorm = n); + setPolyString(user.getHonorificSuffix(), + o -> row.honorificSuffixOrig = o, n -> row.honorificSuffixNorm = n); + setPolyString(user.getNickName(), o -> row.nickNameOrig = o, n -> row.nickNameNorm = n); + setPolyString(user.getTitle(), o -> row.titleOrig = o, n -> row.titleNorm = n); + + // TODO: + // user.getOrganizationalUnit() -> m_user_organizational_unit + // user.getOrganization() -> m_user_organization + + return row; } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/UserSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/UserSqlTransformer.java deleted file mode 100644 index a2316192798..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/UserSqlTransformer.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.focus; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; - -public class UserSqlTransformer - extends FocusSqlTransformer { - - public UserSqlTransformer( - SqlTransformerSupport transformerSupport, QUserMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MUser toRowObjectWithoutFullObject( - UserType user, JdbcSession jdbcSession) { - MUser row = super.toRowObjectWithoutFullObject(user, jdbcSession); - - setPolyString(user.getAdditionalName(), - o -> row.additionalNameOrig = o, n -> row.additionalNameNorm = n); - row.employeeNumber = user.getEmployeeNumber(); - setPolyString(user.getFamilyName(), - o -> row.familyNameOrig = o, n -> row.familyNameNorm = n); - setPolyString(user.getFullName(), o -> row.fullNameOrig = o, n -> row.fullNameNorm = n); - setPolyString(user.getGivenName(), o -> row.givenNameOrig = o, n -> row.givenNameNorm = n); - setPolyString(user.getHonorificPrefix(), - o -> row.honorificPrefixOrig = o, n -> row.honorificPrefixNorm = n); - setPolyString(user.getHonorificSuffix(), - o -> row.honorificSuffixOrig = o, n -> row.honorificSuffixNorm = n); - setPolyString(user.getNickName(), o -> row.nickNameOrig = o, n -> row.nickNameNorm = n); - setPolyString(user.getTitle(), o -> row.titleOrig = o, n -> row.titleNorm = n); - - // TODO: - // user.getOrganizationalUnit() -> m_user_organizational_unit - // user.getOrganization() -> m_user_organization - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableRowSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableRowSqlTransformer.java deleted file mode 100644 index b01d7baddd9..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableRowSqlTransformer.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.lookuptable; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ContainerSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType; - -public class LookupTableRowSqlTransformer - extends ContainerSqlTransformer { - - public LookupTableRowSqlTransformer( - SqlTransformerSupport transformerSupport, QLookupTableRowMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public MLookupTableRow insert(LookupTableRowType lookupTableRow, - MLookupTable ownerRow, JdbcSession jdbcSession) { - - MLookupTableRow row = initRowObject(lookupTableRow, ownerRow); - row.key = lookupTableRow.getKey(); - row.value = lookupTableRow.getValue(); - setPolyString(lookupTableRow.getLabel(), o -> row.labelOrig = o, n -> row.labelNorm = n); - row.lastChangeTimestamp = MiscUtil.asInstant(lookupTableRow.getLastChangeTimestamp()); - - insert(row, jdbcSession); - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableSqlTransformer.java deleted file mode 100644 index 21941971077..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableSqlTransformer.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.lookuptable; - -import java.util.List; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType; - -public class LookupTableSqlTransformer - extends ObjectSqlTransformer { - - public LookupTableSqlTransformer( - SqlTransformerSupport transformerSupport, QLookupTableMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public void storeRelatedEntities( - @NotNull MLookupTable lookupTable, - @NotNull LookupTableType schemaObject, - @NotNull JdbcSession jdbcSession) { - super.storeRelatedEntities(lookupTable, schemaObject, jdbcSession); - - List rows = schemaObject.getRow(); - if (!rows.isEmpty()) { - LookupTableRowSqlTransformer transformer = - QLookupTableRowMapping.INSTANCE.createTransformer(transformerSupport); - rows.forEach(row -> transformer.insert(row, lookupTable, jdbcSession)); - } - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java index 405d6ef9877..2156eba2e29 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java @@ -8,8 +8,13 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType.F_ROW; +import java.util.List; + +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; +import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType; /** @@ -36,12 +41,21 @@ protected QLookupTable newAliasInstance(String alias) { } @Override - public LookupTableSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new LookupTableSqlTransformer(transformerSupport, this); + public MLookupTable newRowObject() { + return new MLookupTable(); } @Override - public MLookupTable newRowObject() { - return new MLookupTable(); + public void storeRelatedEntities( + @NotNull MLookupTable lookupTable, + @NotNull LookupTableType schemaObject, + @NotNull JdbcSession jdbcSession) { + super.storeRelatedEntities(lookupTable, schemaObject, jdbcSession); + + List rows = schemaObject.getRow(); + if (!rows.isEmpty()) { + rows.forEach(row -> + QLookupTableRowMapping.INSTANCE.insert(row, lookupTable, jdbcSession)); + } } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java index faaf1e9ae64..df6f9cb8033 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java @@ -9,7 +9,8 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType.*; import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; +import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType; /** @@ -39,11 +40,6 @@ protected QLookupTableRow newAliasInstance(String alias) { return new QLookupTableRow(alias); } - @Override - public LookupTableRowSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new LookupTableRowSqlTransformer(transformerSupport, this); - } - @Override public MLookupTableRow newRowObject() { return new MLookupTableRow(); @@ -55,4 +51,18 @@ public MLookupTableRow newRowObject(MLookupTable ownerRow) { row.ownerOid = ownerRow.oid; return row; } + + @Override + public MLookupTableRow insert(LookupTableRowType lookupTableRow, + MLookupTable ownerRow, JdbcSession jdbcSession) { + + MLookupTableRow row = initRowObject(lookupTableRow, ownerRow); + row.key = lookupTableRow.getKey(); + row.value = lookupTableRow.getValue(); + setPolyString(lookupTableRow.getLabel(), o -> row.labelOrig = o, n -> row.labelNorm = n); + row.lastChangeTimestamp = MiscUtil.asInstant(lookupTableRow.getLastChangeTimestamp()); + + insert(row, jdbcSession); + return row; + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/NodeSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/NodeSqlTransformer.java deleted file mode 100644 index b6003939f26..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/NodeSqlTransformer.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.node; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType; - -public class NodeSqlTransformer - extends ObjectSqlTransformer { - - public NodeSqlTransformer( - SqlTransformerSupport transformerSupport, QNodeMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MNode toRowObjectWithoutFullObject(NodeType node, JdbcSession jdbcSession) { - MNode row = super.toRowObjectWithoutFullObject(node, jdbcSession); - - row.nodeIdentifier = node.getNodeIdentifier(); - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java index 38bf3917847..5e0dcee34df 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java @@ -8,8 +8,10 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType.F_NODE_IDENTIFIER; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType; /** @@ -34,13 +36,15 @@ protected QNode newAliasInstance(String alias) { } @Override - public NodeSqlTransformer createTransformer( - SqlTransformerSupport transformerSupport) { - return new NodeSqlTransformer(transformerSupport, this); + public MNode newRowObject() { + return new MNode(); } @Override - public MNode newRowObject() { - return new MNode(); + public @NotNull MNode toRowObjectWithoutFullObject(NodeType node, JdbcSession jdbcSession) { + MNode row = super.toRowObjectWithoutFullObject(node, jdbcSession); + + row.nodeIdentifier = node.getNodeIdentifier(); + return row; } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ContainerSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ContainerSqlTransformer.java deleted file mode 100644 index 4788cdb3bef..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ContainerSqlTransformer.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.object; - -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTransformerBase; -import com.evolveum.midpoint.repo.sqale.qmodel.TransformerForOwnedBy; -import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainer; -import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainer; -import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; - -/** - * @param schema type - * @param type of entity path - * @param type of the row bean for the table - * @param type of the owner row (table owning the container) - */ -public class ContainerSqlTransformer - , R extends MContainer, OR> - extends SqaleTransformerBase - implements TransformerForOwnedBy { - - private final QContainerMapping mapping; - - public ContainerSqlTransformer( - SqlTransformerSupport transformerSupport, QContainerMapping mapping) { - super(transformerSupport); - this.mapping = mapping; - } - - @Override - protected QContainerMapping mapping() { - return mapping; - } - - /** - * This creates the right type of object and fills in the base {@link MContainer} attributes. - */ - public R initRowObject(S schemaObject, OR ownerRow) { - R row = mapping.newRowObject(ownerRow); - row.cid = schemaObject.asPrismContainerValue().getId(); - // containerType is generated in DB, must be left null! - return row; - } - - @Override - public R insert(S schemaObject, OR ownerRow, JdbcSession jdbcSession) { - throw new UnsupportedOperationException("insert not implemented in the subclass"); - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ObjectSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ObjectSqlTransformer.java deleted file mode 100644 index f34779d1dce..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ObjectSqlTransformer.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.object; - -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import javax.xml.namespace.QName; - -import com.querydsl.core.Tuple; -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.SerializationOptions; -import com.evolveum.midpoint.repo.sqale.SqaleUtils; -import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTransformerBase; -import com.evolveum.midpoint.repo.sqale.qmodel.assignment.AssignmentSqlTransformer; -import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.SelectorOptions; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; - -public class ObjectSqlTransformer, R extends MObject> - extends SqaleTransformerBase { - - private final QObjectMapping mapping; - - public ObjectSqlTransformer( - SqlTransformerSupport transformerSupport, - QObjectMapping mapping) { - super(transformerSupport); - this.mapping = mapping; - } - - @Override - protected QObjectMapping mapping() { - return mapping; - } - - @Override - public S toSchemaObject(Tuple row, Q entityPath, - Collection> options) - throws SchemaException { - - byte[] fullObject = Objects.requireNonNull(row.get(entityPath.fullObject)); - - PrismObject prismObject; - String serializedForm = new String(fullObject, StandardCharsets.UTF_8); - try { - SqlTransformerSupport.ParseResult result = - transformerSupport.parsePrismObject(serializedForm); - prismObject = result.prismObject; - if (result.parsingContext.hasWarnings()) { - logger.warn("Object {} parsed with {} warnings", - ObjectTypeUtil.toShortString(prismObject), - result.parsingContext.getWarnings().size()); - } - } catch (SchemaException | RuntimeException | Error e) { - // This is a serious thing. We have corrupted XML in the repo. This may happen even - // during system init. We want really loud and detailed error here. - logger.error("Couldn't parse object {} {}: {}: {}\n{}", - mapping.schemaType().getSimpleName(), row.get(entityPath.oid), - e.getClass().getName(), e.getMessage(), serializedForm, e); - throw e; - } - - return prismObject.asObjectable(); - } - - /** - * Override this to fill additional row attributes after calling this super version. - * - * *This must be called with active JDBC session* so it can create new {@link QUri} rows. - * As this is intended for inserts *DO NOT* set {@link MObject#objectType} to any value, - * it must be NULL otherwise the DB will complain about the value for the generated column. - * - * OID may be null, hence the method does NOT create any sub-entities, see - * {@link #storeRelatedEntities(MObject, ObjectType, JdbcSession)}. - * Try to keep order of fields here, in M-class (MObject for this one) and in SQL the same. - */ - @SuppressWarnings("DuplicatedCode") // see comment for metadata lower - @NotNull - public R toRowObjectWithoutFullObject(S schemaObject, JdbcSession jdbcSession) { - R row = mapping.newRowObject(); - - row.oid = oidToUUid(schemaObject.getOid()); - // objectType MUST be left NULL for INSERT, it's determined by PG - setPolyString(schemaObject.getName(), o -> row.nameOrig = o, n -> row.nameNorm = n); - // fullObject is managed outside of this method - setReference(schemaObject.getTenantRef(), - o -> row.tenantRefTargetOid = o, - t -> row.tenantRefTargetType = t, - r -> row.tenantRefRelationId = r); - row.lifecycleState = schemaObject.getLifecycleState(); - // containerIdSeq is managed outside of this method - row.version = SqaleUtils.objectVersionAsInt(schemaObject); - - // complex DB fields - row.policySituations = processCacheableUris(schemaObject.getPolicySituation()); - row.subtypes = arrayFor(schemaObject.getSubtype()); - // TODO textInfo (fulltext support) - // repo.getTextInfoItems().addAll(RObjectTextInfo.createItemsSet(jaxb, repo, repositoryContext)); - // TODO extensions stored inline (JSON) - that is ext column - - // This is duplicate code with AssignmentSqlTransformer.toRowObject, but making interface - // and needed setters (fields are not "interface-able") would create much more code. - MetadataType metadata = schemaObject.getMetadata(); - if (metadata != null) { - setReference(metadata.getCreatorRef(), - o -> row.creatorRefTargetOid = o, - t -> row.creatorRefTargetType = t, - r -> row.creatorRefRelationId = r); - row.createChannelId = processCacheableUri(metadata.getCreateChannel()); - row.createTimestamp = MiscUtil.asInstant(metadata.getCreateTimestamp()); - - setReference(metadata.getModifierRef(), - o -> row.modifierRefTargetOid = o, - t -> row.modifierRefTargetType = t, - r -> row.modifierRefRelationId = r); - row.modifyChannelId = processCacheableUri(metadata.getModifyChannel()); - row.modifyTimestamp = MiscUtil.asInstant(metadata.getModifyTimestamp()); - } - return row; - } - - /** - * Stores other entities related to the main object row like containers, references, etc. - * This is not part of {@link #toRowObjectWithoutFullObject} because it requires know OID - * which is not assured before calling that method. - * - * *Always call this super method first in overriding methods.* - * - * @param row master row for the added object("aggregate root") - * @param schemaObject schema objects for which the details are stored - * @param jdbcSession JDBC session used to insert related rows - */ - public void storeRelatedEntities( - @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) { - Objects.requireNonNull(row.oid); - - // We're after insert, we can set this for the needs of owned entities (assignments). - row.objectType = MObjectType.fromSchemaType(schemaObject.getClass()); - - MetadataType metadata = schemaObject.getMetadata(); - if (metadata != null) { - storeRefs(row, metadata.getCreateApproverRef(), - mapping.objectCreateApproverReferenceMapping(), jdbcSession); - storeRefs(row, metadata.getModifyApproverRef(), - mapping.objectModifyApproverReferenceMapping(), jdbcSession); - } - - List triggers = schemaObject.getTrigger(); - if (!triggers.isEmpty()) { - TriggerSqlTransformer transformer = - mapping.triggerMapping().createTransformer(transformerSupport); - triggers.forEach(t -> transformer.insert(t, row, jdbcSession)); - } - - List operationExecutions = schemaObject.getOperationExecution(); - if (!operationExecutions.isEmpty()) { - OperationExecutionSqlTransformer transformer = - mapping.operationExecutionMapping().createTransformer(transformerSupport); - operationExecutions.forEach(oe -> transformer.insert(oe, row, jdbcSession)); - } - - storeRefs(row, schemaObject.getParentOrgRef(), - mapping.objectParentOrgReferenceMapping(), jdbcSession); - - if (schemaObject instanceof AssignmentHolderType) { - storeAssignmentHolderEntities(row, (AssignmentHolderType) schemaObject, jdbcSession); - } - - /* TODO EAV extensions - the relevant code from old repo RObject#copyObjectInformationFromJAXB - if (jaxb.getExtension() != null) { - copyExtensionOrAttributesFromJAXB(jaxb.getExtension().asPrismContainerValue(), repo, repositoryContext, RObjectExtensionType.EXTENSION, generatorResult); - } - */ - } - - private void storeAssignmentHolderEntities( - R row, AssignmentHolderType schemaObject, JdbcSession jdbcSession) { - List assignments = schemaObject.getAssignment(); - if (!assignments.isEmpty()) { - AssignmentSqlTransformer transformer = - mapping.assignmentMapping().createTransformer(transformerSupport); - assignments.forEach(assignment -> - transformer.insert(assignment, row, jdbcSession)); - } - - storeRefs(row, schemaObject.getArchetypeRef(), - mapping.archetypeReferenceMapping(), jdbcSession); - storeRefs(row, schemaObject.getDelegatedRef(), - mapping.delegatedReferenceMapping(), jdbcSession); - storeRefs(row, schemaObject.getRoleMembershipRef(), - mapping.roleMembershipReferenceMapping(), jdbcSession); - } - - /** - * Serializes schema object and sets {@link R#fullObject}. - */ - public void setFullObject(R row, S schemaObject) throws SchemaException { - row.fullObject = createFullObject(schemaObject); - } - - public byte[] createFullObject(S schemaObject) throws SchemaException { - if (schemaObject.getOid() == null || schemaObject.getVersion() == null) { - throw new IllegalArgumentException( - "Serialized object must have assigned OID and version: " + schemaObject); - } - - return transformerSupport.createStringSerializer() - .itemsToSkip(fullObjectItemsToSkip()) - .options(SerializationOptions - .createSerializeReferenceNamesForNullOids() - .skipIndexOnly(true) - .skipTransient(true)) - .serialize(schemaObject.asPrismObject()) - .getBytes(StandardCharsets.UTF_8); - } - - protected Collection fullObjectItemsToSkip() { - // TODO extend later, things like FocusType.F_JPEG_PHOTO, see ObjectUpdater#updateFullObject - return Collections.emptyList(); - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/OperationExecutionSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/OperationExecutionSqlTransformer.java deleted file mode 100644 index 3048955b408..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/OperationExecutionSqlTransformer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.object; - -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationExecutionType; - -public class OperationExecutionSqlTransformer - extends ContainerSqlTransformer, MOperationExecution, OR> { - - public OperationExecutionSqlTransformer( - SqlTransformerSupport transformerSupport, QOperationExecutionMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public MOperationExecution insert( - OperationExecutionType schemaObject, OR ownerRow, JdbcSession jdbcSession) { - MOperationExecution row = initRowObject(schemaObject, ownerRow); - - row.status = schemaObject.getStatus(); - row.recordType = schemaObject.getRecordType(); - setReference(schemaObject.getInitiatorRef(), - o -> row.initiatorRefTargetOid = o, - t -> row.initiatorRefTargetType = t, - r -> row.initiatorRefRelationId = r); - setReference(schemaObject.getTaskRef(), - o -> row.taskRefTargetOid = o, - t -> row.taskRefTargetType = t, - r -> row.taskRefRelationId = r); - row.timestampValue = MiscUtil.asInstant(schemaObject.getTimestamp()); - - insert(row, jdbcSession); - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java index f33c8922acb..8dd59af9d46 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java @@ -8,22 +8,35 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType.*; +import java.nio.charset.StandardCharsets; import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import javax.xml.namespace.QName; +import com.querydsl.core.Tuple; import com.querydsl.core.types.Path; import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.prism.PrismConstants; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.SerializationOptions; +import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport; +import com.evolveum.midpoint.repo.sqale.SqaleUtils; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentMapping; +import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.util.MiscUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; /** * Mapping between {@link QObject} and {@link ObjectType}. @@ -171,7 +184,7 @@ protected Q newAliasInstance(String alias) { @Override public SqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new ObjectSqlTransformer<>(transformerSupport, this); + return this; } @Override @@ -179,4 +192,187 @@ public R newRowObject() { //noinspection unchecked return (R) new MObject(); } + + // region transformation + @Override + public S toSchemaObject(Tuple row, Q entityPath, + Collection> options) + throws SchemaException { + + byte[] fullObject = Objects.requireNonNull(row.get(entityPath.fullObject)); + + PrismObject prismObject; + String serializedForm = new String(fullObject, StandardCharsets.UTF_8); + try { + SqlTransformerSupport.ParseResult result = + SqaleTransformerSupport.getInstance().parsePrismObject(serializedForm); + prismObject = result.prismObject; + if (result.parsingContext.hasWarnings()) { + logger.warn("Object {} parsed with {} warnings", + ObjectTypeUtil.toShortString(prismObject), + result.parsingContext.getWarnings().size()); + } + } catch (SchemaException | RuntimeException | Error e) { + // This is a serious thing. We have corrupted XML in the repo. This may happen even + // during system init. We want really loud and detailed error here. + logger.error("Couldn't parse object {} {}: {}: {}\n{}", + schemaType().getSimpleName(), row.get(entityPath.oid), + e.getClass().getName(), e.getMessage(), serializedForm, e); + throw e; + } + + return prismObject.asObjectable(); + } + + /** + * Override this to fill additional row attributes after calling this super version. + * + * *This must be called with active JDBC session* so it can create new {@link QUri} rows. + * As this is intended for inserts *DO NOT* set {@link MObject#objectType} to any value, + * it must be NULL otherwise the DB will complain about the value for the generated column. + * + * OID may be null, hence the method does NOT create any sub-entities, see + * {@link #storeRelatedEntities(MObject, ObjectType, JdbcSession)}. + * Try to keep order of fields here, in M-class (MObject for this one) and in SQL the same. + */ + @SuppressWarnings("DuplicatedCode") // see comment for metadata lower + @NotNull + public R toRowObjectWithoutFullObject(S schemaObject, JdbcSession jdbcSession) { + R row = newRowObject(); + + row.oid = oidToUUid(schemaObject.getOid()); + // objectType MUST be left NULL for INSERT, it's determined by PG + setPolyString(schemaObject.getName(), o -> row.nameOrig = o, n -> row.nameNorm = n); + // fullObject is managed outside of this method + setReference(schemaObject.getTenantRef(), + o -> row.tenantRefTargetOid = o, + t -> row.tenantRefTargetType = t, + r -> row.tenantRefRelationId = r); + row.lifecycleState = schemaObject.getLifecycleState(); + // containerIdSeq is managed outside of this method + row.version = SqaleUtils.objectVersionAsInt(schemaObject); + + // complex DB fields + row.policySituations = processCacheableUris(schemaObject.getPolicySituation()); + row.subtypes = arrayFor(schemaObject.getSubtype()); + // TODO textInfo (fulltext support) + // repo.getTextInfoItems().addAll(RObjectTextInfo.createItemsSet(jaxb, repo, repositoryContext)); + // TODO extensions stored inline (JSON) - that is ext column + + // This is duplicate code with AssignmentSqlTransformer.toRowObject, but making interface + // and needed setters (fields are not "interface-able") would create much more code. + MetadataType metadata = schemaObject.getMetadata(); + if (metadata != null) { + setReference(metadata.getCreatorRef(), + o -> row.creatorRefTargetOid = o, + t -> row.creatorRefTargetType = t, + r -> row.creatorRefRelationId = r); + row.createChannelId = processCacheableUri(metadata.getCreateChannel()); + row.createTimestamp = MiscUtil.asInstant(metadata.getCreateTimestamp()); + + setReference(metadata.getModifierRef(), + o -> row.modifierRefTargetOid = o, + t -> row.modifierRefTargetType = t, + r -> row.modifierRefRelationId = r); + row.modifyChannelId = processCacheableUri(metadata.getModifyChannel()); + row.modifyTimestamp = MiscUtil.asInstant(metadata.getModifyTimestamp()); + } + return row; + } + + /** + * Stores other entities related to the main object row like containers, references, etc. + * This is not part of {@link #toRowObjectWithoutFullObject} because it requires know OID + * which is not assured before calling that method. + * + * *Always call this super method first in overriding methods.* + * + * @param row master row for the added object("aggregate root") + * @param schemaObject schema objects for which the details are stored + * @param jdbcSession JDBC session used to insert related rows + */ + public void storeRelatedEntities( + @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) { + Objects.requireNonNull(row.oid); + + // We're after insert, we can set this for the needs of owned entities (assignments). + row.objectType = MObjectType.fromSchemaType(schemaObject.getClass()); + + MetadataType metadata = schemaObject.getMetadata(); + if (metadata != null) { + storeRefs(row, metadata.getCreateApproverRef(), + objectCreateApproverReferenceMapping(), jdbcSession); + storeRefs(row, metadata.getModifyApproverRef(), + objectModifyApproverReferenceMapping(), jdbcSession); + } + + List triggers = schemaObject.getTrigger(); + if (!triggers.isEmpty()) { + triggers.forEach(t -> triggerMapping().insert(t, row, jdbcSession)); + } + + List operationExecutions = schemaObject.getOperationExecution(); + if (!operationExecutions.isEmpty()) { + operationExecutions.forEach(oe -> + operationExecutionMapping().insert(oe, row, jdbcSession)); + } + + storeRefs(row, schemaObject.getParentOrgRef(), + objectParentOrgReferenceMapping(), jdbcSession); + + if (schemaObject instanceof AssignmentHolderType) { + storeAssignmentHolderEntities(row, (AssignmentHolderType) schemaObject, jdbcSession); + } + + /* TODO EAV extensions - the relevant code from old repo RObject#copyObjectInformationFromJAXB + if (jaxb.getExtension() != null) { + copyExtensionOrAttributesFromJAXB(jaxb.getExtension().asPrismContainerValue(), repo, repositoryContext, RObjectExtensionType.EXTENSION, generatorResult); + } + */ + } + + private void storeAssignmentHolderEntities( + R row, AssignmentHolderType schemaObject, JdbcSession jdbcSession) { + List assignments = schemaObject.getAssignment(); + if (!assignments.isEmpty()) { + assignments.forEach(assignment -> + assignmentMapping().insert(assignment, row, jdbcSession)); + } + + storeRefs(row, schemaObject.getArchetypeRef(), + archetypeReferenceMapping(), jdbcSession); + storeRefs(row, schemaObject.getDelegatedRef(), + delegatedReferenceMapping(), jdbcSession); + storeRefs(row, schemaObject.getRoleMembershipRef(), + roleMembershipReferenceMapping(), jdbcSession); + } + + /** + * Serializes schema object and sets {@link R#fullObject}. + */ + public void setFullObject(R row, S schemaObject) throws SchemaException { + row.fullObject = createFullObject(schemaObject); + } + + public byte[] createFullObject(S schemaObject) throws SchemaException { + if (schemaObject.getOid() == null || schemaObject.getVersion() == null) { + throw new IllegalArgumentException( + "Serialized object must have assigned OID and version: " + schemaObject); + } + + return SqaleTransformerSupport.getInstance().createStringSerializer() + .itemsToSkip(fullObjectItemsToSkip()) + .options(SerializationOptions + .createSerializeReferenceNamesForNullOids() + .skipIndexOnly(true) + .skipTransient(true)) + .serialize(schemaObject.asPrismObject()) + .getBytes(StandardCharsets.UTF_8); + } + + protected Collection fullObjectItemsToSkip() { + // TODO extend later, things like FocusType.F_JPEG_PHOTO, see ObjectUpdater#updateFullObject + return Collections.emptyList(); + } + // endregion } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java index 427bed89379..25e65d8f0e5 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java @@ -9,7 +9,8 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.OperationExecutionType.*; import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; +import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationExecutionType; /** @@ -50,12 +51,6 @@ protected QOperationExecution newAliasInstance(String alias) { return new QOperationExecution<>(alias); } - @Override - public OperationExecutionSqlTransformer createTransformer( - SqlTransformerSupport transformerSupport) { - return new OperationExecutionSqlTransformer<>(transformerSupport, this); - } - @Override public MOperationExecution newRowObject() { return new MOperationExecution(); @@ -67,4 +62,25 @@ public MOperationExecution newRowObject(OR ownerRow) { row.ownerOid = ownerRow.oid; return row; } + + @Override + public MOperationExecution insert( + OperationExecutionType schemaObject, OR ownerRow, JdbcSession jdbcSession) { + MOperationExecution row = initRowObject(schemaObject, ownerRow); + + row.status = schemaObject.getStatus(); + row.recordType = schemaObject.getRecordType(); + setReference(schemaObject.getInitiatorRef(), + o -> row.initiatorRefTargetOid = o, + t -> row.initiatorRefTargetType = t, + r -> row.initiatorRefRelationId = r); + setReference(schemaObject.getTaskRef(), + o -> row.taskRefTargetOid = o, + t -> row.taskRefTargetType = t, + r -> row.taskRefRelationId = r); + row.timestampValue = MiscUtil.asInstant(schemaObject.getTimestamp()); + + insert(row, jdbcSession); + return row; + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java index dd1019ddf14..6cf8fefe560 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java @@ -7,7 +7,8 @@ package com.evolveum.midpoint.repo.sqale.qmodel.object; import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; +import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.TriggerType; /** @@ -37,11 +38,6 @@ protected QTrigger newAliasInstance(String alias) { return new QTrigger<>(alias); } - @Override - public TriggerSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new TriggerSqlTransformer<>(transformerSupport, this); - } - @Override public MTrigger newRowObject() { return new MTrigger(); @@ -53,4 +49,15 @@ public MTrigger newRowObject(OR ownerRow) { row.ownerOid = ownerRow.oid; return row; } + + @Override + public MTrigger insert(TriggerType schemaObject, OR ownerRow, JdbcSession jdbcSession) { + MTrigger row = initRowObject(schemaObject, ownerRow); + + row.handlerUriId = processCacheableUri(schemaObject.getHandlerUri()); + row.timestampValue = MiscUtil.asInstant(schemaObject.getTimestamp()); + + insert(row, jdbcSession); + return row; + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/TriggerSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/TriggerSqlTransformer.java deleted file mode 100644 index 77c42cb0974..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/TriggerSqlTransformer.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.object; - -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TriggerType; - -public class TriggerSqlTransformer - extends ContainerSqlTransformer, MTrigger, OR> { - - public TriggerSqlTransformer( - SqlTransformerSupport transformerSupport, QTriggerMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public MTrigger insert(TriggerType schemaObject, OR ownerRow, JdbcSession jdbcSession) { - MTrigger row = initRowObject(schemaObject, ownerRow); - - row.handlerUriId = processCacheableUri(schemaObject.getHandlerUri()); - row.timestampValue = MiscUtil.asInstant(schemaObject.getTimestamp()); - - insert(row, jdbcSession); - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QDashboardMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QDashboardMapping.java index 79a2ce5f5f4..856f3292201 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QDashboardMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QDashboardMapping.java @@ -7,9 +7,7 @@ package com.evolveum.midpoint.repo.sqale.qmodel.other; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardType; /** @@ -32,13 +30,6 @@ protected QDashboard newAliasInstance(String alias) { return new QDashboard(alias); } - @Override - public ObjectSqlTransformer - createTransformer(SqlTransformerSupport transformerSupport) { - // no special class needed, no additional columns - return new ObjectSqlTransformer<>(transformerSupport, this); - } - @Override public MObject newRowObject() { return new MObject(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFormMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFormMapping.java index cb52224d9ef..c85a7e07553 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFormMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFormMapping.java @@ -7,9 +7,7 @@ package com.evolveum.midpoint.repo.sqale.qmodel.other; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.FormType; /** @@ -31,13 +29,6 @@ protected QForm newAliasInstance(String alias) { return new QForm(alias); } - @Override - public ObjectSqlTransformer - createTransformer(SqlTransformerSupport transformerSupport) { - // no special class needed, no additional columns - return new ObjectSqlTransformer<>(transformerSupport, this); - } - @Override public MObject newRowObject() { return new MObject(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFunctionLibraryMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFunctionLibraryMapping.java index 4045a9c7354..f4ca68fb11e 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFunctionLibraryMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFunctionLibraryMapping.java @@ -7,9 +7,7 @@ package com.evolveum.midpoint.repo.sqale.qmodel.other; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.FunctionLibraryType; /** @@ -32,13 +30,6 @@ protected QFunctionLibrary newAliasInstance(String alias) { return new QFunctionLibrary(alias); } - @Override - public ObjectSqlTransformer - createTransformer(SqlTransformerSupport transformerSupport) { - // no special class needed, no additional columns - return new ObjectSqlTransformer<>(transformerSupport, this); - } - @Override public MObject newRowObject() { return new MObject(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QObjectCollectionMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QObjectCollectionMapping.java index 689429112eb..d6b6b485bc3 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QObjectCollectionMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QObjectCollectionMapping.java @@ -7,9 +7,7 @@ package com.evolveum.midpoint.repo.sqale.qmodel.other; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectCollectionType; /** @@ -32,13 +30,6 @@ protected QObjectCollection newAliasInstance(String alias) { return new QObjectCollection(alias); } - @Override - public ObjectSqlTransformer - createTransformer(SqlTransformerSupport transformerSupport) { - // no special class needed, no additional columns - return new ObjectSqlTransformer<>(transformerSupport, this); - } - @Override public MObject newRowObject() { return new MObject(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QSequenceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QSequenceMapping.java index d73c213ef1f..76c62f5a41d 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QSequenceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QSequenceMapping.java @@ -7,9 +7,7 @@ package com.evolveum.midpoint.repo.sqale.qmodel.other; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.SequenceType; /** @@ -31,13 +29,6 @@ protected QSequence newAliasInstance(String alias) { return new QSequence(alias); } - @Override - public ObjectSqlTransformer - createTransformer(SqlTransformerSupport transformerSupport) { - // no special class needed, no additional columns - return new ObjectSqlTransformer<>(transformerSupport, this); - } - @Override public MObject newRowObject() { return new MObject(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java index cce8979b28c..37c5138901e 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java @@ -6,6 +6,7 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.ref; +import java.util.UUID; import java.util.function.BiFunction; import com.querydsl.core.types.Predicate; @@ -13,6 +14,7 @@ import com.evolveum.midpoint.prism.Referencable; import com.evolveum.midpoint.repo.sqale.qmodel.QOwnedByMapping; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; @@ -59,10 +61,9 @@ protected Q newAliasInstance(String alias) { return (Q) new QReference<>(MReference.class, alias); } - @Override - public ReferenceSqlTransformer createTransformer( + public QReferenceMapping createTransformer( SqlTransformerSupport transformerSupport) { - return new ReferenceSqlTransformer<>(transformerSupport, this); + return this; } /** Defines a contract for creating the reference for the provided owner row. */ @@ -76,4 +77,21 @@ public BiFunction joinOnPredicate() { throw new UnsupportedOperationException( "joinOnPredicate not supported on abstract reference mapping"); } + + /** + * There is no need to override this, only reference creation is different and that is covered + * by {@link QReferenceMapping#newRowObject(Object)} including setting FK columns. + * All the other columns are based on a single schema type, so there is no variation. + */ + @Override + public R insert(Referencable schemaObject, OR ownerRow, JdbcSession jdbcSession) { + R row = newRowObject(ownerRow); + // row.referenceType is DB generated, must be kept NULL, but it will match referenceType + row.relationId = processCacheableRelation(schemaObject.getRelation()); + row.targetOid = UUID.fromString(schemaObject.getOid()); + row.targetType = schemaTypeToObjectType(schemaObject.getType()); + + insert(row, jdbcSession); + return row; + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/ReferenceSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/ReferenceSqlTransformer.java deleted file mode 100644 index d42fb232724..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/ReferenceSqlTransformer.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.ref; - -import java.util.UUID; - -import com.evolveum.midpoint.prism.Referencable; -import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTransformerBase; -import com.evolveum.midpoint.repo.sqale.qmodel.TransformerForOwnedBy; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; - -/** - * @param type of entity path for the reference table - * @param type of the transformed data, a row bean - * @param row type of the reference owner - */ -public class ReferenceSqlTransformer, R extends MReference, OR> - extends SqaleTransformerBase - implements TransformerForOwnedBy { - - private final QReferenceMapping mapping; - - public ReferenceSqlTransformer( - SqlTransformerSupport transformerSupport, QReferenceMapping mapping) { - super(transformerSupport); - this.mapping = mapping; - } - - @Override - protected QReferenceMapping mapping() { - return mapping; - } - - /** - * There is no need to override this, only reference creation is different and that is covered - * by {@link QReferenceMapping#newRowObject(Object)} including setting FK columns. - * All the other columns are based on a single schema type, so there is no variation. - */ - @Override - public R insert(Referencable schemaObject, OR ownerRow, JdbcSession jdbcSession) { - R row = mapping.newRowObject(ownerRow); - // row.referenceType is DB generated, must be kept NULL, but it will match referenceType - row.relationId = processCacheableRelation(schemaObject.getRelation()); - row.targetOid = UUID.fromString(schemaObject.getOid()); - row.targetType = schemaTypeToObjectType(schemaObject.getType()); - - insert(row, jdbcSession); - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java index 4f4c393fece..04dd1e88576 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java @@ -8,7 +8,10 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.ReportDataType.F_REPORT_REF; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportDataType; @@ -38,12 +41,25 @@ protected QReportData newAliasInstance(String alias) { } @Override - public ReportDataSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new ReportDataSqlTransformer(transformerSupport, this); + public QReportDataMapping createTransformer(SqlTransformerSupport transformerSupport) { + return this; } @Override public MReportData newRowObject() { return new MReportData(); } + + @Override + public @NotNull MReportData toRowObjectWithoutFullObject( + ReportDataType reportData, JdbcSession jdbcSession) { + MReportData row = super.toRowObjectWithoutFullObject(reportData, jdbcSession); + + setReference(reportData.getReportRef(), + o -> row.reportRefTargetOid = o, + t -> row.reportRefTargetType = t, + r -> row.reportRefRelationId = r); + + return row; + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java index 4e7ecc3a4c0..74ef986fdbd 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java @@ -6,7 +6,10 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.report; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.JasperReportEngineConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportType; @@ -38,12 +41,26 @@ protected QReport newAliasInstance(String alias) { } @Override - public ReportSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new ReportSqlTransformer(transformerSupport, this); + public QReportMapping createTransformer(SqlTransformerSupport transformerSupport) { + return this; } @Override public MReport newRowObject() { return new MReport(); } + + @Override + public @NotNull MReport toRowObjectWithoutFullObject( + ReportType schemaObject, JdbcSession jdbcSession) { + MReport row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); + + JasperReportEngineConfigurationType jasper = schemaObject.getJasper(); + if (jasper != null) { + row.orientation = jasper.getOrientation(); + row.parent = jasper.isParent(); + } + + return row; + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/ReportDataSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/ReportDataSqlTransformer.java deleted file mode 100644 index 24a9bbe40da..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/ReportDataSqlTransformer.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.report; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportDataType; - -public class ReportDataSqlTransformer - extends ObjectSqlTransformer { - - public ReportDataSqlTransformer( - SqlTransformerSupport transformerSupport, QReportDataMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MReportData toRowObjectWithoutFullObject( - ReportDataType reportData, JdbcSession jdbcSession) { - MReportData row = super.toRowObjectWithoutFullObject(reportData, jdbcSession); - - setReference(reportData.getReportRef(), - o -> row.reportRefTargetOid = o, - t -> row.reportRefTargetType = t, - r -> row.reportRefRelationId = r); - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/ReportSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/ReportSqlTransformer.java deleted file mode 100644 index ff2a51847e2..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/ReportSqlTransformer.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.report; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.JasperReportEngineConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportType; - -public class ReportSqlTransformer - extends ObjectSqlTransformer { - - public ReportSqlTransformer( - SqlTransformerSupport transformerSupport, QReportMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MReport toRowObjectWithoutFullObject( - ReportType schemaObject, JdbcSession jdbcSession) { - MReport row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); - - JasperReportEngineConfigurationType jasper = schemaObject.getJasper(); - if (jasper != null) { - row.orientation = jasper.getOrientation(); - row.parent = jasper.isParent(); - } - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java index ae5eaafa2b7..b5b72b7229c 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java @@ -8,8 +8,11 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType.*; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationalStateType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceBusinessConfigurationType; @@ -49,12 +52,49 @@ protected QResource newAliasInstance(String alias) { } @Override - public ResourceSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new ResourceSqlTransformer(transformerSupport, this); + public QResourceMapping createTransformer(SqlTransformerSupport transformerSupport) { + return this; } @Override public MResource newRowObject() { return new MResource(); } + + @Override + public @NotNull MResource toRowObjectWithoutFullObject( + ResourceType schemaObject, JdbcSession jdbcSession) { + MResource row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); + + ResourceBusinessConfigurationType business = schemaObject.getBusiness(); + if (business != null) { + row.businessAdministrativeState = business.getAdministrativeState(); + } + + OperationalStateType operationalState = schemaObject.getOperationalState(); + if (operationalState != null) { + row.operationalStateLastAvailabilityStatus = + operationalState.getLastAvailabilityStatus(); + } + + setReference(schemaObject.getConnectorRef(), + o -> row.connectorRefTargetOid = o, + t -> row.connectorRefTargetType = t, + r -> row.connectorRefRelationId = r); + + return row; + } + + @Override + public void storeRelatedEntities(@NotNull MResource row, + @NotNull ResourceType schemaObject, @NotNull JdbcSession jdbcSession) { + super.storeRelatedEntities(row, schemaObject, jdbcSession); + + ResourceBusinessConfigurationType business = schemaObject.getBusiness(); + if (business != null) { + storeRefs(row, business.getApproverRef(), + QObjectReferenceMapping.INSTANCE_RESOURCE_BUSINESS_CONFIGURATION_APPROVER, + jdbcSession); + } + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/ResourceSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/ResourceSqlTransformer.java deleted file mode 100644 index bce4d17a50c..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/ResourceSqlTransformer.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.resource; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationalStateType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceBusinessConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; - -public class ResourceSqlTransformer - extends ObjectSqlTransformer { - - public ResourceSqlTransformer( - SqlTransformerSupport transformerSupport, QResourceMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MResource toRowObjectWithoutFullObject( - ResourceType schemaObject, JdbcSession jdbcSession) { - MResource row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); - - ResourceBusinessConfigurationType business = schemaObject.getBusiness(); - if (business != null) { - row.businessAdministrativeState = business.getAdministrativeState(); - } - - OperationalStateType operationalState = schemaObject.getOperationalState(); - if (operationalState != null) { - row.operationalStateLastAvailabilityStatus = - operationalState.getLastAvailabilityStatus(); - } - - setReference(schemaObject.getConnectorRef(), - o -> row.connectorRefTargetOid = o, - t -> row.connectorRefTargetType = t, - r -> row.connectorRefRelationId = r); - - return row; - } - - @Override - public void storeRelatedEntities(@NotNull MResource row, - @NotNull ResourceType schemaObject, @NotNull JdbcSession jdbcSession) { - super.storeRelatedEntities(row, schemaObject, jdbcSession); - - ResourceBusinessConfigurationType business = schemaObject.getBusiness(); - if (business != null) { - storeRefs(row, business.getApproverRef(), - QObjectReferenceMapping.INSTANCE_RESOURCE_BUSINESS_CONFIGURATION_APPROVER, - jdbcSession); - } - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/AbstractRoleSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/AbstractRoleSqlTransformer.java deleted file mode 100644 index 6b7c83f22d0..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/AbstractRoleSqlTransformer.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.role; - -import java.util.List; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.assignment.AssignmentSqlTransformer; -import com.evolveum.midpoint.repo.sqale.qmodel.focus.FocusSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AutoassignSpecificationType; - -public class AbstractRoleSqlTransformer< - S extends AbstractRoleType, Q extends QAbstractRole, R extends MAbstractRole> - extends FocusSqlTransformer { - - public AbstractRoleSqlTransformer( - SqlTransformerSupport transformerSupport, QAbstractRoleMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull R toRowObjectWithoutFullObject(S abstractRole, JdbcSession jdbcSession) { - R row = super.toRowObjectWithoutFullObject(abstractRole, jdbcSession); - - AutoassignSpecificationType autoassign = abstractRole.getAutoassign(); - if (autoassign != null) { - row.autoAssignEnabled = autoassign.isEnabled(); - } - setPolyString(abstractRole.getDisplayName(), - o -> row.displayNameOrig = o, n -> row.displayNameNorm = n); - row.identifier = abstractRole.getIdentifier(); - row.requestable = abstractRole.isRequestable(); - row.riskLevel = abstractRole.getRiskLevel(); - return row; - } - - @Override - public void storeRelatedEntities( - @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) { - super.storeRelatedEntities(row, schemaObject, jdbcSession); - - List inducement = schemaObject.getInducement(); - if (!inducement.isEmpty()) { - AssignmentSqlTransformer transformer = - mapping().inducementMapping().createTransformer(transformerSupport); - inducement.forEach(assignment -> - transformer.insert(assignment, row, jdbcSession)); - } - } - - @Override - protected QAbstractRoleMapping mapping() { - return (QAbstractRoleMapping) super.mapping(); - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java index b0abeb426ef..c1f69a05847 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java @@ -8,12 +8,15 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType.*; +import java.util.List; + import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentMapping; import com.evolveum.midpoint.repo.sqale.qmodel.focus.QFocusMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AutoassignSpecificationType; /** @@ -68,8 +71,30 @@ protected Q newAliasInstance(String alias) { } @Override - public AbstractRoleSqlTransformer createTransformer( - SqlTransformerSupport transformerSupport) { - return new AbstractRoleSqlTransformer<>(transformerSupport, this); + public @NotNull R toRowObjectWithoutFullObject(S abstractRole, JdbcSession jdbcSession) { + R row = super.toRowObjectWithoutFullObject(abstractRole, jdbcSession); + + AutoassignSpecificationType autoassign = abstractRole.getAutoassign(); + if (autoassign != null) { + row.autoAssignEnabled = autoassign.isEnabled(); + } + setPolyString(abstractRole.getDisplayName(), + o -> row.displayNameOrig = o, n -> row.displayNameNorm = n); + row.identifier = abstractRole.getIdentifier(); + row.requestable = abstractRole.isRequestable(); + row.riskLevel = abstractRole.getRiskLevel(); + return row; + } + + @Override + public void storeRelatedEntities( + @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) { + super.storeRelatedEntities(row, schemaObject, jdbcSession); + + List inducement = schemaObject.getInducement(); + if (!inducement.isEmpty()) { + inducement.forEach(assignment -> + inducementMapping().insert(assignment, row, jdbcSession)); + } } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QArchetypeMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QArchetypeMapping.java index f867f70cbb4..55788f874b6 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QArchetypeMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QArchetypeMapping.java @@ -6,7 +6,6 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.role; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.ArchetypeType; /** @@ -29,13 +28,6 @@ protected QArchetype newAliasInstance(String alias) { return new QArchetype(alias); } - @Override - public AbstractRoleSqlTransformer - createTransformer(SqlTransformerSupport transformerSupport) { - // no special class needed, no additional columns - return new AbstractRoleSqlTransformer<>(transformerSupport, this); - } - @Override public MArchetype newRowObject() { return new MArchetype(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QRoleMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QRoleMapping.java index c7ca6f41ee2..bf33d135430 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QRoleMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QRoleMapping.java @@ -8,7 +8,9 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType.F_ROLE_TYPE; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; /** @@ -34,12 +36,17 @@ protected QRole newAliasInstance(String alias) { } @Override - public RoleSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new RoleSqlTransformer(transformerSupport, this); + public MRole newRowObject() { + return new MRole(); } @Override - public MRole newRowObject() { - return new MRole(); + public @NotNull MRole toRowObjectWithoutFullObject( + RoleType schemaObject, JdbcSession jdbcSession) { + MRole row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); + + row.roleType = schemaObject.getRoleType(); + + return row; } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QServiceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QServiceMapping.java index 4b8d185fa16..3f0c2920588 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QServiceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QServiceMapping.java @@ -8,7 +8,9 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.ServiceType.F_DISPLAY_ORDER; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.ServiceType; /** @@ -34,12 +36,17 @@ protected QService newAliasInstance(String alias) { } @Override - public ServiceSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return new ServiceSqlTransformer(transformerSupport, this); + public MService newRowObject() { + return new MService(); } @Override - public MService newRowObject() { - return new MService(); + public @NotNull MService toRowObjectWithoutFullObject( + ServiceType schemaObject, JdbcSession jdbcSession) { + MService row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); + + row.displayOrder = schemaObject.getDisplayOrder(); + + return row; } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/RoleSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/RoleSqlTransformer.java deleted file mode 100644 index 60dcbf2db88..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/RoleSqlTransformer.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.role; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; - -public class RoleSqlTransformer - extends AbstractRoleSqlTransformer { - - public RoleSqlTransformer( - SqlTransformerSupport transformerSupport, QRoleMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MRole toRowObjectWithoutFullObject( - RoleType schemaObject, JdbcSession jdbcSession) { - MRole row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); - - row.roleType = schemaObject.getRoleType(); - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/ServiceSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/ServiceSqlTransformer.java deleted file mode 100644 index 5885dfe1c69..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/ServiceSqlTransformer.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.role; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ServiceType; - -public class ServiceSqlTransformer - extends AbstractRoleSqlTransformer { - - public ServiceSqlTransformer( - SqlTransformerSupport transformerSupport, QServiceMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MService toRowObjectWithoutFullObject( - ServiceType schemaObject, JdbcSession jdbcSession) { - MService row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession); - - row.displayOrder = schemaObject.getDisplayOrder(); - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java index 7ff572cc48b..7fe2bb99a2a 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java @@ -8,8 +8,12 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType.*; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; /** @@ -51,13 +55,40 @@ protected QShadow newAliasInstance(String alias) { } @Override - public ShadowSqlTransformer createTransformer( + public QShadowMapping createTransformer( SqlTransformerSupport transformerSupport) { - return new ShadowSqlTransformer(transformerSupport, this); + return this; } @Override public MShadow newRowObject() { return new MShadow(); } + + @Override + public @NotNull MShadow toRowObjectWithoutFullObject( + ShadowType shadow, JdbcSession jdbcSession) { + MShadow row = super.toRowObjectWithoutFullObject(shadow, jdbcSession); + + row.objectClassId = processCacheableUri(shadow.getObjectClass()); + setReference(shadow.getResourceRef(), + o -> row.resourceRefTargetOid = o, + t -> row.resourceRefTargetType = t, + r -> row.resourceRefRelationId = r); + row.intent = shadow.getIntent(); + row.kind = shadow.getKind(); +// row.attemptNumber = shadow.att; TODO not set in RShadow, probably just with deltas? Where does it come from? + row.dead = shadow.isDead(); + row.exist = shadow.isExists(); + row.fullSynchronizationTimestamp = + MiscUtil.asInstant(shadow.getFullSynchronizationTimestamp()); + row.pendingOperationCount = shadow.getPendingOperation().size(); + row.primaryIdentifierValue = shadow.getPrimaryIdentifierValue(); + row.synchronizationSituation = shadow.getSynchronizationSituation(); + row.synchronizationTimestamp = MiscUtil.asInstant(shadow.getSynchronizationTimestamp()); + + // TODO extension attributes + // copyExtensionOrAttributesFromJAXB(jaxb.getAttributes().asPrismContainerValue(), repo, repositoryContext, RObjectExtensionType.ATTRIBUTES, generatorResult); + return row; + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/ShadowSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/ShadowSqlTransformer.java deleted file mode 100644 index 1e229b4dae9..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/ShadowSqlTransformer.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.shadow; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; - -public class ShadowSqlTransformer - extends ObjectSqlTransformer { - - public ShadowSqlTransformer( - SqlTransformerSupport transformerSupport, QShadowMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MShadow toRowObjectWithoutFullObject( - ShadowType shadow, JdbcSession jdbcSession) { - MShadow row = super.toRowObjectWithoutFullObject(shadow, jdbcSession); - - row.objectClassId = processCacheableUri(shadow.getObjectClass()); - setReference(shadow.getResourceRef(), - o -> row.resourceRefTargetOid = o, - t -> row.resourceRefTargetType = t, - r -> row.resourceRefRelationId = r); - row.intent = shadow.getIntent(); - row.kind = shadow.getKind(); -// row.attemptNumber = shadow.att; TODO not set in RShadow, probably just with deltas? Where does it come from? - row.dead = shadow.isDead(); - row.exist = shadow.isExists(); - row.fullSynchronizationTimestamp = - MiscUtil.asInstant(shadow.getFullSynchronizationTimestamp()); - row.pendingOperationCount = shadow.getPendingOperation().size(); - row.primaryIdentifierValue = shadow.getPrimaryIdentifierValue(); - row.synchronizationSituation = shadow.getSynchronizationSituation(); - row.synchronizationTimestamp = MiscUtil.asInstant(shadow.getSynchronizationTimestamp()); - - // TODO extension attributes - // copyExtensionOrAttributesFromJAXB(jaxb.getAttributes().asPrismContainerValue(), repo, repositoryContext, RObjectExtensionType.ATTRIBUTES, generatorResult); - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSecurityPolicyMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSecurityPolicyMapping.java index 001f458c3b7..7cfeff53eb6 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSecurityPolicyMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSecurityPolicyMapping.java @@ -7,9 +7,7 @@ package com.evolveum.midpoint.repo.sqale.qmodel.system; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityPolicyType; /** @@ -32,13 +30,6 @@ protected QSecurityPolicy newAliasInstance(String alias) { return new QSecurityPolicy(alias); } - @Override - public ObjectSqlTransformer - createTransformer(SqlTransformerSupport transformerSupport) { - // no special class needed, no additional columns - return new ObjectSqlTransformer<>(transformerSupport, this); - } - @Override public MObject newRowObject() { return new MObject(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSystemConfigurationMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSystemConfigurationMapping.java index b6f5b30e143..1ebaa23eb9a 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSystemConfigurationMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSystemConfigurationMapping.java @@ -7,9 +7,7 @@ package com.evolveum.midpoint.repo.sqale.qmodel.system; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; /** @@ -32,13 +30,6 @@ protected QSystemConfiguration newAliasInstance(String alias) { return new QSystemConfiguration(alias); } - @Override - public ObjectSqlTransformer - createTransformer(SqlTransformerSupport transformerSupport) { - // no special class needed, no additional columns - return new ObjectSqlTransformer<>(transformerSupport, this); - } - @Override public MObject newRowObject() { return new MObject(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QValuePolicyMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QValuePolicyMapping.java index 3b4d87a0277..0fda2aeb90e 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QValuePolicyMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QValuePolicyMapping.java @@ -7,9 +7,7 @@ package com.evolveum.midpoint.repo.sqale.qmodel.system; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.ValuePolicyType; /** @@ -32,13 +30,6 @@ protected QValuePolicy newAliasInstance(String alias) { return new QValuePolicy(alias); } - @Override - public ObjectSqlTransformer - createTransformer(SqlTransformerSupport transformerSupport) { - // no special class needed, no additional columns - return new ObjectSqlTransformer<>(transformerSupport, this); - } - @Override public MObject newRowObject() { return new MObject(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java index 54d94df64d6..5397685ce17 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java @@ -6,8 +6,12 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.task; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; +import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; /** @@ -59,13 +63,46 @@ protected QTask newAliasInstance(String alias) { } @Override - public TaskSqlTransformer createTransformer( + public QTaskMapping createTransformer( SqlTransformerSupport transformerSupport) { - return new TaskSqlTransformer(transformerSupport, this); + return this; } @Override public MTask newRowObject() { return new MTask(); } + + @Override + public @NotNull MTask toRowObjectWithoutFullObject( + TaskType task, JdbcSession jdbcSession) { + MTask row = super.toRowObjectWithoutFullObject(task, jdbcSession); + + row.taskIdentifier = task.getTaskIdentifier(); + row.binding = task.getBinding(); + row.category = task.getCategory(); + row.completionTimestamp = MiscUtil.asInstant(task.getCompletionTimestamp()); + row.executionStatus = task.getExecutionStatus(); +// row.fullResult = TODO + row.handlerUriId = processCacheableUri(task.getHandlerUri()); + row.lastRunStartTimestamp = MiscUtil.asInstant(task.getLastRunStartTimestamp()); + row.lastRunFinishTimestamp = MiscUtil.asInstant(task.getLastRunFinishTimestamp()); + row.node = task.getNode(); + setReference(task.getObjectRef(), + o -> row.objectRefTargetOid = o, + t -> row.objectRefTargetType = t, + r -> row.objectRefRelationId = r); + setReference(task.getOwnerRef(), + o -> row.ownerRefTargetOid = o, + t -> row.ownerRefTargetType = t, + r -> row.ownerRefRelationId = r); + row.parent = task.getParent(); + row.recurrence = task.getRecurrence(); + row.resultStatus = task.getResultStatus(); + row.threadStopAction = task.getThreadStopAction(); + row.waitingReason = task.getWaitingReason(); + row.dependentTaskIdentifiers = task.getDependent().toArray(String[]::new); + + return row; + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/TaskSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/TaskSqlTransformer.java deleted file mode 100644 index 9058d52ddde..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/TaskSqlTransformer.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel.task; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; - -public class TaskSqlTransformer extends ObjectSqlTransformer { - - public TaskSqlTransformer(SqlTransformerSupport transformerSupport, QTaskMapping mapping) { - super(transformerSupport, mapping); - } - - @Override - public @NotNull MTask toRowObjectWithoutFullObject( - TaskType task, JdbcSession jdbcSession) { - MTask row = super.toRowObjectWithoutFullObject(task, jdbcSession); - - row.taskIdentifier = task.getTaskIdentifier(); - row.binding = task.getBinding(); - row.category = task.getCategory(); - row.completionTimestamp = MiscUtil.asInstant(task.getCompletionTimestamp()); - row.executionStatus = task.getExecutionStatus(); -// row.fullResult = TODO - row.handlerUriId = processCacheableUri(task.getHandlerUri()); - row.lastRunStartTimestamp = MiscUtil.asInstant(task.getLastRunStartTimestamp()); - row.lastRunFinishTimestamp = MiscUtil.asInstant(task.getLastRunFinishTimestamp()); - row.node = task.getNode(); - setReference(task.getObjectRef(), - o -> row.objectRefTargetOid = o, - t -> row.objectRefTargetType = t, - r -> row.objectRefRelationId = r); - setReference(task.getOwnerRef(), - o -> row.ownerRefTargetOid = o, - t -> row.ownerRefTargetType = t, - r -> row.ownerRefRelationId = r); - row.parent = task.getParent(); - row.recurrence = task.getRecurrence(); - row.resultStatus = task.getResultStatus(); - row.threadStopAction = task.getThreadStopAction(); - row.waitingReason = task.getWaitingReason(); - row.dependentTaskIdentifiers = task.getDependent().toArray(String[]::new); - - return row; - } -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java index e5bf09f6a98..d30e5677846 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java @@ -22,8 +22,8 @@ import com.evolveum.midpoint.repo.sqale.SqaleUtils; import com.evolveum.midpoint.repo.sqale.delta.DelegatingItemDeltaProcessor; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObject; +import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.RepositoryException; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; @@ -42,7 +42,7 @@ public class RootUpdateContext, R ext extends SqaleUpdateContext { private final S object; - protected final QueryTableMapping mapping; + protected final QObjectMapping mapping; private final Q rootPath; private final SQLUpdateClause update; private final int objectVersion; @@ -148,10 +148,7 @@ protected void finishExecutionOwn() throws SchemaException, RepositoryException update.set(rootPath.version, newVersion); update.set(rootPath.containerIdSeq, cidGenerator.lastUsedId() + 1); - - ObjectSqlTransformer transformer = - (ObjectSqlTransformer) mapping.createTransformer(transformerSupport); - update.set(rootPath.fullObject, transformer.createFullObject(object)); + update.set(rootPath.fullObject, mapping.createFullObject(object)); long rows = update.execute(); if (rows != 1) { diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java index 12e5515ddc3..fd2422fe226 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java @@ -18,7 +18,6 @@ import com.evolveum.midpoint.repo.sqale.delta.ItemDeltaValueProcessor; import com.evolveum.midpoint.repo.sqale.delta.item.UriItemDeltaProcessor; import com.evolveum.midpoint.repo.sqale.qmodel.QOwnedByMapping; -import com.evolveum.midpoint.repo.sqale.qmodel.TransformerForOwnedBy; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.RepositoryException; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryModelMapping; @@ -127,9 +126,7 @@ public R row() { @SuppressWarnings("UnusedReturnValue") public TR insertOwnedRow(QOwnedByMapping mapping, TS schemaObject) { - TransformerForOwnedBy transformer = - mapping.createTransformer(transformerSupport()); - return transformer.insert(schemaObject, row, jdbcSession); + return mapping.insert(schemaObject, row, jdbcSession); } public SqaleUpdateContext getSubcontext(ItemPath itemPath) { diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerSupport.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerSupport.java index b007a0575de..9710f9c2643 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerSupport.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerSupport.java @@ -22,12 +22,19 @@ */ public class SqlTransformerSupport { + private static SqlTransformerSupport instance; + protected final SchemaService schemaService; protected final SqlRepoContext sqlRepoContext; public SqlTransformerSupport(SchemaService schemaService, SqlRepoContext sqlRepoContext) { this.schemaService = schemaService; this.sqlRepoContext = sqlRepoContext; + instance = this; + } + + public static SqlTransformerSupport getInstance() { + return instance; } public Class qNameToSchemaClass(QName qName) { diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java index e6da4e258af..a702c535f98 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java @@ -260,6 +260,7 @@ public synchronized Q defaultAlias() { * or cache (I don't like the sound of that). On the other hand they are really lightweight * and short lived helpers too, so it shouldn't be a real GC problem. */ + @Deprecated public SqlTransformer createTransformer( SqlTransformerSupport transformerSupport) { throw new UnsupportedOperationException("Bean transformer not supported for " + queryType()); From a52a7f84dcb109f62a6f19d8246c114bc19bc435 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Fri, 30 Apr 2021 14:32:44 +0200 Subject: [PATCH 06/33] SqlTransformer completely gone, all is in mapping now, audit included --- .../repo/sqale/SqaleQueryContext.java | 6 - .../repo/sqale/SqaleRepositoryService.java | 6 +- .../sqale/qmodel/QObjectTemplateMapping.java | 7 - .../repo/sqale/qmodel/SqaleTableMapping.java | 16 +- .../qmodel/common/QContainerMapping.java | 5 - .../sqale/qmodel/object/QObjectMapping.java | 6 - .../sqale/qmodel/ref/QReferenceMapping.java | 6 - .../qmodel/report/QReportDataMapping.java | 6 - .../sqale/qmodel/report/QReportMapping.java | 6 - .../qmodel/resource/QResourceMapping.java | 6 - .../sqale/qmodel/shadow/QShadowMapping.java | 7 - .../repo/sqale/qmodel/task/QTaskMapping.java | 7 - .../repo/sql/SqlAuditServiceImpl.java | 4 +- .../repo/sql/audit/AuditSqlQueryContext.java | 6 - .../sql/audit/beans/MAuditEventRecord.java | 15 +- .../mapping/AuditDeltaSqlTransformer.java | 75 ----- .../AuditEventRecordSqlTransformer.java | 263 ------------------ .../AuditTableMapping.java} | 32 +-- .../sql/audit/mapping/QAuditDeltaMapping.java | 53 +++- .../mapping/QAuditEventRecordMapping.java | 233 +++++++++++++++- .../sql/audit/mapping/QAuditItemMapping.java | 3 +- .../mapping/QAuditPropertyValueMapping.java | 3 +- .../audit/mapping/QAuditRefValueMapping.java | 3 +- .../audit/mapping/QAuditResourceMapping.java | 3 +- .../repo/sqlbase/SqlQueryContext.java | 25 +- .../sqlbase/mapping/QueryModelMapping.java | 4 + .../sqlbase/mapping/QueryTableMapping.java | 49 ++-- .../mapping/SqlTransformationException.java | 18 ++ .../repo/sqlbase/mapping/SqlTransformer.java | 65 ----- 29 files changed, 369 insertions(+), 569 deletions(-) delete mode 100644 repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditDeltaSqlTransformer.java delete mode 100644 repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditEventRecordSqlTransformer.java rename repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/{AuditSqlTransformerBase.java => mapping/AuditTableMapping.java} (80%) create mode 100644 repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformationException.java delete mode 100644 repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformer.java diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java index cffe745ec8d..07f9e0ff2dd 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java @@ -18,7 +18,6 @@ import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.filtering.FilterProcessor; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; -import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; public class SqaleQueryContext, R> @@ -48,11 +47,6 @@ private SqaleQueryContext( super(entityPath, mapping, sqlRepoContext, transformerSupport, query); } - @Override - protected SqlTransformer createTransformer() { - return entityPathMapping.createTransformer(transformerSupport); - } - @Override public FilterProcessor createInOidFilter(SqlQueryContext context) { return new InOidFilterProcessor(context); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java index 47dfa1f6840..42899eb84ce 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java @@ -184,8 +184,7 @@ private S readByOid( throw new ObjectNotFoundException(schemaType, oid.toString()); } - return rootMapping.createTransformer(transformerSupport) - .toSchemaObject(result, root, options); + return rootMapping.toSchemaObject(result, root, options); } @Override @@ -416,8 +415,7 @@ RootUpdateContext prepareUpdateContext( throw new ObjectNotFoundException(schemaType, oid.toString()); } - S object = rootMapping.createTransformer(transformerSupport) - .toSchemaObject(result, root, Collections.emptyList()); + S object = rootMapping.toSchemaObject(result, root, Collections.emptyList()); R rootRow = rootMapping.newRowObject(); rootRow.oid = oid; diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java index c97b359d9e0..f492dfda53f 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java @@ -14,7 +14,6 @@ import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType; /** @@ -39,12 +38,6 @@ protected QObjectTemplate newAliasInstance(String alias) { return new QObjectTemplate(alias); } - @Override - public QObjectTemplateMapping createTransformer( - SqlTransformerSupport transformerSupport) { - return this; - } - @Override public MObject newRowObject() { return new MObject(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java index 0b2d5986a9c..af453912c57 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java @@ -18,8 +18,6 @@ import com.querydsl.sql.ColumnMetadata; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport; import com.evolveum.midpoint.repo.sqale.delta.item.*; @@ -37,7 +35,6 @@ import com.evolveum.midpoint.repo.sqlbase.filtering.item.SimpleItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.TimestampItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; -import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.repo.sqlbase.querydsl.UuidPath; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -59,9 +56,7 @@ */ public abstract class SqaleTableMapping, R> extends QueryTableMapping - implements SqaleMappingMixin, SqlTransformer { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); + implements SqaleMappingMixin { protected SqaleTableMapping( @NotNull String tableName, @@ -105,7 +100,8 @@ public SqaleItemSqlMapper integerMapper( * @param mapped schema type, see javadoc in {@link QueryTableMapping} */ @Override - protected SqaleItemSqlMapper booleanMapper(Function rootToQueryItem) { + protected SqaleItemSqlMapper booleanMapper( + Function rootToQueryItem) { return new SqaleItemSqlMapper<>( ctx -> new SimpleItemFilterProcessor<>(ctx, rootToQueryItem), ctx -> new SimpleItemDeltaProcessor<>(ctx, rootToQueryItem), @@ -242,7 +238,8 @@ protected ObjectReferenceType objectReferenceType( return new ObjectReferenceType() .oid(oid) - .type(SqaleTransformerSupport.getInstance().schemaClassToQName(repoObjectType.getSchemaType())) + .type(SqaleTransformerSupport.getInstance() + .schemaClassToQName(repoObjectType.getSchemaType())) .description(targetName) .targetName(targetName); } @@ -287,7 +284,8 @@ protected Integer processCacheableUri(String uri) { /** Returns ID for URI creating new cache row in DB as needed. */ protected Integer processCacheableUri(QName qName) { return qName != null - ? SqaleTransformerSupport.getInstance().processCacheableUri(QNameUtil.qNameToUri(qName)) + ? SqaleTransformerSupport.getInstance() + .processCacheableUri(QNameUtil.qNameToUri(qName)) : null; } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java index 58fbe74beb4..0bb4cb72005 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java @@ -12,7 +12,6 @@ import com.evolveum.midpoint.repo.sqale.qmodel.QOwnedByMapping; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; /** * Mapping between {@link QContainer} and {@link Containerable}. @@ -55,10 +54,6 @@ public R newRowObject(OR ownerRow) { "Container bean creation for owner row called on abstract container mapping"); } - public QContainerMapping createTransformer(SqlTransformerSupport transformerSupport) { - return this; - } - @Override public R newRowObject() { //noinspection unchecked diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java index 8dd59af9d46..e8d43b9abb4 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java @@ -30,7 +30,6 @@ import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -182,11 +181,6 @@ protected Q newAliasInstance(String alias) { return (Q) new QObject<>(MObject.class, alias); } - @Override - public SqlTransformer createTransformer(SqlTransformerSupport transformerSupport) { - return this; - } - @Override public R newRowObject() { //noinspection unchecked diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java index 37c5138901e..0ad554ca371 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java @@ -15,7 +15,6 @@ import com.evolveum.midpoint.repo.sqale.qmodel.QOwnedByMapping; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; @@ -61,11 +60,6 @@ protected Q newAliasInstance(String alias) { return (Q) new QReference<>(MReference.class, alias); } - public QReferenceMapping createTransformer( - SqlTransformerSupport transformerSupport) { - return this; - } - /** Defines a contract for creating the reference for the provided owner row. */ public R newRowObject(OR ownerRow) { throw new UnsupportedOperationException( diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java index 04dd1e88576..68f32bf115f 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java @@ -12,7 +12,6 @@ import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportDataType; /** @@ -40,11 +39,6 @@ protected QReportData newAliasInstance(String alias) { return new QReportData(alias); } - @Override - public QReportDataMapping createTransformer(SqlTransformerSupport transformerSupport) { - return this; - } - @Override public MReportData newRowObject() { return new MReportData(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java index 74ef986fdbd..c07dd68b7a7 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java @@ -10,7 +10,6 @@ import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.JasperReportEngineConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportType; @@ -40,11 +39,6 @@ protected QReport newAliasInstance(String alias) { return new QReport(alias); } - @Override - public QReportMapping createTransformer(SqlTransformerSupport transformerSupport) { - return this; - } - @Override public MReport newRowObject() { return new MReport(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java index b5b72b7229c..9f8964fab34 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java @@ -13,7 +13,6 @@ import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationalStateType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceBusinessConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; @@ -51,11 +50,6 @@ protected QResource newAliasInstance(String alias) { return new QResource(alias); } - @Override - public QResourceMapping createTransformer(SqlTransformerSupport transformerSupport) { - return this; - } - @Override public MResource newRowObject() { return new MResource(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java index 7fe2bb99a2a..c68a2a35293 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java @@ -12,7 +12,6 @@ import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; @@ -54,12 +53,6 @@ protected QShadow newAliasInstance(String alias) { return new QShadow(alias); } - @Override - public QShadowMapping createTransformer( - SqlTransformerSupport transformerSupport) { - return this; - } - @Override public MShadow newRowObject() { return new MShadow(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java index 5397685ce17..16bf53d48e1 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java @@ -10,7 +10,6 @@ import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; @@ -62,12 +61,6 @@ protected QTask newAliasInstance(String alias) { return new QTask(alias); } - @Override - public QTaskMapping createTransformer( - SqlTransformerSupport transformerSupport) { - return this; - } - @Override public MTask newRowObject() { return new MTask(); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java index 9c8984d9307..2629cbdac40 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java @@ -179,9 +179,7 @@ private Long insertAuditEventRecord( JdbcSession jdbcSession, AuditEventRecord record) { QAuditEventRecordMapping aerMapping = QAuditEventRecordMapping.INSTANCE; QAuditEventRecord aer = aerMapping.defaultAlias(); - MAuditEventRecord aerBean = aerMapping - .createTransformer(transformerSupport) - .from(record); + MAuditEventRecord aerBean = aerMapping.from(record); SQLInsertClause insert = jdbcSession.newInsert(aer).populate(aerBean); Map customColumns = aerMapping.getExtensionColumns(); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java index 81068d051ed..7656a79d106 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java @@ -12,7 +12,6 @@ import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; -import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; /** @@ -47,11 +46,6 @@ private AuditSqlQueryContext( super(entityPath, mapping, sqlRepoContext, transformerSupport, query); } - @Override - protected SqlTransformer createTransformer() { - return entityPathMapping.createTransformer(transformerSupport); - } - @Override protected , TR> SqlQueryContext deriveNew(TQ newPath, QueryTableMapping newMapping) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/beans/MAuditEventRecord.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/beans/MAuditEventRecord.java index 40560e8350f..0466a587903 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/beans/MAuditEventRecord.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/beans/MAuditEventRecord.java @@ -9,22 +9,9 @@ import java.time.Instant; import java.util.*; -import com.evolveum.midpoint.repo.sql.audit.mapping.AuditEventRecordSqlTransformer; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditEventRecord; -/** - * Querydsl "row bean" type related to {@link QAuditEventRecord}. - *

- * Design notes (TODO reconsider in 2021 and possibly remove if settled): - * This bean is super stupid for now. - * It can have getters/setters and handle more transformations and trimming (in setters), - * but at this moment this is left to transformation code like in {@link AuditEventRecordSqlTransformer}. - * I'd not suggest to move complete transformations here, but small conversions and trimming could - * be here - but how to do it reasonably without converting all fields to private + set/get methods? - * Can additional setter indicate conversion/trimming duties? - * What about methods like {@code SqlTransformerBase.trim()}, should we create common supertype - * to make it easy to call them in M-beans? Or should we use RUtil? - */ +/** Querydsl "row bean" type related to {@link QAuditEventRecord}. */ @SuppressWarnings("unused") public class MAuditEventRecord { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditDeltaSqlTransformer.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditDeltaSqlTransformer.java deleted file mode 100644 index 7a820f582ba..00000000000 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditDeltaSqlTransformer.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sql.audit.mapping; - -import com.querydsl.sql.SQLServerTemplates; -import com.querydsl.sql.SQLTemplates; - -import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.repo.sql.audit.AuditSqlTransformerBase; -import com.evolveum.midpoint.repo.sql.audit.beans.MAuditDelta; -import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditDelta; -import com.evolveum.midpoint.repo.sql.util.RUtil; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectDeltaOperationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; -import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; -import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; - -/** - * Transformer between repo and Prism world for audit event. - */ -public class AuditDeltaSqlTransformer - extends AuditSqlTransformerBase { - - private static final Trace LOGGER = TraceManager.getTrace(AuditDeltaSqlTransformer.class); - - public AuditDeltaSqlTransformer( - SqlTransformerSupport transformerSupport, QAuditDeltaMapping mapping) { - super(transformerSupport, mapping); - } - - public ObjectDeltaOperationType toSchemaObject(MAuditDelta row) { - ObjectDeltaOperationType odo = new ObjectDeltaOperationType(); - SQLTemplates querydslTemplates = transformerSupport.sqlRepoContext().getQuerydslTemplates(); - - boolean usingSqlServer = querydslTemplates instanceof SQLServerTemplates; - odo.setObjectDelta(parseBytes(row.delta, usingSqlServer, ObjectDeltaType.class)); - odo.setExecutionResult(parseBytes(row.fullResult, usingSqlServer, OperationResultType.class)); - - if (row.objectNameOrig != null || row.objectNameNorm != null) { - odo.setObjectName(new PolyStringType( - new PolyString(row.objectNameOrig, row.objectNameNorm))); - } - odo.setResourceOid(row.resourceOid); - if (row.resourceNameOrig != null || row.resourceNameNorm != null) { - odo.setResourceName(new PolyStringType( - new PolyString(row.resourceNameOrig, row.resourceNameNorm))); - } - - return odo; - } - - private T parseBytes(byte[] bytes, boolean usingSqlServer, Class clazz) { - if (bytes == null) { - return null; - } - - try { - return transformerSupport - .createStringParser(RUtil.getSerializedFormFromBytes(bytes, usingSqlServer)) - .compat() - .parseRealValue(clazz); - } catch (SchemaException e) { - LOGGER.error("Cannot parse {}: {}", clazz.getSimpleName(), e.getMessage(), e); - return null; - } - } -} diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditEventRecordSqlTransformer.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditEventRecordSqlTransformer.java deleted file mode 100644 index dbca9ac7ccd..00000000000 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditEventRecordSqlTransformer.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sql.audit.mapping; - -import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditEventRecord.MESSAGE; - -import java.util.List; -import java.util.Map; -import javax.xml.namespace.QName; - -import com.querydsl.core.Tuple; - -import com.evolveum.midpoint.audit.api.AuditEventRecord; -import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.repo.sql.audit.AuditSqlTransformerBase; -import com.evolveum.midpoint.repo.sql.audit.beans.MAuditDelta; -import com.evolveum.midpoint.repo.sql.audit.beans.MAuditEventRecord; -import com.evolveum.midpoint.repo.sql.audit.beans.MAuditRefValue; -import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditDelta; -import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditEventRecord; -import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventStage; -import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventType; -import com.evolveum.midpoint.repo.sql.data.common.enums.ROperationResultStatus; -import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.xml.ns._public.common.audit_3.*; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectDeltaOperationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; -import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; -import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; - -/** - * Transformation of audit event records between repo and Prism world. - */ -public class AuditEventRecordSqlTransformer - extends AuditSqlTransformerBase { - - public AuditEventRecordSqlTransformer( - SqlTransformerSupport transformerSupport, QAuditEventRecordMapping mapping) { - super(transformerSupport, mapping); - } - - public AuditEventRecordType toSchemaObject(MAuditEventRecord row) throws SchemaException { - AuditEventRecordType record = mapSimpleAttributes(row); - mapDeltas(record, row.deltas); - mapChangedItems(record, row.changedItemPaths); - mapRefValues(record, row.refValues); - mapProperties(record, row.properties); - mapResourceOids(record, row.resourceOids); - return record; - } - - private AuditEventRecordType mapSimpleAttributes(MAuditEventRecord row) { - // prismContext in constructor ensures complex type definition - return new AuditEventRecordType(transformerSupport.prismContext()) - .repoId(row.id) - .channel(row.channel) - .eventIdentifier(row.eventIdentifier) - .eventStage(auditEventStageTypeFromRepo(row.eventStage)) - .eventType(auditEventTypeTypeFromRepo(row.eventType)) - .hostIdentifier(row.hostIdentifier) - .message(row.message) - .nodeIdentifier(row.nodeIdentifier) - .outcome(operationResultStatusTypeFromRepo(row.outcome)) - .parameter(row.parameter) - .remoteHostAddress(row.remoteHostAddress) - .requestIdentifier(row.requestIdentifier) - .result(row.result) - .sessionIdentifier(row.sessionIdentifier) - .taskIdentifier(row.taskIdentifier) - .taskOID(row.taskOid) - .timestamp(MiscUtil.asXMLGregorianCalendar(row.timestamp)) - .initiatorRef(objectReferenceType( - row.initiatorOid, - repoObjectType(row.initiatorType, RObjectType.FOCUS), - row.initiatorName)) - .attorneyRef(objectReferenceType( - row.attorneyOid, RObjectType.FOCUS, row.attorneyName)) - .targetRef(objectReferenceType( - row.targetOid, - // targetType must not be null if targetOid is not - repoObjectType(row.targetType), - row.targetName)) - .targetOwnerRef(objectReferenceType( - row.targetOwnerOid, - repoObjectType(row.targetOwnerType), - row.targetOwnerName)); - } - - private void mapDeltas(AuditEventRecordType record, List deltas) - throws SchemaException { - if (deltas == null) { - return; - } - - SqlTransformer deltaTransformer = - QAuditDeltaMapping.INSTANCE.createTransformer(transformerSupport); - for (MAuditDelta delta : deltas) { - record.delta(deltaTransformer.toSchemaObject(delta)); - } - } - - // the rest of sub-entities do not deserve the dedicated transformer classes (yet) - private void mapChangedItems(AuditEventRecordType record, List changedItemPaths) { - if (changedItemPaths == null) { - return; - } - - for (String changedItemPath : changedItemPaths) { - ItemPath itemPath = ItemPath.create(changedItemPath); - record.getChangedItem().add(new ItemPathType(itemPath)); - } - } - - private void mapRefValues( - AuditEventRecordType record, Map> refValues) { - if (refValues == null) { - return; - } - - for (Map.Entry> entry : refValues.entrySet()) { - AuditEventRecordReferenceType referenceValues = - new AuditEventRecordReferenceType().name(entry.getKey()); - for (MAuditRefValue refValue : entry.getValue()) { - AuditEventRecordReferenceValueType value = new AuditEventRecordReferenceValueType() - .oid(refValue.oid) - .type(QName.valueOf(refValue.type)); - if (refValue.targetNameOrig != null) { - value.targetName(new PolyStringType( - new PolyString(refValue.targetNameOrig, refValue.targetNameNorm))); - } - referenceValues.value(value); - } - record.reference(referenceValues); - } - } - - private void mapProperties(AuditEventRecordType record, Map> properties) { - if (properties == null) { - return; - } - - for (Map.Entry> entry : properties.entrySet()) { - AuditEventRecordPropertyType propType = - new AuditEventRecordPropertyType().name(entry.getKey()); - propType.getValue().addAll(entry.getValue()); - record.property(propType); - } - } - - private void mapResourceOids( - AuditEventRecordType record, List resourceOids) { - if (resourceOids == null) { - return; - } - - record.getResourceOid().addAll(resourceOids); - } - - private AuditEventTypeType auditEventTypeTypeFromRepo(Integer ordinal) { - RAuditEventType eventType = MiscUtil.enumFromOrdinal(RAuditEventType.class, ordinal); - return eventType != null - ? eventType.getSchemaValue() - : null; - } - - private AuditEventStageType auditEventStageTypeFromRepo(Integer ordinal) { - RAuditEventStage stage = MiscUtil.enumFromOrdinal(RAuditEventStage.class, ordinal); - return stage != null - ? stage.getSchemaValue() - : null; - } - - private OperationResultStatusType operationResultStatusTypeFromRepo(Integer ordinal) { - ROperationResultStatus status = - MiscUtil.enumFromOrdinal(ROperationResultStatus.class, ordinal); - return status != null - ? status.getSchemaValue() - : null; - } - - /** - * Transforms {@link AuditEventRecord} to {@link MAuditEventRecord} without any subentities. - *

- * Design notes: Arguably, this code could be in {@link MAuditEventRecord}. - * Also the - */ - public MAuditEventRecord from(AuditEventRecord record) { - MAuditEventRecord bean = new MAuditEventRecord(); - bean.id = record.getRepoId(); // this better be null if we want to insert - bean.eventIdentifier = record.getEventIdentifier(); - bean.timestamp = MiscUtil.asInstant(record.getTimestamp()); - bean.channel = record.getChannel(); - bean.eventStage = MiscUtil.enumOrdinal(RAuditEventStage.from(record.getEventStage())); - bean.eventType = MiscUtil.enumOrdinal(RAuditEventType.from(record.getEventType())); - bean.hostIdentifier = record.getHostIdentifier(); - - PrismReferenceValue attorney = record.getAttorneyRef(); - if (attorney != null) { - bean.attorneyName = attorney.getDescription(); - bean.attorneyOid = attorney.getOid(); - } - - PrismReferenceValue initiator = record.getInitiatorRef(); - if (initiator != null) { - bean.initiatorName = initiator.getDescription(); - bean.initiatorOid = initiator.getOid(); - bean.initiatorType = targetTypeToRepoOrdinal(initiator); - } - - bean.message = trim(record.getMessage(), MESSAGE); - bean.nodeIdentifier = record.getNodeIdentifier(); - bean.outcome = MiscUtil.enumOrdinal(ROperationResultStatus.from(record.getOutcome())); - bean.parameter = record.getParameter(); - bean.remoteHostAddress = record.getRemoteHostAddress(); - bean.requestIdentifier = record.getRequestIdentifier(); - bean.result = record.getResult(); - bean.sessionIdentifier = record.getSessionIdentifier(); - - PrismReferenceValue target = record.getTargetRef(); - if (target != null) { - bean.targetName = target.getDescription(); - bean.targetOid = target.getOid(); - bean.targetType = targetTypeToRepoOrdinal(target); - } - PrismReferenceValue targetOwner = record.getTargetOwnerRef(); - if (targetOwner != null) { - bean.targetOwnerName = targetOwner.getDescription(); - bean.targetOwnerOid = targetOwner.getOid(); - bean.targetOwnerType = targetTypeToRepoOrdinal(targetOwner); - } - bean.taskIdentifier = record.getTaskIdentifier(); - bean.taskOid = record.getTaskOid(); - return bean; - } - - private Integer targetTypeToRepoOrdinal(PrismReferenceValue targetOwner) { - //noinspection rawtypes - Class objectClass = transformerSupport.qNameToSchemaClass(targetOwner.getTargetType()); - //noinspection unchecked - return MiscUtil.enumOrdinal(RObjectType.getByJaxbType(objectClass)); - } - - @Override - protected void processExtensionColumns( - AuditEventRecordType schemaObject, Tuple tuple, QAuditEventRecord entityPath) { - for (String propertyName : mapping.getExtensionColumns().keySet()) { - Object customColumnValue = tuple.get(entityPath.getPath(propertyName)); - schemaObject.getCustomColumnProperty().add( - new AuditEventRecordCustomColumnPropertyType() - .name(propertyName).value((String) customColumnValue)); - } - } -} diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlTransformerBase.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java similarity index 80% rename from repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlTransformerBase.java rename to repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java index 1deeef56da9..5ce8221f693 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlTransformerBase.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java @@ -4,7 +4,7 @@ * This work is dual-licensed under the Apache License 2.0 * and European Union Public License. See LICENSE file for details. */ -package com.evolveum.midpoint.repo.sql.audit; +package com.evolveum.midpoint.repo.sql.audit.mapping; import java.util.Collection; @@ -16,31 +16,25 @@ import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; -import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -/** Transformation functionality common for audit. */ -public abstract class AuditSqlTransformerBase, R> - implements SqlTransformer { - - protected final SqlTransformerSupport transformerSupport; - protected final QueryTableMapping mapping; +/** + * Common functionality for audit table mapping, mostly around row/object transformation. + */ +public abstract class AuditTableMapping, R> + extends QueryTableMapping { - protected AuditSqlTransformerBase( - SqlTransformerSupport transformerSupport, QueryTableMapping mapping) { - this.transformerSupport = transformerSupport; - this.mapping = mapping; + protected AuditTableMapping(@NotNull String tableName, @NotNull String defaultAliasName, @NotNull Class schemaType, @NotNull Class queryType) { + super(tableName, defaultAliasName, schemaType, queryType); } @Override public S toSchemaObject( - Tuple tuple, Q entityPath, Collection> options) - throws SchemaException { + Tuple tuple, Q entityPath, Collection> options) { S schemaObject = toSchemaObject(tuple.get(entityPath)); processExtensionColumns(schemaObject, tuple, entityPath); return schemaObject; @@ -69,7 +63,8 @@ protected ObjectReferenceType objectReferenceType( return new ObjectReferenceType() .oid(oid) - .type(transformerSupport.schemaClassToQName(repoObjectType.getJaxbClass())) + .type(SqlTransformerSupport.getInstance() + .schemaClassToQName(repoObjectType.getJaxbClass())) .description(targetName) .targetName(targetName); } @@ -109,4 +104,9 @@ protected ObjectReferenceType objectReferenceType( } return MiscUtil.trimString(value, columnMetadata.getSize()); } + + @Override + public S toSchemaObject(R row) { + throw new UnsupportedOperationException("Implemented in subclasses only"); + } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java index 29664f946cd..40042910e00 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java @@ -8,18 +8,25 @@ import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditItem.TABLE_NAME; +import com.querydsl.sql.SQLServerTemplates; +import com.querydsl.sql.SQLTemplates; + +import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.repo.sql.audit.beans.MAuditDelta; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditDelta; +import com.evolveum.midpoint.repo.sql.util.RUtil; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; -import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; -import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; +import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectDeltaOperationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; +import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; +import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; /** * Mapping between {@link QAuditDelta} and {@link ObjectDeltaOperationType}. */ public class QAuditDeltaMapping - extends QueryTableMapping { + extends AuditTableMapping { public static final String DEFAULT_ALIAS_NAME = "ad"; @@ -35,9 +42,41 @@ protected QAuditDelta newAliasInstance(String alias) { return new QAuditDelta(alias); } - @Override - public SqlTransformer createTransformer( - SqlTransformerSupport transformerSupport) { - return new AuditDeltaSqlTransformer(transformerSupport, this); + public ObjectDeltaOperationType toSchemaObject(MAuditDelta row) { + ObjectDeltaOperationType odo = new ObjectDeltaOperationType(); + SQLTemplates querydslTemplates = + SqlTransformerSupport.getInstance().sqlRepoContext().getQuerydslTemplates(); + + boolean usingSqlServer = querydslTemplates instanceof SQLServerTemplates; + odo.setObjectDelta(parseBytes(row.delta, usingSqlServer, ObjectDeltaType.class)); + odo.setExecutionResult(parseBytes(row.fullResult, usingSqlServer, OperationResultType.class)); + + if (row.objectNameOrig != null || row.objectNameNorm != null) { + odo.setObjectName(new PolyStringType( + new PolyString(row.objectNameOrig, row.objectNameNorm))); + } + odo.setResourceOid(row.resourceOid); + if (row.resourceNameOrig != null || row.resourceNameNorm != null) { + odo.setResourceName(new PolyStringType( + new PolyString(row.resourceNameOrig, row.resourceNameNorm))); + } + + return odo; + } + + private T parseBytes(byte[] bytes, boolean usingSqlServer, Class clazz) { + if (bytes == null) { + return null; + } + + try { + return SqlTransformerSupport.getInstance() + .createStringParser(RUtil.getSerializedFormFromBytes(bytes, usingSqlServer)) + .compat() + .parseRealValue(clazz); + } catch (SchemaException e) { + logger.error("Cannot parse {}: {}", clazz.getSimpleName(), e.getMessage(), e); + return null; + } } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java index b764c2352a7..04c8fcf0ec4 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java @@ -6,28 +6,45 @@ */ package com.evolveum.midpoint.repo.sql.audit.mapping; +import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditEventRecord.MESSAGE; import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditEventRecord.TABLE_NAME; import static com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType.*; +import java.util.List; +import java.util.Map; +import javax.xml.namespace.QName; + +import com.querydsl.core.Tuple; + +import com.evolveum.midpoint.audit.api.AuditEventRecord; +import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.polystring.PolyString; +import com.evolveum.midpoint.repo.sql.audit.beans.MAuditDelta; import com.evolveum.midpoint.repo.sql.audit.beans.MAuditEventRecord; +import com.evolveum.midpoint.repo.sql.audit.beans.MAuditRefValue; import com.evolveum.midpoint.repo.sql.audit.querymodel.*; import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventStage; import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventType; import com.evolveum.midpoint.repo.sql.data.common.enums.ROperationResultStatus; +import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.repo.sqlbase.filtering.item.CanonicalItemPathItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.DetailTableItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.EnumOrdinalItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.SimpleItemFilterProcessor; -import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.repo.sqlbase.mapping.SqlDetailFetchMapper; -import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; +import com.evolveum.midpoint.util.MiscUtil; +import com.evolveum.midpoint.xml.ns._public.common.audit_3.*; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; +import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; +import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; /** * Mapping between {@link QAuditEventRecord} and {@link AuditEventRecordType}. */ public class QAuditEventRecordMapping - extends QueryTableMapping { + extends AuditTableMapping { public static final String DEFAULT_ALIAS_NAME = "aer"; @@ -120,9 +137,213 @@ protected QAuditEventRecord newAliasInstance(String alias) { return new QAuditEventRecord(alias); } + public AuditEventRecordType toSchemaObject(MAuditEventRecord row) { + AuditEventRecordType record = mapSimpleAttributes(row); + mapDeltas(record, row.deltas); + mapChangedItems(record, row.changedItemPaths); + mapRefValues(record, row.refValues); + mapProperties(record, row.properties); + mapResourceOids(record, row.resourceOids); + return record; + } + + private AuditEventRecordType mapSimpleAttributes(MAuditEventRecord row) { + // prismContext in constructor ensures complex type definition + return new AuditEventRecordType(SqlTransformerSupport.getInstance().prismContext()) + .repoId(row.id) + .channel(row.channel) + .eventIdentifier(row.eventIdentifier) + .eventStage(auditEventStageTypeFromRepo(row.eventStage)) + .eventType(auditEventTypeTypeFromRepo(row.eventType)) + .hostIdentifier(row.hostIdentifier) + .message(row.message) + .nodeIdentifier(row.nodeIdentifier) + .outcome(operationResultStatusTypeFromRepo(row.outcome)) + .parameter(row.parameter) + .remoteHostAddress(row.remoteHostAddress) + .requestIdentifier(row.requestIdentifier) + .result(row.result) + .sessionIdentifier(row.sessionIdentifier) + .taskIdentifier(row.taskIdentifier) + .taskOID(row.taskOid) + .timestamp(MiscUtil.asXMLGregorianCalendar(row.timestamp)) + .initiatorRef(objectReferenceType( + row.initiatorOid, + repoObjectType(row.initiatorType, RObjectType.FOCUS), + row.initiatorName)) + .attorneyRef(objectReferenceType( + row.attorneyOid, RObjectType.FOCUS, row.attorneyName)) + .targetRef(objectReferenceType( + row.targetOid, + // targetType must not be null if targetOid is not + repoObjectType(row.targetType), + row.targetName)) + .targetOwnerRef(objectReferenceType( + row.targetOwnerOid, + repoObjectType(row.targetOwnerType), + row.targetOwnerName)); + } + + private void mapDeltas(AuditEventRecordType record, List deltas) { + if (deltas == null) { + return; + } + + for (MAuditDelta delta : deltas) { + record.delta(QAuditDeltaMapping.INSTANCE.toSchemaObject(delta)); + } + } + + // the rest of sub-entities do not deserve the dedicated transformer classes (yet) + private void mapChangedItems(AuditEventRecordType record, List changedItemPaths) { + if (changedItemPaths == null) { + return; + } + + for (String changedItemPath : changedItemPaths) { + ItemPath itemPath = ItemPath.create(changedItemPath); + record.getChangedItem().add(new ItemPathType(itemPath)); + } + } + + private void mapRefValues( + AuditEventRecordType record, Map> refValues) { + if (refValues == null) { + return; + } + + for (Map.Entry> entry : refValues.entrySet()) { + AuditEventRecordReferenceType referenceValues = + new AuditEventRecordReferenceType().name(entry.getKey()); + for (MAuditRefValue refValue : entry.getValue()) { + AuditEventRecordReferenceValueType value = new AuditEventRecordReferenceValueType() + .oid(refValue.oid) + .type(QName.valueOf(refValue.type)); + if (refValue.targetNameOrig != null) { + value.targetName(new PolyStringType( + new PolyString(refValue.targetNameOrig, refValue.targetNameNorm))); + } + referenceValues.value(value); + } + record.reference(referenceValues); + } + } + + private void mapProperties(AuditEventRecordType record, Map> properties) { + if (properties == null) { + return; + } + + for (Map.Entry> entry : properties.entrySet()) { + AuditEventRecordPropertyType propType = + new AuditEventRecordPropertyType().name(entry.getKey()); + propType.getValue().addAll(entry.getValue()); + record.property(propType); + } + } + + private void mapResourceOids( + AuditEventRecordType record, List resourceOids) { + if (resourceOids == null) { + return; + } + + record.getResourceOid().addAll(resourceOids); + } + + private AuditEventTypeType auditEventTypeTypeFromRepo(Integer ordinal) { + RAuditEventType eventType = MiscUtil.enumFromOrdinal(RAuditEventType.class, ordinal); + return eventType != null + ? eventType.getSchemaValue() + : null; + } + + private AuditEventStageType auditEventStageTypeFromRepo(Integer ordinal) { + RAuditEventStage stage = MiscUtil.enumFromOrdinal(RAuditEventStage.class, ordinal); + return stage != null + ? stage.getSchemaValue() + : null; + } + + private OperationResultStatusType operationResultStatusTypeFromRepo(Integer ordinal) { + ROperationResultStatus status = + MiscUtil.enumFromOrdinal(ROperationResultStatus.class, ordinal); + return status != null + ? status.getSchemaValue() + : null; + } + + /** + * Transforms {@link AuditEventRecord} to {@link MAuditEventRecord} without any subentities. + *

+ * Design notes: Arguably, this code could be in {@link MAuditEventRecord}. + * Also the + */ + public MAuditEventRecord from(AuditEventRecord record) { + MAuditEventRecord bean = new MAuditEventRecord(); + bean.id = record.getRepoId(); // this better be null if we want to insert + bean.eventIdentifier = record.getEventIdentifier(); + bean.timestamp = MiscUtil.asInstant(record.getTimestamp()); + bean.channel = record.getChannel(); + bean.eventStage = MiscUtil.enumOrdinal(RAuditEventStage.from(record.getEventStage())); + bean.eventType = MiscUtil.enumOrdinal(RAuditEventType.from(record.getEventType())); + bean.hostIdentifier = record.getHostIdentifier(); + + PrismReferenceValue attorney = record.getAttorneyRef(); + if (attorney != null) { + bean.attorneyName = attorney.getDescription(); + bean.attorneyOid = attorney.getOid(); + } + + PrismReferenceValue initiator = record.getInitiatorRef(); + if (initiator != null) { + bean.initiatorName = initiator.getDescription(); + bean.initiatorOid = initiator.getOid(); + bean.initiatorType = targetTypeToRepoOrdinal(initiator); + } + + bean.message = trim(record.getMessage(), MESSAGE); + bean.nodeIdentifier = record.getNodeIdentifier(); + bean.outcome = MiscUtil.enumOrdinal(ROperationResultStatus.from(record.getOutcome())); + bean.parameter = record.getParameter(); + bean.remoteHostAddress = record.getRemoteHostAddress(); + bean.requestIdentifier = record.getRequestIdentifier(); + bean.result = record.getResult(); + bean.sessionIdentifier = record.getSessionIdentifier(); + + PrismReferenceValue target = record.getTargetRef(); + if (target != null) { + bean.targetName = target.getDescription(); + bean.targetOid = target.getOid(); + bean.targetType = targetTypeToRepoOrdinal(target); + } + PrismReferenceValue targetOwner = record.getTargetOwnerRef(); + if (targetOwner != null) { + bean.targetOwnerName = targetOwner.getDescription(); + bean.targetOwnerOid = targetOwner.getOid(); + bean.targetOwnerType = targetTypeToRepoOrdinal(targetOwner); + } + bean.taskIdentifier = record.getTaskIdentifier(); + bean.taskOid = record.getTaskOid(); + return bean; + } + + private Integer targetTypeToRepoOrdinal(PrismReferenceValue targetOwner) { + //noinspection rawtypes + Class objectClass = SqlTransformerSupport.getInstance() + .qNameToSchemaClass(targetOwner.getTargetType()); + //noinspection unchecked + return MiscUtil.enumOrdinal(RObjectType.getByJaxbType(objectClass)); + } + @Override - public AuditEventRecordSqlTransformer createTransformer( - SqlTransformerSupport transformerSupport) { - return new AuditEventRecordSqlTransformer(transformerSupport, this); + protected void processExtensionColumns( + AuditEventRecordType schemaObject, Tuple tuple, QAuditEventRecord entityPath) { + for (String propertyName : getExtensionColumns().keySet()) { + Object customColumnValue = tuple.get(entityPath.getPath(propertyName)); + schemaObject.getCustomColumnProperty().add( + new AuditEventRecordCustomColumnPropertyType() + .name(propertyName).value((String) customColumnValue)); + } } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java index a615273c1b8..cc38d987160 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java @@ -10,14 +10,13 @@ import com.evolveum.midpoint.repo.sql.audit.beans.MAuditItem; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditItem; -import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; /** * Mapping for {@link QAuditItem}, model type is non-containerable {@link ItemPathType}. */ public class QAuditItemMapping - extends QueryTableMapping { + extends AuditTableMapping { public static final String DEFAULT_ALIAS_NAME = "ai"; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java index 328c6cf5541..36f9a15c9fc 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java @@ -10,14 +10,13 @@ import com.evolveum.midpoint.repo.sql.audit.beans.MAuditPropertyValue; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditPropertyValue; -import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordPropertyType; /** * Mapping for {@link QAuditPropertyValue}. */ public class QAuditPropertyValueMapping - extends QueryTableMapping { + extends AuditTableMapping { public static final String DEFAULT_ALIAS_NAME = "apv"; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java index 6507e3eeebd..15396686744 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java @@ -10,14 +10,13 @@ import com.evolveum.midpoint.repo.sql.audit.beans.MAuditRefValue; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditRefValue; -import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordReferenceType; /** * Mapping between {@link QAuditRefValue} and {@link AuditEventRecordReferenceType}. */ public class QAuditRefValueMapping - extends QueryTableMapping { + extends AuditTableMapping { public static final String DEFAULT_ALIAS_NAME = "aref"; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java index 8f65c518dab..a912d94ce62 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java @@ -10,13 +10,12 @@ import com.evolveum.midpoint.repo.sql.audit.beans.MAuditResource; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditResource; -import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; /** * Mapping for {@link QAuditResource}, no transformation supported. */ public class QAuditResourceMapping - extends QueryTableMapping { + extends AuditTableMapping { public static final String DEFAULT_ALIAS_NAME = "ares"; diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java index 5bad518b18e..d7304ad77d0 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java @@ -29,7 +29,7 @@ import com.evolveum.midpoint.repo.sqlbase.filtering.ObjectFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.repo.sqlbase.mapping.SqlDetailFetchMapper; -import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; +import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformationException; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; @@ -141,7 +141,8 @@ private void processOrdering(List orderings) throw new QueryException( "ORDER BY is not possible for complex paths: " + orderByItemPath); } - Path path = mapping().primarySqlPath(orderByItemPath.asSingleNameOrFail(), this); + Path path = entityPathMapping.primarySqlPath( + orderByItemPath.asSingleNameOrFail(), this); if (!(path instanceof ComparableExpressionBase)) { throw new QueryException( "ORDER BY is not possible for non-comparable path: " + orderByItemPath); @@ -172,12 +173,14 @@ public PageOf executeQuery(Connection conn) throws QueryException { .fetch(); // TODO: run fetchers selectively based on options? - if (!mapping().detailFetchMappers().isEmpty()) { + Collection> detailFetchMappers = + entityPathMapping.detailFetchMappers(); + if (!detailFetchMappers.isEmpty()) { // we don't want to extract R if no mappers exist, otherwise we want to do it only once List dataEntities = data.stream() .map(t -> t.get(entity)) .collect(Collectors.toList()); - for (SqlDetailFetchMapper fetcher : mapping().detailFetchMappers()) { + for (SqlDetailFetchMapper fetcher : detailFetchMappers) { fetcher.execute(sqlRepoContext, () -> sqlRepoContext.newQuery(conn), dataEntities); } } @@ -186,7 +189,7 @@ public PageOf executeQuery(Connection conn) throws QueryException { } private @NotNull Expression[] buildSelectExpressions(Q entity, SQLQuery query) { - Path[] defaultExpressions = mapping().selectExpressions(entity, options); + Path[] defaultExpressions = entityPathMapping.selectExpressions(entity, options); if (!query.getMetadata().isDistinct() || query.getMetadata().getOrderBy().isEmpty()) { return defaultExpressions; } @@ -293,9 +296,8 @@ public void processOptions(Collection> opti public PageOf transformToSchemaType(PageOf result) throws SchemaException, QueryException { try { - SqlTransformer transformer = createTransformer(); - return result.map(row -> transformer.toSchemaObjectSafe(row, root(), options)); - } catch (SqlTransformer.SqlTransformationException e) { + return result.map(row -> entityPathMapping.toSchemaObjectSafe(row, root(), options)); + } catch (SqlTransformationException e) { Throwable cause = e.getCause(); if (cause instanceof SchemaException) { throw (SchemaException) cause; @@ -307,13 +309,6 @@ public PageOf transformToSchemaType(PageOf result) } } - /** - * Creates transformer for the {@link #entityPathMapping}. - * Made abstract, because the way how to create the transformer can differ on the type - * of context that is needed to do it (typically providing various components). - */ - protected abstract SqlTransformer createTransformer(); - /** * Returns wrapped query if usage of Querydsl API is more convenient. */ diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryModelMapping.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryModelMapping.java index edaa59726b5..73033d3b514 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryModelMapping.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryModelMapping.java @@ -13,6 +13,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.evolveum.midpoint.prism.path.ItemName; import com.evolveum.midpoint.prism.path.ItemPath; @@ -39,6 +41,8 @@ */ public class QueryModelMapping, R> { + protected final Logger logger = LoggerFactory.getLogger(getClass()); + private final Class schemaType; private final Class queryType; diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java index a702c535f98..961282f4912 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java @@ -11,6 +11,7 @@ import java.util.function.Function; import javax.xml.namespace.QName; +import com.querydsl.core.Tuple; import com.querydsl.core.types.EntityPath; import com.querydsl.core.types.Path; import com.querydsl.core.types.Predicate; @@ -26,7 +27,6 @@ import com.evolveum.midpoint.repo.sqlbase.QueryException; import com.evolveum.midpoint.repo.sqlbase.RepositoryException; import com.evolveum.midpoint.repo.sqlbase.SqlQueryContext; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; import com.evolveum.midpoint.repo.sqlbase.filtering.item.PolyStringItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.SimpleItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.TimestampItemFilterProcessor; @@ -35,6 +35,7 @@ import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.SchemaException; /** * Common supertype for mapping items/attributes between schema (prism) classes and tables. @@ -43,8 +44,8 @@ * related to-many detail tables. * * The main goal of this type is to map object query conditions and ORDER BY to SQL. - * Transformation between schema/prism objects and repository objects (row beans or tuples) is - * delegated to {@link SqlTransformer}. + * Mappings also takes care of transformation between schema/prism objects and repository objects + * (row beans or tuples). * Objects of various {@link QueryTableMapping} subclasses are factories for the transformer. * * Other important functions of mapping: @@ -253,19 +254,6 @@ public synchronized Q defaultAlias() { return defaultAlias; } - /** - * Creates {@link SqlTransformer} of row bean to schema type, override if provided. - * TODO: rethink/confirm this create mechanism, currently the SqlTransformerSupport is managed - * component without any other state and so are transformers, perhaps we can pre-create them - * or cache (I don't like the sound of that). On the other hand they are really lightweight - * and short lived helpers too, so it shouldn't be a real GC problem. - */ - @Deprecated - public SqlTransformer createTransformer( - SqlTransformerSupport transformerSupport) { - throw new UnsupportedOperationException("Bean transformer not supported for " + queryType()); - } - /** * Returns collection of all registered {@link SqlDetailFetchMapper}s. */ @@ -325,6 +313,35 @@ public R newRowObject() { "Row bean creation not implemented for query type " + queryType().getName()); } + /** + * Transforms row of {@link R} type to schema type {@link S}. + * If pre-generated bean is used as row it does not include extension (dynamic) columns, + * which is OK if extension columns are used only for query and their information + * is still contained in the object somehow else (e.g. full object LOB). + * + * Alternative would be dynamically generated list of select expressions and transforming + * row to M object directly from {@link com.querydsl.core.Tuple}. + */ + public abstract S toSchemaObject(R row) throws SchemaException; + + /** + * Transforms row Tuple containing attributes of {@link R} to schema type {@link S}. + * Entity path can be used to access tuple elements. + * This allows loading also dynamically defined columns (like extensions). + */ + public abstract S toSchemaObject(Tuple row, Q entityPath, + Collection> options) + throws SchemaException; + + public S toSchemaObjectSafe(Tuple tuple, Q entityPath, + Collection> options) { + try { + return toSchemaObject(tuple, entityPath, options); + } catch (SchemaException e) { + throw new SqlTransformationException(e); + } + } + @Override public String toString() { return "QueryTableMapping{" + diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformationException.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformationException.java new file mode 100644 index 00000000000..35028b6b7fb --- /dev/null +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformationException.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.repo.sqlbase.mapping; + +/** + * Runtime exception wrapping other exception that occurred during object transformation + * inside mapping (e.g. tuple to schema object). + */ +public class SqlTransformationException extends RuntimeException { + + public SqlTransformationException(Throwable cause) { + super(cause); + } +} diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformer.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformer.java deleted file mode 100644 index 20e71732c62..00000000000 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformer.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqlbase.mapping; - -import java.util.Collection; - -import com.querydsl.core.Tuple; - -import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.SelectorOptions; -import com.evolveum.midpoint.util.exception.SchemaException; - -/** - * Contract for SQL transformers translating from query beans or tuples to model types. - * Concrete transformers may do more than pure transformation, they can also help with storing - * related entities (e.g. parts of the object aggregate). - * The implemented methods may vary wildly as some are used by very generic mechanisms (query - * interpreter) while others are called on concrete transformer of known type needed in particular - * situation. - * - * @param schema type - * @param type of entity path - * @param type of the transformed data, a row bean - */ -public interface SqlTransformer, R> { - - /** - * Transforms row of {@link R} type to schema type {@link S}. - * If pre-generated bean is used as row it does not include extension (dynamic) columns, - * which is OK if extension columns are used only for query and their information - * is still contained in the object somehow else (e.g. full object LOB). - *

- * Alternative would be dynamically generated list of select expressions and transforming - * row to M object directly from {@link com.querydsl.core.Tuple}. - */ - S toSchemaObject(R row) throws SchemaException; - - /** - * Transforms row Tuple containing attributes of {@link R} to schema type {@link S}. - * Entity path can be used to access tuple elements. - * This allows loading also dynamically defined columns (like extensions). - */ - S toSchemaObject(Tuple row, Q entityPath, - Collection> options) - throws SchemaException; - - default S toSchemaObjectSafe(Tuple tuple, Q entityPath, Collection> options) { - try { - return toSchemaObject(tuple, entityPath, options); - } catch (SchemaException e) { - throw new SqlTransformationException(e); - } - } - - class SqlTransformationException extends RuntimeException { - public SqlTransformationException(Throwable cause) { - super(cause); - } - } -} From d12dbc72937c5dcb6f57be35aebaf58ac3d51725 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Fri, 30 Apr 2021 13:24:42 +0200 Subject: [PATCH 07/33] Improve parameterized system performance test 1) We now use TestMonitor to report some of the aspects. 2) Second import task and user recomputation task were added. 3) Minor code improvements were done. 4) Plus other things cherry-picked from support-4.2 branch. --- testing/story/pom.xml | 4 - .../story/sysperf/DetailsOutputFile.java | 32 +++ .../story/sysperf/ExtensionSchemaVariant.java | 7 +- .../story/sysperf/OtherParameters.java | 18 ++ .../story/sysperf/PopulationVariant.java | 3 +- .../story/sysperf/ProgressOutputFile.java | 32 +++ .../testing/story/sysperf/SourceVariant.java | 2 + .../story/sysperf/SummaryOutputFile.java | 36 ++++ .../story/sysperf/TestSystemPerformance.java | 203 +++++++++++++----- .../story/sysperf/ThreadingVariant.java | 39 +++- .../resources/system-perf/task-import-16t.xml | 28 --- .../resources/system-perf/task-import-4t.xml | 28 --- .../{task-import-1t.xml => task-import.xml} | 2 +- .../resources/system-perf/task-recompute.xml | 35 +++ 14 files changed, 337 insertions(+), 132 deletions(-) create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/OtherParameters.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java delete mode 100644 testing/story/src/test/resources/system-perf/task-import-16t.xml delete mode 100644 testing/story/src/test/resources/system-perf/task-import-4t.xml rename testing/story/src/test/resources/system-perf/{task-import-1t.xml => task-import.xml} (92%) create mode 100644 testing/story/src/test/resources/system-perf/task-recompute.xml diff --git a/testing/story/pom.xml b/testing/story/pom.xml index c6bd553c231..31af5e5bab1 100644 --- a/testing/story/pom.xml +++ b/testing/story/pom.xml @@ -181,10 +181,6 @@ ch.qos.logback logback-classic - - com.google.guava - guava - diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java new file mode 100644 index 00000000000..beadc7ec923 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java @@ -0,0 +1,32 @@ +package com.evolveum.midpoint.testing.story.sysperf; + +import com.evolveum.midpoint.schema.util.task.TaskOperationStatsUtil; +import com.evolveum.midpoint.schema.util.task.TaskPerformanceInformation; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.START; +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TARGET_DIR; + +class DetailsOutputFile { + + private static final File FILE = new File(TARGET_DIR, START + "-details.txt"); + private final PrintWriter writer; + + DetailsOutputFile() throws IOException { + writer = new PrintWriter(new FileWriter(FILE)); + } + + void logTestFinish(String testName, TaskType taskAfter, TaskPerformanceInformation performanceInformation) { + writer.printf("********** %s FINISHED **********\n\n", testName); + writer.println(TaskOperationStatsUtil.format(taskAfter.getOperationStats())); + writer.println(); + writer.println(performanceInformation.debugDump()); + writer.println(); + writer.flush(); + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java index 5870a608bc8..fc2b6a2a5ad 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java @@ -10,9 +10,10 @@ enum ExtensionSchemaVariant { BASIC("basic"), - BIG("big"), - BIG_GLOBAL("big-global"), - INDEXED("indexed"); + INDEXED("indexed"), + BIG("big"), // don't use: does not make any difference + BIG_GLOBAL("big-global") // don't use: does not make any difference + ; private static final String PROP_EXTENSION_SCHEMA = "schema"; diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/OtherParameters.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/OtherParameters.java new file mode 100644 index 00000000000..820feafecf2 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/OtherParameters.java @@ -0,0 +1,18 @@ +package com.evolveum.midpoint.testing.story.sysperf; + +public class OtherParameters { + + private static final String PROP_TASK_TIMEOUT = "taskTimeout"; + + final int taskTimeout; + + private OtherParameters(int taskTimeout) { + this.taskTimeout = taskTimeout; + } + + static OtherParameters setup() { + return new OtherParameters( + Integer.parseInt(System.getProperty(PROP_TASK_TIMEOUT, "1800000")) // 30 minutes + ); + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java index fc5971206eb..8e18fe1655a 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java @@ -7,11 +7,10 @@ package com.evolveum.midpoint.testing.story.sysperf; -import com.evolveum.midpoint.test.DummyTestResource; - enum PopulationVariant { P10("10", 10), + P100("100", 100), P1K("1k", 1000), P10K("10k", 10000), P100K("100k", 100_000), diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java new file mode 100644 index 00000000000..5fef0efa789 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java @@ -0,0 +1,32 @@ +package com.evolveum.midpoint.testing.story.sysperf; + +import com.evolveum.midpoint.task.api.Task; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TARGET_DIR; +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.START; + +class ProgressOutputFile { + + static final File FILE = new File(TARGET_DIR, START + "-progress.csv"); + private final PrintWriter writer; + + ProgressOutputFile() throws IOException { + writer = new PrintWriter(new FileWriter(FILE)); + writer.println("test;time;progress"); + } + + void recordProgress(String testName, Task task) { + long start = task.getLastRunStartTimestamp(); + Long lastFinish = task.getLastRunFinishTimestamp(); + long thisFinish = lastFinish != null && lastFinish > start ? lastFinish : System.currentTimeMillis(); + long running = thisFinish - start; + long progress = task.getProgress(); + writer.println(testName + ";" + running + ";" + progress); + writer.flush(); + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java index 396ba8e503c..9ce90c90906 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java @@ -23,6 +23,8 @@ enum SourceVariant { MS2_5("ms2-5", "resource-source-ms0002.xml", 1, 1, 5), MS20_5("ms20-5", "resource-source-ms0020.xml", 10, 10, 5), MS110_5("ms110-5", "resource-source-ms0110.xml", 100, 10, 5), + MS110_20("ms110-20", "resource-source-ms0110.xml", 100, 10, 20), + MS110_100("ms110-100", "resource-source-ms0110.xml", 100, 10, 100), MS110_1000("ms110-1000", "resource-source-ms0110.xml", 100, 10, 1000); private static final String PROP_SOURCE = "source"; diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java new file mode 100644 index 00000000000..514801ed06b --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java @@ -0,0 +1,36 @@ +package com.evolveum.midpoint.testing.story.sysperf; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Date; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.*; + +class SummaryOutputFile { + + private static final File FILE = new File(TARGET_DIR, START + "-summary.txt"); + private final PrintWriter writer; + + SummaryOutputFile() throws IOException { + writer = new PrintWriter(new FileWriter(FILE)); + } + + void logStart() { + writer.println("Started: " + new Date(START) + " (" + START + ")"); + writer.printf("Extension schema variant: %s\n", EXTENSION_SCHEMA_VARIANT); + writer.printf("Source variant: %s\n", SOURCE_VARIANT); + writer.printf("Threading variant: %s\n", THREADING_VARIANT); + writer.printf("Population variant: %s\n", POPULATION_VARIANT); + writer.printf("Progress file: %s\n\n", ProgressOutputFile.FILE); + writer.flush(); + } + + void logTestFinish(String testName, long executionTime, double timePerAccount) { + writer.printf("********** %s FINISHED **********\n\n", testName); + writer.printf("Task execution time: %,d ms\n", executionTime); + writer.printf("Time per account: %,.1f ms\n\n", timePerAccount); + writer.flush(); + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java index c9273dd4e81..ab4b89cf977 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java @@ -7,14 +7,16 @@ package com.evolveum.midpoint.testing.story.sysperf; +import static com.evolveum.midpoint.tools.testng.TestMonitor.PERF_REPORT_PREFIX_PROPERTY_NAME; + import static org.assertj.core.api.Assertions.assertThat; import java.io.File; -import java.io.FileWriter; -import java.io.PrintWriter; -import java.util.Date; +import java.io.IOException; + +import com.evolveum.midpoint.tools.testng.PerformanceTestClassMixin; +import com.evolveum.midpoint.tools.testng.TestReportSection; -import com.google.common.base.MoreObjects; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; @@ -43,34 +45,41 @@ * * Examples: * - * -Dpopulation=10k -Dthreading=16t -Dschema=basic -Dsource=ms2-5 - * -Dpopulation=100k -Dthreading=4t -Dschema=indexed -Dsource=ms110-5 - * -Dpopulation=10k -Dthreading=16t -Dschema=big-global -Dsource=ms110-1000 + * -Dpopulation=10k -Dthreading=16t -Dschema=basic -Dsource=ms2-5 + * -Dpopulation=100k -Dthreading=4t -Dschema=indexed -Dsource=ms110-5 + * -Dpopulation=10k -Dthreading=16t -Dschema=basic -Dsource=ms110-1000 */ @ContextConfiguration(locations = { "classpath:ctx-story-test-main.xml" }) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) -public class TestSystemPerformance extends AbstractStoryTest { +public class TestSystemPerformance extends AbstractStoryTest implements PerformanceTestClassMixin { public static final File TEST_DIR = new File(MidPointTestConstants.TEST_RESOURCES_DIR, "system-perf"); + static final String TARGET_DIR = "./target"; private static final File SYSTEM_CONFIGURATION_FILE = new File(TEST_DIR, "system-configuration.xml"); - private static final ExtensionSchemaVariant EXTENSION_SCHEMA_VARIANT; - private static final SourceVariant SOURCE_VARIANT; - private static final ThreadingVariant THREADING_VARIANT; + static final ExtensionSchemaVariant EXTENSION_SCHEMA_VARIANT; + static final SourceVariant SOURCE_VARIANT; + static final ThreadingVariant THREADING_VARIANT; private static final TemplateVariant TEMPLATE_VARIANT; - private static final PopulationVariant POPULATION_VARIANT; + static final PopulationVariant POPULATION_VARIANT; + private static final OtherParameters OTHER_PARAMETERS; private static final DummyTestResource RESOURCE_SOURCE; private static final TestResource TASK_IMPORT; + private static final TestResource TASK_RECOMPUTE; + + static final long START = System.currentTimeMillis(); - private static final long START = System.currentTimeMillis(); + private static final String REPORT_FILE_PREFIX = TARGET_DIR + "/" + START + "-report"; + private static final String REPORT_SECTION_SUMMARY_NAME = "summary"; + private static final String REPORT_SECTION_TEST_SUMMARY_NAME = "testSummary"; - private static final File SUMMARY_FILE = new File("./target", START + "-summary.txt"); - private PrintWriter summary; + private TestReportSection testSummaryReportSection; - private static final File PROGRESS_FILE = new File("./target", START + "-progress.csv"); - private PrintWriter progress; + private final ProgressOutputFile progressOutputFile = new ProgressOutputFile(); + private final SummaryOutputFile summaryOutputFile = new SummaryOutputFile(); + private final DetailsOutputFile detailsOutputFile = new DetailsOutputFile(); private long lastProgress; @@ -82,9 +91,16 @@ public class TestSystemPerformance extends AbstractStoryTest { THREADING_VARIANT = ThreadingVariant.setup(); TEMPLATE_VARIANT = TemplateVariant.setup(); POPULATION_VARIANT = PopulationVariant.setup(); + OTHER_PARAMETERS = OtherParameters.setup(); RESOURCE_SOURCE = SOURCE_VARIANT.createDummyTestResource(); TASK_IMPORT = THREADING_VARIANT.getImportTaskResource(); + TASK_RECOMPUTE = THREADING_VARIANT.getRecomputeTaskResource(); + + System.setProperty(PERF_REPORT_PREFIX_PROPERTY_NAME, REPORT_FILE_PREFIX); + } + + public TestSystemPerformance() throws IOException { } @Override @@ -98,12 +114,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti sourceInitializer = new SourceInitializer(this, RESOURCE_SOURCE, SOURCE_VARIANT, POPULATION_VARIANT, initTask); sourceInitializer.run(initResult); - summary = new PrintWriter(new FileWriter(SUMMARY_FILE)); - - progress = new PrintWriter(new FileWriter(PROGRESS_FILE)); - progress.println("time;progress"); - - logStart(); + addObject(TASK_IMPORT.file, initTask, initResult, workerThreadsCustomizer(THREADING_VARIANT.getThreads())); + addObject(TASK_RECOMPUTE.file, initTask, initResult, workerThreadsCustomizer(THREADING_VARIANT.getThreads())); } @Override @@ -121,6 +133,38 @@ protected void importSystemTasks(OperationResult initResult) { // nothing here } + @Test + public void test000LogStart() { + + testMonitor().addReportSection(REPORT_SECTION_SUMMARY_NAME) + .withColumns("schema", "source", "singleValuedAttributes", "multiValuedAttributes", "attributeValues", + "threading", "threads", "tasks", + "population", "accounts") + .addRow(EXTENSION_SCHEMA_VARIANT.getName(), + SOURCE_VARIANT.getName(), + SOURCE_VARIANT.getSingleValuedAttributes(), + SOURCE_VARIANT.getMultiValuedAttributes(), + SOURCE_VARIANT.getAttributeValues(), + THREADING_VARIANT.getName(), + THREADING_VARIANT.getThreads(), + THREADING_VARIANT.getTasks(), + POPULATION_VARIANT.getName(), + POPULATION_VARIANT.getAccounts()); + + + testSummaryReportSection = testMonitor().addReportSection(REPORT_SECTION_TEST_SUMMARY_NAME) + .withColumns("test", "time", "timePerAccount"); + + logger.info("********** STARTED **********\n"); + logger.info("Extension schema variant: {}", EXTENSION_SCHEMA_VARIANT); + logger.info("Source variant: {}", SOURCE_VARIANT); + logger.info("Threading variant: {}", THREADING_VARIANT); + logger.info("Population variant: {}", POPULATION_VARIANT); + logger.info("Progress file: {}", ProgressOutputFile.FILE); + + summaryOutputFile.logStart(); + } + @Test public void test001DumpExtensionSchema() { PrismObjectDefinition userDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); @@ -139,8 +183,10 @@ public void test100Import() throws Exception { when(); - addTask(TASK_IMPORT, result); - waitForTaskFinish(TASK_IMPORT.oid, false, 0, 1000000, false, 0, + restartTask(TASK_IMPORT.oid, result); + Thread.sleep(500); + + waitForTaskFinish(TASK_IMPORT.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, builder -> builder.taskConsumer(this::recordProgress)); then(); @@ -162,7 +208,62 @@ public void test100Import() throws Exception { .display() .getObject(); - logFinish(taskAfter); + logTestFinish(taskAfter); + } + + @Test + public void test110ImportAgain() throws Exception { + given(); + + Task task = getTestTask(); + OperationResult result = task.getResult(); + + int usersBefore = repositoryService.countObjects(UserType.class, null, null, result); + + when(); + + restartTask(TASK_IMPORT.oid, result); + Thread.sleep(500); + + lastProgress = 0; + waitForTaskFinish(TASK_IMPORT.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, + builder -> builder.taskConsumer(this::recordProgress)); + + then(); + + int usersAfter = repositoryService.countObjects(UserType.class, null, null, result); + assertThat(usersAfter - usersBefore).as("users created").isEqualTo(0); + + PrismObject taskAfter = assertTask(TASK_IMPORT.oid, "after") + .display() + .getObject(); + + logTestFinish(taskAfter); + } + + @Test + public void test120RecomputeUsers() throws Exception { + given(); + + Task task = getTestTask(); + OperationResult result = task.getResult(); + + when(); + + restartTask(TASK_RECOMPUTE.oid, result); + Thread.sleep(500); + + lastProgress = 0; + waitForTaskFinish(TASK_RECOMPUTE.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, + builder -> builder.taskConsumer(this::recordProgress)); + + then(); + + PrismObject taskAfter = assertTask(TASK_RECOMPUTE.oid, "after") + .display() + .getObject(); + + logTestFinish(taskAfter); } private long getExecutionTime(PrismObject taskAfter) { @@ -171,47 +272,34 @@ private long getExecutionTime(PrismObject taskAfter) { return end - start; } + @SuppressWarnings("SameParameterValue") private String getSingleValuedPropertyName(int i) { return String.format("p-single-%04d", i); } + @SuppressWarnings("SameParameterValue") private String getMultiValuedPropertyName(int i) { return String.format("p-multi-%04d", i); } - private void logStart() { - logger.info("********** STARTED **********\n"); - logger.info("Extension schema variant: {}", EXTENSION_SCHEMA_VARIANT); - logger.info("Source variant: {}", SOURCE_VARIANT); - logger.info("Threading variant: {}", THREADING_VARIANT); - logger.info("Population variant: {}", POPULATION_VARIANT); - logger.info("Progress file: {}", PROGRESS_FILE); - - summary.println("Started: " + new Date(START) + " (" + START + ")"); - summary.printf("Extension schema variant: %s\n", EXTENSION_SCHEMA_VARIANT); - summary.printf("Source variant: %s\n", SOURCE_VARIANT); - summary.printf("Threading variant: %s\n", THREADING_VARIANT); - summary.printf("Population variant: %s\n", POPULATION_VARIANT); - summary.printf("Progress file: %s\n\n", PROGRESS_FILE); - summary.flush(); - } - - private void logFinish(PrismObject taskAfter) { + private void logTestFinish(PrismObject taskAfter) { TaskPerformanceInformation performanceInformation = TaskPerformanceInformation.fromTaskTree(taskAfter.asObjectable()); long executionTime = getExecutionTime(taskAfter); + double timePerAccount = (double) executionTime / (double) POPULATION_VARIANT.getAccounts(); + + String testName = getTestNameShort(); + + logger.info("********** {} FINISHED **********\n", testName); + logger.info(String.format("Task execution time: %,d ms", executionTime)); + logger.info(String.format("Time per account: %,.1f ms", timePerAccount)); + logger.info(TaskOperationStatsUtil.format(taskAfter.asObjectable().getOperationStats())); + logger.info(performanceInformation.debugDump()); - logger.info("********** FINISHED **********\n"); - logger.info("{}", String.format("Task execution time: %,d ms", executionTime)); - logger.info("{}", String.format("Time per account: %,.1f ms", (double) executionTime / (double) POPULATION_VARIANT.getAccounts())); - logger.info("{}", (TaskOperationStatsUtil.format(taskAfter.asObjectable().getOperationStats()))); - logger.info("{}", performanceInformation.debugDump()); + summaryOutputFile.logTestFinish(testName, executionTime, timePerAccount); + detailsOutputFile.logTestFinish(testName, taskAfter.asObjectable(), performanceInformation); - summary.printf("********** FINISHED **********\n"); - summary.printf("Task execution time: %,d ms\n", executionTime); - summary.printf("Time per account: %,.1f ms\n", (double) executionTime / (double) POPULATION_VARIANT.getAccounts()); - summary.println(TaskOperationStatsUtil.format(taskAfter.asObjectable().getOperationStats())); - summary.println(performanceInformation.debugDump()); - summary.flush(); + testSummaryReportSection + .addRow(testName, executionTime, timePerAccount); } private void recordProgress(Task task) { @@ -223,10 +311,7 @@ private void recordProgress(Task task) { } lastProgress = progress; - long end = MoreObjects.firstNonNull(task.getLastRunFinishTimestamp(), System.currentTimeMillis()); - long running = end - start; - this.progress.println(running + ";" + progress); - this.progress.flush(); + progressOutputFile.recordProgress(getTestNameShort(), task); OperationStatsType stats = task.getStoredOperationStatsOrClone(); logger.info("\n{}", TaskOperationStatsUtil.format(stats)); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java index 9fabb6b0793..cf5b0f368f0 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java @@ -14,26 +14,46 @@ enum ThreadingVariant { - T1("1t"), - T4("4t"), - T16("16t"), - T40_N4("40t-4n"); + T1("1t", "", 1, 1), + T4("4t", "", 4, 1), + T6("6t", "", 6, 1), + T8("8t", "", 8, 1), + T12("12t", "", 12, 1), + T16("16t", "", 16, 1), + T40_N4("40t-4n", "", 40, 4); private static final String PROP_THREADING = "threading"; private static final String IMPORT_TASK_OID = "c32d4da6-bdd3-481d-931a-60ca8a5a01ba"; - private static final String TASK_FILE_NAME_PATTERN = "task-import-%s.xml"; + private static final String IMPORT_TASK_FILE_NAME_PATTERN = "task-import%s.xml"; + + private static final String RECOMPUTE_TASK_OID = "f5920848-6c8f-4eda-ae26-2b961d6dae1b"; + private static final String RECOMPUTE_TASK_FILE_NAME_PATTERN = "task-recompute%s.xml"; private final String name; + private final String taskNameSuffix; + private final int threads; + private final int tasks; - ThreadingVariant(String name) { + ThreadingVariant(String name, String taskNameSuffix, int threads, int tasks) { this.name = name; + this.taskNameSuffix = taskNameSuffix; + this.threads = threads; + this.tasks = tasks; } public String getName() { return name; } + public int getThreads() { + return threads; + } + + public int getTasks() { + return tasks; + } + public static ThreadingVariant setup() { String configuredName = System.getProperty(PROP_THREADING, T1.name); ThreadingVariant variant = fromName(configuredName); @@ -42,10 +62,15 @@ public static ThreadingVariant setup() { } public TestResource getImportTaskResource() { - String fileName = String.format(TASK_FILE_NAME_PATTERN, name); + String fileName = String.format(IMPORT_TASK_FILE_NAME_PATTERN, taskNameSuffix); return new TestResource<>(TEST_DIR, fileName, IMPORT_TASK_OID); } + public TestResource getRecomputeTaskResource() { + String fileName = String.format(RECOMPUTE_TASK_FILE_NAME_PATTERN, taskNameSuffix); + return new TestResource<>(TEST_DIR, fileName, RECOMPUTE_TASK_OID); + } + private static ThreadingVariant fromName(String name) { for (ThreadingVariant value : values()) { if (value.name.equals(name)) { diff --git a/testing/story/src/test/resources/system-perf/task-import-16t.xml b/testing/story/src/test/resources/system-perf/task-import-16t.xml deleted file mode 100644 index 4e99715237f..00000000000 --- a/testing/story/src/test/resources/system-perf/task-import-16t.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - Import - - - ri:AccountObjectClass - 16 - - - - runnable - - http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/import/handler-3 - - - single - diff --git a/testing/story/src/test/resources/system-perf/task-import-4t.xml b/testing/story/src/test/resources/system-perf/task-import-4t.xml deleted file mode 100644 index 1f5fd3eeced..00000000000 --- a/testing/story/src/test/resources/system-perf/task-import-4t.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - Import - - - ri:AccountObjectClass - 4 - - - - runnable - - http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/import/handler-3 - - - single - diff --git a/testing/story/src/test/resources/system-perf/task-import-1t.xml b/testing/story/src/test/resources/system-perf/task-import.xml similarity index 92% rename from testing/story/src/test/resources/system-perf/task-import-1t.xml rename to testing/story/src/test/resources/system-perf/task-import.xml index fad1852f6f2..6f5872231f9 100644 --- a/testing/story/src/test/resources/system-perf/task-import-1t.xml +++ b/testing/story/src/test/resources/system-perf/task-import.xml @@ -18,7 +18,7 @@ - runnable + closed http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/import/handler-3 diff --git a/testing/story/src/test/resources/system-perf/task-recompute.xml b/testing/story/src/test/resources/system-perf/task-recompute.xml new file mode 100644 index 00000000000..4a17cd4afea --- /dev/null +++ b/testing/story/src/test/resources/system-perf/task-recompute.xml @@ -0,0 +1,35 @@ + + + + + + Recompute + + + UserType + + + + name + u- + true + + + + + + + closed + + http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/recompute/handler-3 + + single + From 1b2c07c9deea55ef5bc451e1931b8266c2d79b72 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Fri, 30 Apr 2021 20:58:28 +0200 Subject: [PATCH 08/33] *TransformerSupport renamed to *SupportService, code cleanup --- .../repo/sqale/SqaleQueryContext.java | 16 ++++++------- .../midpoint/repo/sqale/SqaleRepoContext.java | 4 +++- .../repo/sqale/SqaleRepositoryBeanConfig.java | 7 +++++- .../repo/sqale/SqaleRepositoryService.java | 23 ++++++++---------- ...rSupport.java => SqaleSupportService.java} | 12 +++++----- .../item/RefTableItemDeltaProcessor.java | 2 +- .../sqale/operations/AddObjectOperation.java | 6 ++--- .../repo/sqale/qmodel/SqaleTableMapping.java | 24 +++++++------------ .../sqale/qmodel/TransformerForOwnedBy.java | 21 ---------------- .../qmodel/assignment/QAssignmentMapping.java | 2 +- .../sqale/qmodel/object/QObjectMapping.java | 12 +++++----- .../repo/sqale/update/RootUpdateContext.java | 10 ++++---- .../repo/sqale/update/SqaleUpdateContext.java | 18 +++++++------- .../func/SqaleRepoAddDeleteObjectTest.java | 6 ++--- .../evolveum/midpoint/repo/sql/AuditTest.java | 2 +- .../midpoint/repo/sql/BaseSQLRepoTest.java | 2 +- .../repo/sql/SqlAuditServiceFactory.java | 4 ++-- .../repo/sql/SqlAuditServiceImpl.java | 6 ++--- .../repo/sql/audit/AuditSqlQueryContext.java | 12 +++++----- .../sql/audit/mapping/AuditTableMapping.java | 4 ++-- .../sql/audit/mapping/QAuditDeltaMapping.java | 6 ++--- .../mapping/QAuditEventRecordMapping.java | 12 ++++------ .../audit/mapping/QAuditResourceMapping.java | 2 +- .../repo/sqlbase/SqlQueryContext.java | 23 +++++++++--------- .../repo/sqlbase/SqlQueryExecutor.java | 3 +-- .../midpoint/repo/sqlbase/SqlRepoContext.java | 12 +++++++++- ...merSupport.java => SqlSupportService.java} | 12 ++++++---- .../sqlbase/mapping/QueryTableMapping.java | 3 +-- ...n.java => RepositoryMappingException.java} | 4 ++-- 29 files changed, 126 insertions(+), 144 deletions(-) rename repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/{SqaleTransformerSupport.java => SqaleSupportService.java} (82%) delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java rename repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/{SqlTransformerSupport.java => SqlSupportService.java} (88%) rename repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/{SqlTransformationException.java => RepositoryMappingException.java} (77%) diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java index 07f9e0ff2dd..4379a1f2e24 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java @@ -24,7 +24,7 @@ public class SqaleQueryContext, R> extends SqlQueryContext { public static , R> SqaleQueryContext from( - Class schemaType, SqaleTransformerSupport transformerSupport, + Class schemaType, SqaleSupportService sqaleSupportService, SqlRepoContext sqlRepoContext) { SqaleTableMapping rootMapping = sqlRepoContext.getMappingBySchemaType(schemaType); @@ -35,16 +35,16 @@ public static , R> SqaleQueryContext< query.getMetadata().setValidate(true); return new SqaleQueryContext<>( - rootPath, rootMapping, transformerSupport, sqlRepoContext, query); + rootPath, rootMapping, sqaleSupportService, sqlRepoContext, query); } private SqaleQueryContext( Q entityPath, SqaleTableMapping mapping, - SqaleTransformerSupport transformerSupport, + SqaleSupportService sqaleSupportService, SqlRepoContext sqlRepoContext, SQLQuery query) { - super(entityPath, mapping, sqlRepoContext, transformerSupport, query); + super(entityPath, mapping, sqaleSupportService, query); } @Override @@ -53,7 +53,7 @@ public FilterProcessor createInOidFilter(SqlQueryContext c } public @NotNull Integer searchCachedRelationId(QName qName) { - return transformerSupport().searchCachedRelationId(qName); + return supportService().searchCachedRelationId(qName); } /** @@ -66,10 +66,10 @@ public FilterProcessor createInOidFilter(SqlQueryContext c deriveNew(TQ newPath, QueryTableMapping newMapping) { return (SqlQueryContext) new SqaleQueryContext( newPath, (SqaleTableMapping) newMapping, - transformerSupport(), sqlRepoContext, sqlQuery); + supportService(), sqlRepoContext, sqlQuery); } - private SqaleTransformerSupport transformerSupport() { - return (SqaleTransformerSupport) transformerSupport; + private SqaleSupportService supportService() { + return (SqaleSupportService) sqlSupportService; } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java index b46b6eea22d..6be2920d497 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryModelMappingRegistry; import com.evolveum.midpoint.repo.sqlbase.querydsl.QuerydslJsonbType; +import com.evolveum.midpoint.schema.SchemaService; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; /** @@ -32,8 +33,9 @@ public class SqaleRepoContext extends SqlRepoContext { public SqaleRepoContext( JdbcRepositoryConfiguration jdbcRepositoryConfiguration, DataSource dataSource, + SchemaService schemaService, QueryModelMappingRegistry mappingRegistry) { - super(jdbcRepositoryConfiguration, dataSource, mappingRegistry); + super(jdbcRepositoryConfiguration, dataSource, schemaService, mappingRegistry); // each enum type must be registered if we want to map it as objects (to PG enum types) querydslConfig.register(new EnumAsObjectType<>(ActivationStatusType.class)); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java index 800f72f08e5..50b9da2b697 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java @@ -110,6 +110,7 @@ public DataSource dataSource(DataSourceFactory dataSourceFactory) @Bean public SqaleRepoContext sqlRepoContext( SqaleRepositoryConfiguration repositoryConfiguration, + SchemaService schemaService, DataSource dataSource) { QueryModelMappingRegistry mappingRegistry = new QueryModelMappingRegistry() // ordered alphabetically here, mappings without schema type at the end @@ -152,7 +153,11 @@ public SqaleRepoContext sqlRepoContext( .register(QReferenceMapping.INSTANCE) .seal(); - return new SqaleRepoContext(repositoryConfiguration, dataSource, mappingRegistry); + return new SqaleRepoContext( + repositoryConfiguration, + dataSource, + schemaService, + mappingRegistry); } @Bean diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java index 42899eb84ce..41822a14438 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java @@ -54,9 +54,7 @@ /** * Repository implementation based on SQL, JDBC and Querydsl without any ORM. - * WORK IN PROGRESS: - * It will be PostgreSQL only or at least PG optimized with generic SQL support for other unsupported DB. - * Possible Oracle support is in play. + * WORK IN PROGRESS. */ public class SqaleRepositoryService implements RepositoryService { @@ -74,7 +72,7 @@ public class SqaleRepositoryService implements RepositoryService { private final SqaleRepoContext sqlRepoContext; private final SchemaService schemaService; private final SqlQueryExecutor sqlQueryExecutor; - private final SqaleTransformerSupport transformerSupport; + private final SqaleSupportService supportService; private final SqlPerformanceMonitorsCollection sqlPerformanceMonitorsCollection; // TODO: see comment in the SystemConfigurationChangeDispatcherImpl for related issues @@ -92,7 +90,7 @@ public SqaleRepositoryService( this.sqlRepoContext = sqlRepoContext; this.schemaService = schemaService; this.sqlQueryExecutor = new SqlQueryExecutor(sqlRepoContext); - this.transformerSupport = new SqaleTransformerSupport(schemaService, sqlRepoContext); + this.supportService = new SqaleSupportService(schemaService, sqlRepoContext); this.sqlPerformanceMonitorsCollection = sqlPerformanceMonitorsCollection; // monitor initialization and registration @@ -257,7 +255,7 @@ public String addObject( // TODO use executeAttempts String oid = new AddObjectOperation<>(object, options, operationResult) - .execute(transformerSupport); + .execute(supportService); invokeConflictWatchers((w) -> w.afterAddObject(oid, object)); return oid; /* @@ -424,7 +422,7 @@ RootUpdateContext prepareUpdateContext( rootRow.objectType = MObjectType.fromSchemaType(object.getClass()); // we don't care about full object in row - return new RootUpdateContext<>(transformerSupport, jdbcSession, object, rootRow); + return new RootUpdateContext<>(supportService, jdbcSession, object, rootRow); } private void logTraceModifications(@NotNull Collection> modifications) { @@ -482,8 +480,7 @@ private void logTraceModifications(@NotNull Collection DeleteObjectResult deleteObjectAttempt(Class type, UUID oid, JdbcSession jdbcSession) throws ObjectNotFoundException { - QueryTableMapping mapping = - transformerSupport.sqlRepoContext().getMappingBySchemaType(type); + QueryTableMapping mapping = sqlRepoContext.getMappingBySchemaType(type); Q entityPath = mapping.defaultAlias(); byte[] fullObject = jdbcSession.newQuery() .select(entityPath.fullObject) @@ -520,7 +517,7 @@ public int countObjects(Class type, ObjectQuery query, .build(); try { - var queryContext = SqaleQueryContext.from(type, transformerSupport, sqlRepoContext); + var queryContext = SqaleQueryContext.from(type, supportService, sqlRepoContext); return sqlQueryExecutor.count(queryContext, query, options); } catch (RepositoryException | RuntimeException e) { throw handledGeneralException(e, operationResult); @@ -548,7 +545,7 @@ public int countObjects(Class type, ObjectQuery query, .build(); try { - var queryContext = SqaleQueryContext.from(type, transformerSupport, sqlRepoContext); + var queryContext = SqaleQueryContext.from(type, supportService, sqlRepoContext); SearchResultList result = sqlQueryExecutor.list(queryContext, query, options); // TODO see the commented code from old repo lower, problems for each object must be caught @@ -567,7 +564,7 @@ public int countObjects(Class type, ObjectQuery query, /* TODO from ObjectRetriever, how to do this per-object Throwable catch + record result? - should we smuggle the OperationResult all the way to the transformer call? + should we smuggle the OperationResult all the way to the mapping call? @NotNull private List> queryResultToPrismObjects( List objects, Class type, @@ -631,7 +628,7 @@ public SearchResultList searchContainers( .build(); try { - var queryContext = SqaleQueryContext.from(type, transformerSupport, sqlRepoContext); + var queryContext = SqaleQueryContext.from(type, supportService, sqlRepoContext); SearchResultList result = sqlQueryExecutor.list(queryContext, query, options); return result; diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerSupport.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleSupportService.java similarity index 82% rename from repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerSupport.java rename to repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleSupportService.java index 7674440d99c..8bbde61260c 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerSupport.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleSupportService.java @@ -11,23 +11,23 @@ import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; import com.evolveum.midpoint.schema.SchemaService; import com.evolveum.midpoint.util.QNameUtil; /** - * Extension of {@link SqlTransformerSupport} adding Sqale features like {@link UriCache} support. + * Extension of {@link SqlSupportService} adding Sqale features like {@link UriCache} support. */ -public class SqaleTransformerSupport extends SqlTransformerSupport { +public class SqaleSupportService extends SqlSupportService { - private static SqaleTransformerSupport instance; + private static SqaleSupportService instance; - public SqaleTransformerSupport(SchemaService schemaService, SqaleRepoContext sqaleRepoContext) { + public SqaleSupportService(SchemaService schemaService, SqaleRepoContext sqaleRepoContext) { super(schemaService, sqaleRepoContext); instance = this; } - public static SqaleTransformerSupport getInstance() { + public static SqaleSupportService getInstance() { return instance; } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java index 011dbb6b2d3..7b068645f6b 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java @@ -46,7 +46,7 @@ public void addValues(Collection values) { public void deleteValues(Collection values) { Q r = refTableMapping.defaultAlias(); for (Referencable ref : values) { - Integer relId = context.transformerSupport().searchCachedRelationId(ref.getRelation()); + Integer relId = context.supportService().searchCachedRelationId(ref.getRelation()); context.jdbcSession().newDelete(r) .where(r.isOwnedBy(context.row()) .and(r.targetOid.eq(UUID.fromString(ref.getOid()))) diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java index fff4d6ecdf3..aa63319d799 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java @@ -18,7 +18,7 @@ import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.repo.api.RepoAddOptions; import com.evolveum.midpoint.repo.sqale.ContainerValueIdGenerator; -import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport; +import com.evolveum.midpoint.repo.sqale.SqaleSupportService; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObject; @@ -59,11 +59,11 @@ public AddObjectOperation(@NotNull PrismObject object, } /** Inserts the object provided to the constructor and returns its OID. */ - public String execute(SqaleTransformerSupport transformerSupport) + public String execute(SqaleSupportService supportService) throws SchemaException, ObjectAlreadyExistsException { try { // TODO utilize options and result - sqlRepoContext = transformerSupport.sqlRepoContext(); + sqlRepoContext = supportService.sqlRepoContext(); Class schemaObjectClass = object.getCompileTimeClass(); objectType = MObjectType.fromSchemaType(schemaObjectClass); rootMapping = sqlRepoContext.getMappingBySchemaType(schemaObjectClass); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java index af453912c57..26df02bc71a 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java @@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport; +import com.evolveum.midpoint.repo.sqale.SqaleSupportService; import com.evolveum.midpoint.repo.sqale.delta.item.*; import com.evolveum.midpoint.repo.sqale.filtering.RefItemFilterProcessor; import com.evolveum.midpoint.repo.sqale.filtering.UriItemFilterProcessor; @@ -191,12 +191,6 @@ public > SqaleItemSqlMapper enumMapper( rootToQueryItem); } - // Previously transformer code from here down - // TODO inline later - protected QueryTableMapping mapping() { - return this; - } - @Override public S toSchemaObject(R row) { throw new UnsupportedOperationException("Use toSchemaObject(Tuple,...)"); @@ -238,7 +232,7 @@ protected ObjectReferenceType objectReferenceType( return new ObjectReferenceType() .oid(oid) - .type(SqaleTransformerSupport.getInstance() + .type(SqaleSupportService.getInstance() .schemaClassToQName(repoObjectType.getSchemaType())) .description(targetName) .targetName(targetName); @@ -257,12 +251,12 @@ protected ObjectReferenceType objectReferenceType( } protected @NotNull Integer searchCachedRelationId(QName qName) { - return SqaleTransformerSupport.getInstance().searchCachedRelationId(qName); + return SqaleSupportService.getInstance().searchCachedRelationId(qName); } /** Returns ID for cached URI without going to the database. */ protected Integer resolveUriToId(String uri) { - return SqaleTransformerSupport.getInstance().resolveUriToId(uri); + return SqaleSupportService.getInstance().resolveUriToId(uri); } /** @@ -271,20 +265,20 @@ protected Integer resolveUriToId(String uri) { * Never returns null, returns default ID for configured default relation. */ protected Integer processCacheableRelation(QName qName) { - return SqaleTransformerSupport.getInstance().processCacheableRelation(qName); + return SqaleSupportService.getInstance().processCacheableRelation(qName); } /** Returns ID for URI creating new cache row in DB as needed. */ protected Integer processCacheableUri(String uri) { return uri != null - ? SqaleTransformerSupport.getInstance().processCacheableUri(uri) + ? SqaleSupportService.getInstance().processCacheableUri(uri) : null; } /** Returns ID for URI creating new cache row in DB as needed. */ protected Integer processCacheableUri(QName qName) { return qName != null - ? SqaleTransformerSupport.getInstance() + ? SqaleSupportService.getInstance() .processCacheableUri(QNameUtil.qNameToUri(qName)) : null; } @@ -309,7 +303,7 @@ protected Integer[] processCacheableUris(List uris) { protected MObjectType schemaTypeToObjectType(QName schemaType) { return schemaType == null ? null : MObjectType.fromSchemaType( - SqaleTransformerSupport.getInstance().qNameToSchemaClass(schemaType)); + SqaleSupportService.getInstance().qNameToSchemaClass(schemaType)); } protected void setPolyString(PolyStringType polyString, @@ -347,7 +341,7 @@ protected String[] arrayFor(List strings) { /** Convenient insert shortcut when the row is fully populated. */ protected void insert(R row, JdbcSession jdbcSession) { - jdbcSession.newInsert(mapping().defaultAlias()) + jdbcSession.newInsert(defaultAlias()) .populate(row) .execute(); } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java deleted file mode 100644 index a50f328a136..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale.qmodel; - -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; - -/** - * Declares capability to insert row for the provided schema object owned by provided row. - * - * @param schema type - * @param target type of the transformation, a row bean - * @param row type of the reference owner - */ -public interface TransformerForOwnedBy { - - /** Contract for insertion of row of type {@link R} owned by {@link OR}. */ -} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java index a8da39f7a7d..f6d7928c836 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java @@ -144,7 +144,7 @@ public MAssignment newRowObject(OR ownerRow) { return row; } - // about duplication see the comment in ObjectSqlTransformer.toRowObjectWithoutFullObject + // about duplication see the comment in QObjectMapping.toRowObjectWithoutFullObject @SuppressWarnings("DuplicatedCode") @Override public MAssignment insert(AssignmentType assignment, OR ownerRow, JdbcSession jdbcSession) { diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java index e8d43b9abb4..1c34ee9a277 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java @@ -22,14 +22,14 @@ import com.evolveum.midpoint.prism.PrismConstants; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.SerializationOptions; -import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport; +import com.evolveum.midpoint.repo.sqale.SqaleSupportService; import com.evolveum.midpoint.repo.sqale.SqaleUtils; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentMapping; import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -198,8 +198,8 @@ public S toSchemaObject(Tuple row, Q entityPath, PrismObject prismObject; String serializedForm = new String(fullObject, StandardCharsets.UTF_8); try { - SqlTransformerSupport.ParseResult result = - SqaleTransformerSupport.getInstance().parsePrismObject(serializedForm); + SqlSupportService.ParseResult result = + SqaleSupportService.getInstance().parsePrismObject(serializedForm); prismObject = result.prismObject; if (result.parsingContext.hasWarnings()) { logger.warn("Object {} parsed with {} warnings", @@ -253,7 +253,7 @@ public R toRowObjectWithoutFullObject(S schemaObject, JdbcSession jdbcSession) { // repo.getTextInfoItems().addAll(RObjectTextInfo.createItemsSet(jaxb, repo, repositoryContext)); // TODO extensions stored inline (JSON) - that is ext column - // This is duplicate code with AssignmentSqlTransformer.toRowObject, but making interface + // This is duplicate code with QAssignmentMapping.insert, but making interface // and needed setters (fields are not "interface-able") would create much more code. MetadataType metadata = schemaObject.getMetadata(); if (metadata != null) { @@ -354,7 +354,7 @@ public byte[] createFullObject(S schemaObject) throws SchemaException { "Serialized object must have assigned OID and version: " + schemaObject); } - return SqaleTransformerSupport.getInstance().createStringSerializer() + return SqaleSupportService.getInstance().createStringSerializer() .itemsToSkip(fullObjectItemsToSkip()) .options(SerializationOptions .createSerializeReferenceNamesForNullOids() diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java index d30e5677846..adacfc59bb8 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java @@ -18,7 +18,7 @@ import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy; import com.evolveum.midpoint.repo.sqale.ContainerValueIdGenerator; -import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport; +import com.evolveum.midpoint.repo.sqale.SqaleSupportService; import com.evolveum.midpoint.repo.sqale.SqaleUtils; import com.evolveum.midpoint.repo.sqale.delta.DelegatingItemDeltaProcessor; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; @@ -49,12 +49,12 @@ public class RootUpdateContext, R ext private ContainerValueIdGenerator cidGenerator; - public RootUpdateContext(SqaleTransformerSupport transformerSupport, + public RootUpdateContext(SqaleSupportService supportService, JdbcSession jdbcSession, S object, R rootRow) { - super(transformerSupport, jdbcSession, rootRow); + super(supportService, jdbcSession, rootRow); this.object = object; - mapping = transformerSupport.sqlRepoContext() + mapping = supportService.sqlRepoContext() .getMappingBySchemaType(SqaleUtils.getClass(object)); rootPath = mapping.defaultAlias(); objectVersion = objectVersionAsInt(object); @@ -101,7 +101,7 @@ public QueryTableMapping mapping() { } } - transformerSupport.normalizeAllRelations(prismObject); + supportService.normalizeAllRelations(prismObject); finishExecution(); return modifications; diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java index fd2422fe226..0f419fc2786 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java @@ -14,7 +14,7 @@ import com.evolveum.midpoint.prism.path.ItemName; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport; +import com.evolveum.midpoint.repo.sqale.SqaleSupportService; import com.evolveum.midpoint.repo.sqale.delta.ItemDeltaValueProcessor; import com.evolveum.midpoint.repo.sqale.delta.item.UriItemDeltaProcessor; import com.evolveum.midpoint.repo.sqale.qmodel.QOwnedByMapping; @@ -60,7 +60,7 @@ public abstract class SqaleUpdateContext> subcontexts = new LinkedHashMap<>(); public SqaleUpdateContext( - SqaleTransformerSupport sqlTransformerSupport, + SqaleSupportService supportService, JdbcSession jdbcSession, R row) { - this.transformerSupport = sqlTransformerSupport; + this.supportService = supportService; this.jdbcSession = jdbcSession; this.row = row; @@ -93,21 +93,21 @@ public SqaleUpdateContext( R row) { this.parentContext = parentContext; // registering this with parent context must happen outside of constructor! - this.transformerSupport = parentContext.transformerSupport; + this.supportService = parentContext.supportService; this.jdbcSession = parentContext.jdbcSession(); this.row = row; } - public SqaleTransformerSupport transformerSupport() { - return transformerSupport; + public SqaleSupportService supportService() { + return supportService; } public Integer processCacheableRelation(QName relation) { - return transformerSupport.processCacheableRelation(relation); + return supportService.processCacheableRelation(relation); } public Integer processCacheableUri(String uri) { - return transformerSupport.processCacheableUri(uri); + return supportService.processCacheableUri(uri); } public JdbcSession jdbcSession() { diff --git a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java index 5c4fcca0a18..fe9751bbce5 100644 --- a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java +++ b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java @@ -378,7 +378,7 @@ public void test291DuplicateCidInDifferentContainersIsCaughtByRepo() { // region insertion of various types - // this test covers function of ObjectSqlTransformer and all the basic object fields + // this test covers function of QObjectMapping and all the basic object fields @Test public void test800SystemConfigurationBasicObjectAttributes() throws Exception { OperationResult result = createOperationResult(); @@ -900,7 +900,7 @@ public void test818Shadow() throws Exception { assertThat(row.synchronizationTimestamp).isEqualTo(Instant.ofEpochMilli(2)); } - // This covers mapping of attributes in FocusSqlTransformer + GenericObject. + // This covers mapping of attributes in QFocusMapping + GenericObject. @Test public void test820GenericObject() throws Exception { OperationResult result = createOperationResult(); @@ -975,7 +975,7 @@ public void test820GenericObject() throws Exception { } // This covers mapping of attributes in AbstractRole + Archetype + inducement mapping. - // There is no focus on FocusSqlTransformer that is covered above. + // There is no focus on QFocusMapping that is covered above. @Test public void test821ArchetypeAndInducement() throws Exception { OperationResult result = createOperationResult(); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java index f207ca63f16..11f91808e79 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java @@ -153,7 +153,7 @@ private MAuditEventRecord getAuditEventRecord(int expectedCount, int index) throws QueryException { // "create" does not actually create a new audit service, but returns the existing one SqlRepoContext sqlRepoContext = auditServiceFactory.createAuditService().getSqlRepoContext(); - SqlTransformerSupport transformerSupport = new SqlTransformerSupport(schemaService, sqlRepoContext); + SqlSupportService transformerSupport = new SqlSupportService(schemaService, sqlRepoContext); SqlQueryContext context = AuditSqlQueryContext.from( AuditEventRecordType.class, transformerSupport, sqlRepoContext); diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/BaseSQLRepoTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/BaseSQLRepoTest.java index 488d48bbd60..1898d2735ac 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/BaseSQLRepoTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/BaseSQLRepoTest.java @@ -363,7 +363,7 @@ protected , R> long count( /** Creates new {@link JdbcSession} based on {@link #baseHelper} setup. */ protected JdbcSession createJdbcSession() { - return new SqlRepoContext(baseHelper.getConfiguration(), baseHelper.dataSource(), null) + return new SqlRepoContext(baseHelper.getConfiguration(), baseHelper.dataSource(), schemaService, null) .newJdbcSession(); } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceFactory.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceFactory.java index a77c277647d..3cb7af8244f 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceFactory.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceFactory.java @@ -98,7 +98,7 @@ private SqlRepoContext createSqlRepoContext(Configuration configuration) // in SqlBaseService. Perhaps the base class is useless and these factories can provide // PerformanceMonitor for the services. return new SqlRepoContext(defaultBaseHelper.getConfiguration(), - defaultBaseHelper.dataSource(), auditModelMapping); + defaultBaseHelper.dataSource(), schemaService, auditModelMapping); } LOGGER.info("Configuring SQL audit service to use a different datasource"); @@ -110,7 +110,7 @@ private SqlRepoContext createSqlRepoContext(Configuration configuration) DataSourceFactory dataSourceFactory = new DataSourceFactory(config); DataSource dataSource = dataSourceFactory.createDataSource(); - return new SqlRepoContext(config, dataSource, auditModelMapping); + return new SqlRepoContext(config, dataSource, schemaService, auditModelMapping); } private void initCustomColumns( diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java index 2629cbdac40..e4995e88a30 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java @@ -104,7 +104,7 @@ public class SqlAuditServiceImpl extends SqlBaseService implements AuditService private final SchemaService schemaService; private final SqlQueryExecutor sqlQueryExecutor; - private final SqlTransformerSupport transformerSupport; + private final SqlSupportService transformerSupport; private volatile SystemConfigurationAuditType auditConfiguration; @@ -116,7 +116,7 @@ public SqlAuditServiceImpl( this.sqlRepoContext = sqlRepoContext; this.schemaService = schemaService; this.sqlQueryExecutor = new SqlQueryExecutor(sqlRepoContext); - this.transformerSupport = new SqlTransformerSupport(schemaService, sqlRepoContext); + this.transformerSupport = new SqlSupportService(schemaService, sqlRepoContext); } public SqlRepoContext getSqlRepoContext() { @@ -179,7 +179,7 @@ private Long insertAuditEventRecord( JdbcSession jdbcSession, AuditEventRecord record) { QAuditEventRecordMapping aerMapping = QAuditEventRecordMapping.INSTANCE; QAuditEventRecord aer = aerMapping.defaultAlias(); - MAuditEventRecord aerBean = aerMapping.from(record); + MAuditEventRecord aerBean = aerMapping.toRowObject(record); SQLInsertClause insert = jdbcSession.newInsert(aer).populate(aerBean); Map customColumns = aerMapping.getExtensionColumns(); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java index 7656a79d106..080a52b9c60 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java @@ -10,7 +10,7 @@ import com.evolveum.midpoint.repo.sqlbase.SqlQueryContext; import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; @@ -24,7 +24,7 @@ public class AuditSqlQueryContext, R> // Type parameters the same as in the class documentation. public static , R> AuditSqlQueryContext from( - Class schemaType, SqlTransformerSupport transformerSupport, SqlRepoContext sqlRepoContext) { + Class schemaType, SqlSupportService sqlSupportService, SqlRepoContext sqlRepoContext) { QueryTableMapping rootMapping = sqlRepoContext.getMappingBySchemaType(schemaType); Q rootPath = rootMapping.defaultAlias(); @@ -34,22 +34,22 @@ public static , R> AuditSqlQueryConte query.getMetadata().setValidate(true); return new AuditSqlQueryContext<>( - rootPath, rootMapping, sqlRepoContext, transformerSupport, query); + rootPath, rootMapping, sqlRepoContext, sqlSupportService, query); } private AuditSqlQueryContext( Q entityPath, QueryTableMapping mapping, SqlRepoContext sqlRepoContext, - SqlTransformerSupport transformerSupport, + SqlSupportService sqlSupportService, SQLQuery query) { - super(entityPath, mapping, sqlRepoContext, transformerSupport, query); + super(entityPath, mapping, sqlSupportService, query); } @Override protected , TR> SqlQueryContext deriveNew(TQ newPath, QueryTableMapping newMapping) { return new AuditSqlQueryContext<>( - newPath, newMapping, sqlRepoContext, transformerSupport, sqlQuery); + newPath, newMapping, sqlRepoContext, sqlSupportService, sqlQuery); } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java index 5ce8221f693..3fc847bcc75 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java @@ -14,7 +14,7 @@ import org.jetbrains.annotations.Nullable; import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -63,7 +63,7 @@ protected ObjectReferenceType objectReferenceType( return new ObjectReferenceType() .oid(oid) - .type(SqlTransformerSupport.getInstance() + .type(SqlSupportService.getInstance() .schemaClassToQName(repoObjectType.getJaxbClass())) .description(targetName) .targetName(targetName); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java index 40042910e00..e1b45b5102f 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java @@ -15,7 +15,7 @@ import com.evolveum.midpoint.repo.sql.audit.beans.MAuditDelta; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditDelta; import com.evolveum.midpoint.repo.sql.util.RUtil; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectDeltaOperationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; @@ -45,7 +45,7 @@ protected QAuditDelta newAliasInstance(String alias) { public ObjectDeltaOperationType toSchemaObject(MAuditDelta row) { ObjectDeltaOperationType odo = new ObjectDeltaOperationType(); SQLTemplates querydslTemplates = - SqlTransformerSupport.getInstance().sqlRepoContext().getQuerydslTemplates(); + SqlSupportService.getInstance().sqlRepoContext().getQuerydslTemplates(); boolean usingSqlServer = querydslTemplates instanceof SQLServerTemplates; odo.setObjectDelta(parseBytes(row.delta, usingSqlServer, ObjectDeltaType.class)); @@ -70,7 +70,7 @@ private T parseBytes(byte[] bytes, boolean usingSqlServer, Class clazz) { } try { - return SqlTransformerSupport.getInstance() + return SqlSupportService.getInstance() .createStringParser(RUtil.getSerializedFormFromBytes(bytes, usingSqlServer)) .compat() .parseRealValue(clazz); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java index 04c8fcf0ec4..67e6d7839a4 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java @@ -28,7 +28,7 @@ import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventType; import com.evolveum.midpoint.repo.sql.data.common.enums.ROperationResultStatus; import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport; +import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; import com.evolveum.midpoint.repo.sqlbase.filtering.item.CanonicalItemPathItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.DetailTableItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.EnumOrdinalItemFilterProcessor; @@ -149,7 +149,7 @@ public AuditEventRecordType toSchemaObject(MAuditEventRecord row) { private AuditEventRecordType mapSimpleAttributes(MAuditEventRecord row) { // prismContext in constructor ensures complex type definition - return new AuditEventRecordType(SqlTransformerSupport.getInstance().prismContext()) + return new AuditEventRecordType(SqlSupportService.getInstance().prismContext()) .repoId(row.id) .channel(row.channel) .eventIdentifier(row.eventIdentifier) @@ -194,7 +194,6 @@ private void mapDeltas(AuditEventRecordType record, List deltas) { } } - // the rest of sub-entities do not deserve the dedicated transformer classes (yet) private void mapChangedItems(AuditEventRecordType record, List changedItemPaths) { if (changedItemPaths == null) { return; @@ -275,11 +274,8 @@ private OperationResultStatusType operationResultStatusTypeFromRepo(Integer ordi /** * Transforms {@link AuditEventRecord} to {@link MAuditEventRecord} without any subentities. - *

- * Design notes: Arguably, this code could be in {@link MAuditEventRecord}. - * Also the */ - public MAuditEventRecord from(AuditEventRecord record) { + public MAuditEventRecord toRowObject(AuditEventRecord record) { MAuditEventRecord bean = new MAuditEventRecord(); bean.id = record.getRepoId(); // this better be null if we want to insert bean.eventIdentifier = record.getEventIdentifier(); @@ -330,7 +326,7 @@ public MAuditEventRecord from(AuditEventRecord record) { private Integer targetTypeToRepoOrdinal(PrismReferenceValue targetOwner) { //noinspection rawtypes - Class objectClass = SqlTransformerSupport.getInstance() + Class objectClass = SqlSupportService.getInstance() .qNameToSchemaClass(targetOwner.getTargetType()); //noinspection unchecked return MiscUtil.enumOrdinal(RObjectType.getByJaxbType(objectClass)); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java index a912d94ce62..34898aed5bf 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java @@ -12,7 +12,7 @@ import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditResource; /** - * Mapping for {@link QAuditResource}, no transformation supported. + * Mapping for {@link QAuditResource}. */ public class QAuditResourceMapping extends AuditTableMapping { diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java index d7304ad77d0..ea3df4f487b 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java @@ -28,8 +28,8 @@ import com.evolveum.midpoint.repo.sqlbase.filtering.FilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.ObjectFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; +import com.evolveum.midpoint.repo.sqlbase.mapping.RepositoryMappingException; import com.evolveum.midpoint.repo.sqlbase.mapping.SqlDetailFetchMapper; -import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformationException; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; @@ -74,23 +74,22 @@ public abstract class SqlQueryContext protected final Q entityPath; protected final QueryTableMapping entityPathMapping; protected final SqlRepoContext sqlRepoContext; - protected final SqlTransformerSupport transformerSupport; + protected final SqlSupportService sqlSupportService; protected boolean notFilterUsed = false; - // options stored to modify select clause and also to affect transformation + // options stored to modify select clause and also to affect mapping protected Collection> options; protected SqlQueryContext( Q entityPath, QueryTableMapping mapping, - SqlRepoContext sqlRepoContext, - SqlTransformerSupport transformerSupport, + SqlSupportService sqlSupportService, SQLQuery query) { this.entityPath = entityPath; this.entityPathMapping = mapping; - this.sqlRepoContext = sqlRepoContext; - this.transformerSupport = transformerSupport; + this.sqlSupportService = sqlSupportService; + this.sqlRepoContext = sqlSupportService.sqlRepoContext(); this.sqlQuery = query; } @@ -297,7 +296,7 @@ public PageOf transformToSchemaType(PageOf result) throws SchemaException, QueryException { try { return result.map(row -> entityPathMapping.toSchemaObjectSafe(row, root(), options)); - } catch (SqlTransformationException e) { + } catch (RepositoryMappingException e) { Throwable cause = e.getCause(); if (cause instanceof SchemaException) { throw (SchemaException) cause; @@ -344,20 +343,20 @@ public SqlRepoContext sqlRepoContext() { } public PrismContext prismContext() { - return transformerSupport.prismContext(); + return sqlSupportService.prismContext(); } public Class qNameToSchemaClass(@NotNull QName qName) { - return transformerSupport.qNameToSchemaClass(qName); + return sqlSupportService.qNameToSchemaClass(qName); } public CanonicalItemPath createCanonicalItemPath(@NotNull ItemPath itemPath) { - return transformerSupport.prismContext().createCanonicalItemPath(itemPath); + return sqlSupportService.prismContext().createCanonicalItemPath(itemPath); } @NotNull public QName normalizeRelation(QName qName) { - return transformerSupport.normalizeRelation(qName); + return sqlSupportService.normalizeRelation(qName); } public FilterProcessor createInOidFilter(SqlQueryContext context) { diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryExecutor.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryExecutor.java index 63cb7773667..4476d443838 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryExecutor.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryExecutor.java @@ -68,8 +68,7 @@ public , R> SearchResultList list( result = context.executeQuery(jdbcSession.connection()); } - PageOf map = context.transformToSchemaType(result); - return createSearchResultList(map); + return createSearchResultList(context.transformToSchemaType(result)); } @NotNull diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java index 518d015aadb..f991327184e 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java @@ -22,6 +22,7 @@ import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.repo.sqlbase.querydsl.QuerydslUtils; +import com.evolveum.midpoint.schema.SchemaService; import com.evolveum.midpoint.util.exception.SystemException; /** @@ -31,6 +32,8 @@ */ public class SqlRepoContext { + private static SqlRepoContext instance; + private final JdbcRepositoryConfiguration jdbcRepositoryConfiguration; protected final Configuration querydslConfig; private final QueryModelMappingRegistry mappingRegistry; @@ -39,12 +42,19 @@ public class SqlRepoContext { public SqlRepoContext( JdbcRepositoryConfiguration jdbcRepositoryConfiguration, DataSource dataSource, - QueryModelMappingRegistry mappingRegistry) { + SchemaService schemaService, QueryModelMappingRegistry mappingRegistry) { this.jdbcRepositoryConfiguration = jdbcRepositoryConfiguration; this.querydslConfig = QuerydslUtils.querydslConfiguration( jdbcRepositoryConfiguration.getDatabaseType()); this.mappingRegistry = mappingRegistry; this.dataSource = dataSource; + + // TODO later inject directly into mappers + instance = this; + } + + public static SqlRepoContext getInstance() { + return instance; } public SQLQuery newQuery() { diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerSupport.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlSupportService.java similarity index 88% rename from repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerSupport.java rename to repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlSupportService.java index 9710f9c2643..cabc9e9347a 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerSupport.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlSupportService.java @@ -16,24 +16,26 @@ import com.evolveum.midpoint.util.exception.SchemaException; /** - * Holds various component dependencies that are used during schema to DB transformations. + * Holds various component dependencies that are for query and update contexts and in mappers. * Components can be obtained to execute calls on them, but preferably the needed logic * can be implemented here (better abstraction). + * + * TODO: Unify/merge with SqlRepoContext and let it provide all the "services". */ -public class SqlTransformerSupport { +public class SqlSupportService { - private static SqlTransformerSupport instance; + private static SqlSupportService instance; protected final SchemaService schemaService; protected final SqlRepoContext sqlRepoContext; - public SqlTransformerSupport(SchemaService schemaService, SqlRepoContext sqlRepoContext) { + public SqlSupportService(SchemaService schemaService, SqlRepoContext sqlRepoContext) { this.schemaService = schemaService; this.sqlRepoContext = sqlRepoContext; instance = this; } - public static SqlTransformerSupport getInstance() { + public static SqlSupportService getInstance() { return instance; } diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java index 961282f4912..110f0dd41fc 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java @@ -46,7 +46,6 @@ * The main goal of this type is to map object query conditions and ORDER BY to SQL. * Mappings also takes care of transformation between schema/prism objects and repository objects * (row beans or tuples). - * Objects of various {@link QueryTableMapping} subclasses are factories for the transformer. * * Other important functions of mapping: * @@ -338,7 +337,7 @@ public S toSchemaObjectSafe(Tuple tuple, Q entityPath, try { return toSchemaObject(tuple, entityPath, options); } catch (SchemaException e) { - throw new SqlTransformationException(e); + throw new RepositoryMappingException(e); } } diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformationException.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/RepositoryMappingException.java similarity index 77% rename from repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformationException.java rename to repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/RepositoryMappingException.java index 35028b6b7fb..bec86faba69 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/SqlTransformationException.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/RepositoryMappingException.java @@ -10,9 +10,9 @@ * Runtime exception wrapping other exception that occurred during object transformation * inside mapping (e.g. tuple to schema object). */ -public class SqlTransformationException extends RuntimeException { +public class RepositoryMappingException extends RuntimeException { - public SqlTransformationException(Throwable cause) { + public RepositoryMappingException(Throwable cause) { super(cause); } } From 67b20d298815953cdc29e43e8c17de4d18cfd57b Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Mon, 3 May 2021 13:57:01 +0200 Subject: [PATCH 09/33] improving midscale gui tests initialization --- .../midpoint/gui/MidScaleGuiTest.java | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/gui/admin-gui/src/test/java/com/evolveum/midpoint/gui/MidScaleGuiTest.java b/gui/admin-gui/src/test/java/com/evolveum/midpoint/gui/MidScaleGuiTest.java index 4e0162d1d86..00d2a183076 100644 --- a/gui/admin-gui/src/test/java/com/evolveum/midpoint/gui/MidScaleGuiTest.java +++ b/gui/admin-gui/src/test/java/com/evolveum/midpoint/gui/MidScaleGuiTest.java @@ -9,9 +9,13 @@ import java.io.File; import com.evolveum.midpoint.gui.api.component.MainObjectListPanel; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.web.AbstractGuiIntegrationTest; import com.evolveum.midpoint.web.page.admin.configuration.PageSystemConfiguration; import com.evolveum.midpoint.web.page.admin.server.PageTasks; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; + import org.apache.wicket.request.mapper.parameter.PageParameters; import org.javasimon.Split; import org.javasimon.Stopwatch; @@ -39,33 +43,34 @@ import com.evolveum.midpoint.web.page.self.PageSelfCredentials; import com.evolveum.midpoint.web.page.self.PageSelfDashboard; import com.evolveum.midpoint.web.page.self.PageUserSelfProfile; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AdminGuiConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationsPerformanceInformationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType; -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +//@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @ActiveProfiles("test") @SpringBootTest(classes = TestMidPointSpringApplication.class) -public class MidScaleGuiTest extends AbstractInitializedGuiIntegrationTest implements PerformanceTestMethodMixin { +public class MidScaleGuiTest extends AbstractGuiIntegrationTest implements PerformanceTestMethodMixin { private static final String TEST_DIR = "./src/test/resources/midScale"; - private static final File FILE_ORG_STRUCT = new File(TEST_DIR, "org-struct.xml"); - private static final File FILE_USERS = new File(TEST_DIR, "users.xml"); +// private static final File FILE_ORG_STRUCT = new File(TEST_DIR, "org-struct.xml"); +// private static final File FILE_USERS = new File(TEST_DIR, "users.xml"); private static final int REPETITION_COUNT = 10; + protected PrismObject userAdministrator; + @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { super.initSystem(initTask, initResult); - - importObjectsFromFileNotRaw(FILE_ORG_STRUCT, initTask, initResult); - initResult.computeStatusIfUnknown(); - if (!initResult.isSuccess()) { - System.out.println("init result:\n" + initResult); - } - importObjectsFromFileNotRaw(FILE_USERS, initTask, initResult); + modelService.postInit(initResult); + userAdministrator = repositoryService.getObject(UserType.class, USER_ADMINISTRATOR_OID, null, initResult); + login(userAdministrator); + +// importObjectsFromFileNotRaw(FILE_ORG_STRUCT, initTask, initResult); +// initResult.computeStatusIfUnknown(); +// if (!initResult.isSuccess()) { +// System.out.println("init result:\n" + initResult); +// } +// importObjectsFromFileNotRaw(FILE_USERS, initTask, initResult); modifyObjectReplaceProperty(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), ItemPath.create(SystemConfigurationType.F_ADMIN_GUI_CONFIGURATION, AdminGuiConfigurationType.F_ENABLE_EXPERIMENTAL_FEATURES), From a281fcd7af38ccd8176ed5c4b56779551c3b43bc Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 3 May 2021 16:58:48 +0200 Subject: [PATCH 10/33] Extend parameterized system performance test 1) Replaced restricted (enum) parameterization with flexible one (independent values). This is due to migration from fixed repo objects to ones generated by Velocity. 2) Added new features: target resources, multiple source resources, business/technical roles, assignments, groups. 3) Added reconciliation tasks. --- .../story/sysperf/DetailsOutputFile.java | 4 +- .../story/sysperf/ImportsConfiguration.java | 91 + .../sysperf/RecomputationConfiguration.java | 71 + .../sysperf/ReconciliationsConfiguration.java | 91 + .../story/sysperf/RolesConfiguration.java | 216 +++ .../story/sysperf/SourceInitializer.java | 53 +- .../testing/story/sysperf/SourceVariant.java | 102 -- .../story/sysperf/SourcesConfiguration.java | 151 ++ .../story/sysperf/SummaryOutputFile.java | 13 +- .../story/sysperf/TargetInitializer.java | 33 + .../story/sysperf/TargetsConfiguration.java | 143 ++ .../story/sysperf/TemplateVariant.java | 43 - .../story/sysperf/TestSystemPerformance.java | 325 +++- .../story/sysperf/ThreadingVariant.java | 82 - .../midpoint/testing/story/sysperf/Util.java | 21 + .../story/sysperf/VelocityGenerator.java | 36 + .../system-perf/archetype-basic-user.xml | 14 + .../system-perf/resource-source-ms0020.xml | 363 ---- .../system-perf/resource-source-ms0110.xml | 1535 ----------------- .../system-perf/resource-source.vm.xml | 194 +++ ...urce-ms0002.xml => resource-target.vm.xml} | 92 +- .../system-perf/role-business.vm.xml | 23 + .../resources/system-perf/role-targets.vm.xml | 19 + .../system-perf/role-technical.vm.xml | 59 + .../system-perf/system-configuration.xml | 4 + .../{task-import.xml => task-import.vm.xml} | 17 +- ...sk-recompute.xml => task-recompute.vm.xml} | 10 +- .../system-perf/task-reconciliation.vm.xml | 36 + .../resources/system-perf/template-user.xml | 30 + 29 files changed, 1591 insertions(+), 2280 deletions(-) create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ImportsConfiguration.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RecomputationConfiguration.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ReconciliationsConfiguration.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RolesConfiguration.java delete mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourcesConfiguration.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TargetInitializer.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TargetsConfiguration.java delete mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TemplateVariant.java delete mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/Util.java create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/VelocityGenerator.java create mode 100644 testing/story/src/test/resources/system-perf/archetype-basic-user.xml delete mode 100644 testing/story/src/test/resources/system-perf/resource-source-ms0020.xml delete mode 100644 testing/story/src/test/resources/system-perf/resource-source-ms0110.xml create mode 100644 testing/story/src/test/resources/system-perf/resource-source.vm.xml rename testing/story/src/test/resources/system-perf/{resource-source-ms0002.xml => resource-target.vm.xml} (65%) create mode 100644 testing/story/src/test/resources/system-perf/role-business.vm.xml create mode 100644 testing/story/src/test/resources/system-perf/role-targets.vm.xml create mode 100644 testing/story/src/test/resources/system-perf/role-technical.vm.xml rename testing/story/src/test/resources/system-perf/{task-import.xml => task-import.vm.xml} (72%) rename testing/story/src/test/resources/system-perf/{task-recompute.xml => task-recompute.vm.xml} (85%) create mode 100644 testing/story/src/test/resources/system-perf/task-reconciliation.vm.xml create mode 100644 testing/story/src/test/resources/system-perf/template-user.xml diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java index beadc7ec923..eca72ed5495 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java @@ -21,8 +21,8 @@ class DetailsOutputFile { writer = new PrintWriter(new FileWriter(FILE)); } - void logTestFinish(String testName, TaskType taskAfter, TaskPerformanceInformation performanceInformation) { - writer.printf("********** %s FINISHED **********\n\n", testName); + void logTaskFinish(String desc, TaskType taskAfter, TaskPerformanceInformation performanceInformation) { + writer.printf("********** FINISHED: %s **********\n\n", desc); writer.println(TaskOperationStatsUtil.format(taskAfter.getOperationStats())); writer.println(); writer.println(performanceInformation.debugDump()); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ImportsConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ImportsConfiguration.java new file mode 100644 index 00000000000..8e7077543ab --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ImportsConfiguration.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TARGET_DIR; +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TEST_DIR; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import com.evolveum.midpoint.test.DummyTestResource; +import com.evolveum.midpoint.test.TestResource; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; + +class ImportsConfiguration { + + private static final String PROP = "import"; + private static final String PROP_THREADS = PROP + ".threads"; + private static final String PROP_NO_OP_RUNS = PROP + ".no-op-runs"; + + private static final File TASK_TEMPLATE_FILE = new File(TEST_DIR, "task-import.vm.xml"); + + private final int threads; + private final int noOpRuns; + + private final List> generatedTasks; + + private ImportsConfiguration() { + threads = Integer.parseInt(System.getProperty(PROP_THREADS, "0")); + noOpRuns = Integer.parseInt(System.getProperty(PROP_NO_OP_RUNS, "1")); + + generatedTasks = generateTasks(); + } + + int getThreads() { + return threads; + } + + int getNoOpRuns() { + return noOpRuns; + } + + List> getGeneratedTasks() { + return generatedTasks; + } + + @Override + public String toString() { + return "ImportConfiguration{" + + "threads=" + threads + + ", noOpRuns=" + noOpRuns + + '}'; + } + + public static ImportsConfiguration setup() { + ImportsConfiguration configuration = new ImportsConfiguration(); + System.out.println("Import: " + configuration); + return configuration; + } + + private List> generateTasks() { + List> tasks = new ArrayList<>(); + List sourceResources = TestSystemPerformance.SOURCES_CONFIGURATION.getGeneratedResources(); + for (int i = 0; i < sourceResources.size(); i++) { + String taskOid = UUID.randomUUID().toString(); + tasks.add(new TestResource<>(TARGET_DIR, createFile(i, sourceResources.get(i), taskOid), taskOid)); + } + return tasks; + } + + private String createFile(int index, DummyTestResource resource, String taskOid) { + String generatedFileName = String.format("generated-task-import-%03d.xml", index); + + File generated = new File(TARGET_DIR, generatedFileName); + VelocityGenerator.generate(TASK_TEMPLATE_FILE, generated, + Map.of("taskOid", taskOid, + "index", String.format("%03d", index), + "resourceOid", resource.oid, + "workerThreads", threads)); + + return generatedFileName; + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RecomputationConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RecomputationConfiguration.java new file mode 100644 index 00000000000..84bcee099ea --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RecomputationConfiguration.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TARGET_DIR; +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TEST_DIR; + +import java.io.File; +import java.util.Map; + +import com.evolveum.midpoint.test.TestResource; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; + +class RecomputationConfiguration { + + private static final String PROP = "recompute"; + private static final String PROP_THREADS = PROP + ".threads"; + + private static final File TASK_TEMPLATE_FILE = new File(TEST_DIR, "task-recompute.vm.xml"); + + private static final String RECOMPUTE_TASK_OID = "f5920848-6c8f-4eda-ae26-2b961d6dae1b"; + + private final int threads; + + private final TestResource generatedTask; + + private RecomputationConfiguration() { + threads = Integer.parseInt(System.getProperty(PROP_THREADS, "0")); + generatedTask = generateTask(); + } + + int getThreads() { + return threads; + } + + TestResource getGeneratedTask() { + return generatedTask; + } + + @Override + public String toString() { + return "RecomputeConfiguration{" + + "threads=" + threads + + '}'; + } + + public static RecomputationConfiguration setup() { + RecomputationConfiguration configuration = new RecomputationConfiguration(); + System.out.println("Recompute: " + configuration); + return configuration; + } + + private TestResource generateTask() { + return new TestResource<>(TARGET_DIR, createFile(), RECOMPUTE_TASK_OID); + } + + private String createFile() { + String generatedFileName = "generated-task-recompute.xml"; + + File generated = new File(TARGET_DIR, generatedFileName); + VelocityGenerator.generate(TASK_TEMPLATE_FILE, generated, + Map.of("workerThreads", threads)); + + return generatedFileName; + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ReconciliationsConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ReconciliationsConfiguration.java new file mode 100644 index 00000000000..a6db7659ce5 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ReconciliationsConfiguration.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import com.evolveum.midpoint.test.DummyTestResource; +import com.evolveum.midpoint.test.TestResource; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TARGET_DIR; +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TEST_DIR; + +class ReconciliationsConfiguration { + + private static final String PROP = "reconciliation"; + private static final String PROP_THREADS = PROP + ".threads"; + private static final String PROP_RUNS = PROP + ".runs"; + + private static final File TASK_TEMPLATE_FILE = new File(TEST_DIR, "task-reconciliation.vm.xml"); + + private final int threads; + private final int runs; + + private final List> generatedTasks; + + private ReconciliationsConfiguration() { + threads = Integer.parseInt(System.getProperty(PROP_THREADS, "0")); + runs = Integer.parseInt(System.getProperty(PROP_RUNS, "1")); + + generatedTasks = generateTasks(); + } + + int getThreads() { + return threads; + } + + int getRuns() { + return runs; + } + + List> getGeneratedTasks() { + return generatedTasks; + } + + @Override + public String toString() { + return "ReconciliationsConfiguration{" + + "threads=" + threads + + ", runs=" + runs + + '}'; + } + + public static ReconciliationsConfiguration setup() { + ReconciliationsConfiguration configuration = new ReconciliationsConfiguration(); + System.out.println("Import: " + configuration); + return configuration; + } + + private List> generateTasks() { + List> tasks = new ArrayList<>(); + List sourceResources = TestSystemPerformance.SOURCES_CONFIGURATION.getGeneratedResources(); + for (int i = 0; i < sourceResources.size(); i++) { + String taskOid = UUID.randomUUID().toString(); + tasks.add(new TestResource<>(TARGET_DIR, createFile(i, sourceResources.get(i), taskOid), taskOid)); + } + return tasks; + } + + private String createFile(int index, DummyTestResource resource, String taskOid) { + String generatedFileName = String.format("generated-task-reconciliation-%03d.xml", index); + + File generated = new File(TARGET_DIR, generatedFileName); + VelocityGenerator.generate(TASK_TEMPLATE_FILE, generated, + Map.of("taskOid", taskOid, + "index", String.format("%03d", index), + "resourceOid", resource.oid, + "workerThreads", threads)); + + return generatedFileName; + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RolesConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RolesConfiguration.java new file mode 100644 index 00000000000..25e66572995 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RolesConfiguration.java @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.*; + +import static java.util.Collections.emptyList; + +import java.io.File; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import com.evolveum.midpoint.test.TestResource; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; + +import org.jetbrains.annotations.NotNull; + +class RolesConfiguration { + + private static final String PROP = "roles"; + private static final String PROP_BUSINESS = PROP + ".business"; + private static final String PROP_BUSINESS_COUNT = PROP_BUSINESS + ".count"; + private static final String PROP_TECHNICAL = PROP + ".technical"; + private static final String PROP_TECHNICAL_COUNT = PROP_TECHNICAL + ".count"; + private static final String PROP_ASSIGNMENTS = PROP + ".assignments"; + private static final String PROP_ASSIGNMENTS_COUNT = PROP_ASSIGNMENTS + ".count"; + private static final String PROP_ASSIGNMENTS_MIN = PROP_ASSIGNMENTS + ".min"; + private static final String PROP_ASSIGNMENTS_MAX = PROP_ASSIGNMENTS + ".max"; + private static final String PROP_INDUCEMENTS = PROP + ".inducements"; + private static final String PROP_INDUCEMENTS_COUNT = PROP_INDUCEMENTS + ".count"; + private static final String PROP_INDUCEMENTS_MIN = PROP_INDUCEMENTS + ".min"; + private static final String PROP_INDUCEMENTS_MAX = PROP_INDUCEMENTS + ".max"; + + private static final File BUSINESS_ROLE_TEMPLATE_FILE = new File(TEST_DIR, "role-business.vm.xml"); + private static final File TECHNICAL_ROLE_TEMPLATE_FILE = new File(TEST_DIR, "role-technical.vm.xml"); + + private final int numberOfBusinessRoles; + private final int numberOfTechnicalRoles; + private final int numberOfAssignmentsMin; + private final int numberOfAssignmentsMax; + private final int numberOfInducementsMin; + private final int numberOfInducementsMax; + + private final List> generatedBusinessRoles; + private final List> generatedTechnicalRoles; + + private RolesConfiguration() { + numberOfBusinessRoles = Integer.parseInt(System.getProperty(PROP_BUSINESS_COUNT, "2")); + numberOfTechnicalRoles = Integer.parseInt(System.getProperty(PROP_TECHNICAL_COUNT, "2")); + String assignmentsCount = System.getProperty(PROP_ASSIGNMENTS_COUNT); + if (assignmentsCount != null) { + numberOfAssignmentsMax = numberOfAssignmentsMin = Integer.parseInt(assignmentsCount); + } else { + numberOfAssignmentsMin = Integer.parseInt(System.getProperty(PROP_ASSIGNMENTS_MIN, "1")); + numberOfAssignmentsMax = Integer.parseInt(System.getProperty(PROP_ASSIGNMENTS_MAX, String.valueOf(numberOfAssignmentsMin))); + } + String inducementsCount = System.getProperty(PROP_INDUCEMENTS_COUNT); + if (inducementsCount != null) { + numberOfInducementsMax = numberOfInducementsMin = Integer.parseInt(inducementsCount); + } else { + numberOfInducementsMin = Integer.parseInt(System.getProperty(PROP_INDUCEMENTS_MIN, "1")); + numberOfInducementsMax = Integer.parseInt(System.getProperty(PROP_INDUCEMENTS_MAX, String.valueOf(numberOfInducementsMin))); + } + + generatedTechnicalRoles = generateTechnicalRoles(); + generatedBusinessRoles = generateBusinessRoles(); + } + + int getNumberOfBusinessRoles() { + return numberOfBusinessRoles; + } + + int getNumberOfTechnicalRoles() { + return numberOfTechnicalRoles; + } + + int getNumberOfAssignmentsMin() { + return numberOfAssignmentsMin; + } + + int getNumberOfAssignmentsMax() { + return numberOfAssignmentsMax; + } + + int getNumberOfInducementsMin() { + return numberOfInducementsMin; + } + + int getNumberOfInducementsMax() { + return numberOfInducementsMax; + } + + List> getGeneratedBusinessRoles() { + return generatedBusinessRoles; + } + + List> getGeneratedTechnicalRoles() { + return generatedTechnicalRoles; + } + + @Override + public String toString() { + return "RolesConfiguration{" + + "numberOfBusinessRoles=" + numberOfBusinessRoles + + ", numberOfTechnicalRoles=" + numberOfTechnicalRoles + + ", numberOfAssignmentsMin=" + numberOfAssignmentsMin + + ", numberOfAssignmentsMax=" + numberOfAssignmentsMax + + ", numberOfInducementsMin=" + numberOfInducementsMin + + ", numberOfInducementsMax=" + numberOfInducementsMax + + '}'; + } + + public static RolesConfiguration setup() { + RolesConfiguration configuration = new RolesConfiguration(); + System.out.println("Roles: " + configuration); + return configuration; + } + + private List> generateTechnicalRoles() { + List> roles = new ArrayList<>(); + for (int i = 0; i < numberOfTechnicalRoles; i++) { + String oid = UUID.randomUUID().toString(); + String fileName = createTechnicalRoleDefinition(i, oid); + roles.add(new TestResource<>(TARGET_DIR, fileName, oid)); + } + return roles; + } + + private String createTechnicalRoleDefinition(int index, String oid) { + String fileName = String.format("generated-technical-role-%04d.xml", index); + String resourceOid = TARGETS_CONFIGURATION.getGeneratedResources() + .get(index % TARGETS_CONFIGURATION.getNumberOfResources()) + .oid; + + File generated = new File(TARGET_DIR, fileName); + VelocityGenerator.generate(TECHNICAL_ROLE_TEMPLATE_FILE, generated, + Map.of("oid", oid, + "index", String.format("%04d", index), + "resourceOid", resourceOid)); + + return fileName; + } + + private List> generateBusinessRoles() { + List> roles = new ArrayList<>(); + for (int i = 0; i < numberOfBusinessRoles; i++) { + String oid = UUID.randomUUID().toString(); + List inducedOidList = createInducedOidList(); + String fileName = createBusinessRoleDefinition(i, oid, inducedOidList); + roles.add(new TestResource<>(TARGET_DIR, fileName, oid)); + } + return roles; + } + + private List createInducedOidList() { + int size = randomFromInterval(numberOfInducementsMin, numberOfInducementsMax); + if (size <= 0) { + return emptyList(); + } else { + List technicalRolesOidList = generatedTechnicalRoles.stream() + .map(r -> r.oid) + .collect(Collectors.toList()); + return randomFromList(technicalRolesOidList, size); + } + } + + @NotNull + private List randomFromList(List technicalRolesOidList, int size) { + Collections.shuffle(technicalRolesOidList); + return technicalRolesOidList.subList(0, size); + } + + private int randomFromInterval(int min, int max) { + //noinspection OptionalGetWithoutIsPresent + return new Random() + .ints(min, max + 1) + .findFirst().getAsInt(); + } + + private String createBusinessRoleDefinition(int index, String oid, List inducedOidList) { + String fileName = String.format("generated-business-role-%04d.xml", index); + + File generated = new File(TARGET_DIR, fileName); + VelocityGenerator.generate(BUSINESS_ROLE_TEMPLATE_FILE, generated, + Map.of("oid", oid, + "name", getBusinessRoleName(index), + "inducedOidList", inducedOidList)); + + return fileName; + } + + private String getBusinessRoleName(int index) { + return String.format("business-%04d", index); + } + + /** + * Generates random names of business roles for an account. + */ + List getRolesForAccount() { + int assignedRoles = randomFromInterval(numberOfAssignmentsMin, numberOfAssignmentsMax); + if (assignedRoles == 0) { + return List.of(); + } else { + List businessRolesNames = IntStream.range(0, numberOfBusinessRoles) + .mapToObj(this::getBusinessRoleName) + .collect(Collectors.toList()); + return randomFromList(businessRolesNames, assignedRoles); + } + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceInitializer.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceInitializer.java index 3d0f006426e..a2eabd9a591 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceInitializer.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceInitializer.java @@ -19,52 +19,65 @@ import java.io.FileNotFoundException; import java.net.ConnectException; +import java.util.List; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.ROLES_CONFIGURATION; +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.SOURCES_CONFIGURATION; public class SourceInitializer { private final TestSystemPerformance test; - private final DummyTestResource resource; - private final SourceVariant sourceVariant; - private final PopulationVariant populationVariant; + private final List resources; private final Task initTask; private static final String ACCOUNT_NAME = "u-%08d"; - SourceInitializer(TestSystemPerformance test, DummyTestResource resource, SourceVariant sourceVariant, - PopulationVariant populationVariant, Task initTask) { + SourceInitializer(TestSystemPerformance test, List resources, Task initTask) { this.test = test; - this.resource = resource; - this.sourceVariant = sourceVariant; - this.populationVariant = populationVariant; + this.resources = resources; this.initTask = initTask; } public void run(OperationResult result) throws Exception { - initializeResource(result); - createAccounts(); + boolean primary = true; + for (DummyTestResource resource : resources) { + initializeResource(resource, result); + createAccounts(resource, primary); + primary = false; + } } - private void initializeResource(OperationResult result) throws Exception { + private void initializeResource(DummyTestResource resource, OperationResult result) throws Exception { test.initDummyResource(resource, initTask, result); } - private void createAccounts() throws ConflictException, FileNotFoundException, SchemaViolationException, + private void createAccounts(DummyTestResource resource, boolean primary) + throws ConflictException, FileNotFoundException, SchemaViolationException, ObjectAlreadyExistsException, InterruptedException, ConnectException { - for (int u = 0; u < populationVariant.getAccounts(); u++) { - createAccount(u); + for (int u = 0; u < SOURCES_CONFIGURATION.getNumberOfAccounts(); u++) { + createAccount(u, resource, primary); } } - private void createAccount(int u) throws ObjectAlreadyExistsException, SchemaViolationException, ConnectException, - FileNotFoundException, ConflictException, InterruptedException { + private void createAccount(int u, DummyTestResource resource, boolean primary) + throws ObjectAlreadyExistsException, SchemaViolationException, ConnectException, FileNotFoundException, + ConflictException, InterruptedException { String name = getAccountName(u); DummyAccount account = resource.controller.addAccount(name); - addAttributes(account, SourceVariant.A_SINGLE_NAME, sourceVariant.getSingleValuedAttributes(), 1); - addAttributes(account, SourceVariant.A_MULTI_NAME, sourceVariant.getMultiValuedAttributes(), - sourceVariant.getAttributeValues()); + if (primary) { + addAttributes(account, SourcesConfiguration.A_SINGLE_NAME, SOURCES_CONFIGURATION.getSingleValuedMappings(), 1); + addRoles(account); + } + addAttributes(account, SourcesConfiguration.A_MULTI_NAME, SOURCES_CONFIGURATION.getMultiValuedMappings(), + SOURCES_CONFIGURATION.getAttributeValues()); + } + + private void addRoles(DummyAccount account) throws ConflictException, FileNotFoundException, SchemaViolationException, + InterruptedException, ConnectException { + account.addAttributeValues(SourcesConfiguration.A_ROLE, ROLES_CONFIGURATION.getRolesForAccount()); } - String getAccountName(int u) { + static String getAccountName(int u) { return String.format(ACCOUNT_NAME, u); } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java deleted file mode 100644 index 9ce90c90906..00000000000 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourceVariant.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ - -package com.evolveum.midpoint.testing.story.sysperf; - -import com.evolveum.icf.dummy.resource.ConflictException; -import com.evolveum.icf.dummy.resource.DummyObjectClass; -import com.evolveum.icf.dummy.resource.SchemaViolationException; -import com.evolveum.midpoint.test.DummyResourceContoller; -import com.evolveum.midpoint.test.DummyTestResource; - -import java.io.FileNotFoundException; -import java.net.ConnectException; - -import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TEST_DIR; - -enum SourceVariant { - - MS2_5("ms2-5", "resource-source-ms0002.xml", 1, 1, 5), - MS20_5("ms20-5", "resource-source-ms0020.xml", 10, 10, 5), - MS110_5("ms110-5", "resource-source-ms0110.xml", 100, 10, 5), - MS110_20("ms110-20", "resource-source-ms0110.xml", 100, 10, 20), - MS110_100("ms110-100", "resource-source-ms0110.xml", 100, 10, 100), - MS110_1000("ms110-1000", "resource-source-ms0110.xml", 100, 10, 1000); - - private static final String PROP_SOURCE = "source"; - - public static final String RESOURCE_INSTANCE = "source"; - private static final String RESOURCE_OID = "7eb3a16c-3a33-4ef0-8523-98f0ef7291ba"; - public static final String A_SINGLE_NAME = "a-single-%04d"; - public static final String A_MULTI_NAME = "a-multi-%04d"; - - private final String name; - private final String fileName; - private final int singleValuedAttributes; - private final int multiValuedAttributes; - private final int attributeValues; - - SourceVariant(String name, String fileName, int singleValuedAttributes, int multiValuedAttributes, int attributeValues) { - this.name = name; - this.fileName = fileName; - this.singleValuedAttributes = singleValuedAttributes; - this.multiValuedAttributes = multiValuedAttributes; - this.attributeValues = attributeValues; - } - - public String getName() { - return name; - } - - public String getFileName() { - return fileName; - } - - public int getSingleValuedAttributes() { - return singleValuedAttributes; - } - - public int getMultiValuedAttributes() { - return multiValuedAttributes; - } - - public int getAttributeValues() { - return attributeValues; - } - - public static SourceVariant setup() { - String configuredName = System.getProperty(PROP_SOURCE, MS2_5.name); - SourceVariant sourceVariant = fromName(configuredName); - System.out.println("Source variant: " + sourceVariant); - return sourceVariant; - } - - private static SourceVariant fromName(String name) { - for (SourceVariant value : values()) { - if (value.name.equals(name)) { - return value; - } - } - throw new IllegalArgumentException("Unknown source resource variant: " + name); - } - - public DummyTestResource createDummyTestResource() { - return new DummyTestResource(TEST_DIR, fileName, RESOURCE_OID, RESOURCE_INSTANCE, - controller -> { - createAttributes(controller, A_SINGLE_NAME, singleValuedAttributes, false); - createAttributes(controller, A_MULTI_NAME, multiValuedAttributes, true); - }); - } - - private void createAttributes(DummyResourceContoller controller, String name, int number, boolean multi) - throws ConflictException, FileNotFoundException, SchemaViolationException, InterruptedException, ConnectException { - DummyObjectClass objectClass = controller.getDummyResource().getAccountObjectClass(); - for (int i = 0; i < number; i++) { - controller.addAttrDef(objectClass, String.format(name, i), String.class, false, multi); - } - } -} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourcesConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourcesConfiguration.java new file mode 100644 index 00000000000..7d9c3d15105 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SourcesConfiguration.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import com.evolveum.icf.dummy.resource.ConflictException; +import com.evolveum.icf.dummy.resource.DummyObjectClass; +import com.evolveum.icf.dummy.resource.SchemaViolationException; +import com.evolveum.midpoint.test.DummyResourceContoller; +import com.evolveum.midpoint.test.DummyTestResource; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.FileNotFoundException; +import java.net.ConnectException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TARGET_DIR; +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TEST_DIR; + +import static java.util.Collections.emptyList; + +class SourcesConfiguration { + + private static final String PROP = "sources"; + private static final String PROP_RESOURCES = PROP + ".resources"; + private static final String PROP_ACCOUNTS = PROP + ".accounts"; + private static final String PROP_SINGLE_MAPPINGS = PROP + ".single-mappings"; + private static final String PROP_MULTI_MAPPINGS = PROP + ".multi-mappings"; + private static final String PROP_MULTI_ATTR_VALUES = PROP + ".multi-attr-values"; + + private static final String RESOURCE_INSTANCE_TEMPLATE = "source-%03d"; + static final String A_SINGLE_NAME = "a-single-%04d"; + static final String A_MULTI_NAME = "a-multi-%04d"; + static final String A_ROLE = "role"; + + private static final File RESOURCE_TEMPLATE_FILE = new File(TEST_DIR, "resource-source.vm.xml"); + + private final int numberOfResources; + private final int numberOfAccounts; + private final int singleValuedMappings; + private final int multiValuedMappings; + private final int attributeValues; + + private final List generatedResources; + + private SourcesConfiguration() { + numberOfResources = Integer.parseInt(System.getProperty(PROP_RESOURCES, "1")); + numberOfAccounts = Integer.parseInt(System.getProperty(PROP_ACCOUNTS, "10")); + singleValuedMappings = Integer.parseInt(System.getProperty(PROP_SINGLE_MAPPINGS, "1")); + multiValuedMappings = Integer.parseInt(System.getProperty(PROP_MULTI_MAPPINGS, "1")); + attributeValues = Integer.parseInt(System.getProperty(PROP_MULTI_ATTR_VALUES, "5")); + + generatedResources = generateDummyTestResources(); + } + + int getNumberOfResources() { + return numberOfResources; + } + + public int getNumberOfAccounts() { + return numberOfAccounts; + } + + int getSingleValuedMappings() { + return singleValuedMappings; + } + + int getMultiValuedMappings() { + return multiValuedMappings; + } + + public int getAttributeValues() { + return attributeValues; + } + + List getGeneratedResources() { + return generatedResources; + } + + @Override + public String toString() { + return "SourcesConfiguration{" + + "numberOfResources=" + numberOfResources + + ", numberOfAccounts=" + numberOfAccounts + + ", singleValuedMappings=" + singleValuedMappings + + ", multiValuedMappings=" + multiValuedMappings + + ", attributeValues=" + attributeValues + + '}'; + } + + public static SourcesConfiguration setup() { + SourcesConfiguration configuration = new SourcesConfiguration(); + System.out.println("Sources: " + configuration); + return configuration; + } + + private List generateDummyTestResources() { + List resources = new ArrayList<>(); + for (int i = 0; i < numberOfResources; i++) { + boolean primary = i == 0; + String oid = UUID.randomUUID().toString(); + String resourceDefinitionFile = createResourceDefinition(i, oid, primary); + resources.add(new DummyTestResource(TARGET_DIR, resourceDefinitionFile, oid, getResourceInstance(i), + controller -> { + if (primary) { + createAttributes(controller, A_SINGLE_NAME, singleValuedMappings, false); + controller.addAttrDef(controller.getDummyResource().getAccountObjectClass(), + A_ROLE, String.class, false, true); + } + createAttributes(controller, A_MULTI_NAME, multiValuedMappings, true); + })); + } + return resources; + } + + private String createResourceDefinition(int index, String oid, boolean primary) { + String generatedFileName = String.format("generated-resource-source-%03d.xml", index); + + File generated = new File(TARGET_DIR, generatedFileName); + VelocityGenerator.generate(RESOURCE_TEMPLATE_FILE, generated, + Map.of("resourceOid", oid, + "resourceInstance", getResourceInstance(index), + "multiValuedIndexList", Util.createIndexList(multiValuedMappings), + "singleValuedIndexList", primary ? + Util.createIndexList(singleValuedMappings) : emptyList(), + "primary", primary)); + return generatedFileName; + } + + @NotNull + private String getResourceInstance(int i) { + return String.format(RESOURCE_INSTANCE_TEMPLATE, i); + } + + private void createAttributes(DummyResourceContoller controller, String name, int number, boolean multi) + throws ConflictException, FileNotFoundException, SchemaViolationException, InterruptedException, ConnectException { + DummyObjectClass objectClass = controller.getDummyResource().getAccountObjectClass(); + for (int i = 0; i < number; i++) { + controller.addAttrDef(objectClass, String.format(name, i), String.class, false, multi); + } + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java index 514801ed06b..4eff8fa544b 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java @@ -20,15 +20,18 @@ class SummaryOutputFile { void logStart() { writer.println("Started: " + new Date(START) + " (" + START + ")"); writer.printf("Extension schema variant: %s\n", EXTENSION_SCHEMA_VARIANT); - writer.printf("Source variant: %s\n", SOURCE_VARIANT); - writer.printf("Threading variant: %s\n", THREADING_VARIANT); - writer.printf("Population variant: %s\n", POPULATION_VARIANT); + writer.printf("Sources: %s\n", SOURCES_CONFIGURATION); + writer.printf("Targets: %s\n", TARGETS_CONFIGURATION); + writer.printf("Roles: %s\n", ROLES_CONFIGURATION); + writer.printf("Imports: %s\n", IMPORTS_CONFIGURATION); + writer.printf("Reconciliations: %s\n", RECONCILIATIONS_CONFIGURATION); + writer.printf("Recomputation: %s\n", RECOMPUTATION_CONFIGURATION); writer.printf("Progress file: %s\n\n", ProgressOutputFile.FILE); writer.flush(); } - void logTestFinish(String testName, long executionTime, double timePerAccount) { - writer.printf("********** %s FINISHED **********\n\n", testName); + void logTaskFinish(String desc, long executionTime, double timePerAccount) { + writer.printf("********** FINISHED: %s **********\n\n", desc); writer.printf("Task execution time: %,d ms\n", executionTime); writer.printf("Time per account: %,.1f ms\n\n", timePerAccount); writer.flush(); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TargetInitializer.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TargetInitializer.java new file mode 100644 index 00000000000..10a2fe57036 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TargetInitializer.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import java.util.List; + +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.DummyTestResource; + +public class TargetInitializer { + + private final TestSystemPerformance test; + private final List resources; + private final Task initTask; + + TargetInitializer(TestSystemPerformance test, List resources, Task initTask) { + this.test = test; + this.resources = resources; + this.initTask = initTask; + } + + public void run(OperationResult result) throws Exception { + for (DummyTestResource resource : resources) { + test.initDummyResource(resource, initTask, result); + } + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TargetsConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TargetsConfiguration.java new file mode 100644 index 00000000000..2f4e0b739ec --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TargetsConfiguration.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.net.ConnectException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +import com.evolveum.icf.dummy.resource.DummyGroup; + +import org.jetbrains.annotations.NotNull; + +import com.evolveum.icf.dummy.resource.ConflictException; +import com.evolveum.icf.dummy.resource.DummyObjectClass; +import com.evolveum.icf.dummy.resource.SchemaViolationException; +import com.evolveum.midpoint.test.DummyResourceContoller; +import com.evolveum.midpoint.test.DummyTestResource; + +class TargetsConfiguration { + + private static final String PROP = "targets"; + private static final String PROP_RESOURCES = PROP + ".resources"; + private static final String PROP_SINGLE_MAPPINGS = PROP + ".single-mappings"; + private static final String PROP_MULTI_MAPPINGS = PROP + ".multi-mappings"; + + private static final String RESOURCE_INSTANCE_TEMPLATE = "target-%03d"; + private static final String A_SINGLE_NAME = "a-single-%04d"; + private static final String A_MULTI_NAME = "a-multi-%04d"; + static final String A_MEMBERSHIP = "membership"; + + private static final File RESOURCE_TARGET_TEMPLATE_FILE = new File(TEST_DIR, "resource-target.vm.xml"); + private static final File ROLE_TARGETS_TEMPLATE_FILE = new File(TEST_DIR, "role-targets.vm.xml"); + + private final int numberOfResources; + private final int singleValuedMappings; + private final int multiValuedMappings; + + private final List generatedResources; + + private TargetsConfiguration() { + numberOfResources = Integer.parseInt(System.getProperty(PROP_RESOURCES, "0")); + singleValuedMappings = Integer.parseInt(System.getProperty(PROP_SINGLE_MAPPINGS, "0")); + multiValuedMappings = Integer.parseInt(System.getProperty(PROP_MULTI_MAPPINGS, "0")); + + generatedResources = generateDummyTestResources(); + generateRoleTargets(); + } + + int getSingleValuedMappings() { + return singleValuedMappings; + } + + int getMultiValuedMappings() { + return multiValuedMappings; + } + + int getNumberOfResources() { + return numberOfResources; + } + + public static TargetsConfiguration setup() { + TargetsConfiguration configuration = new TargetsConfiguration(); + System.out.println("Targets: " + configuration); + return configuration; + } + + @Override + public String toString() { + return "TargetsConfiguration{" + + "numberOfResources=" + numberOfResources + + ", singleValuedMappings=" + singleValuedMappings + + ", multiValuedMappings=" + multiValuedMappings + + '}'; + } + + private List generateDummyTestResources() { + List resources = new ArrayList<>(); + for (int i = 0; i < numberOfResources; i++) { + String oid = UUID.randomUUID().toString(); + String resourceDefinitionFile = createResourceDefinition(i, oid); + resources.add(new DummyTestResource(TARGET_DIR, resourceDefinitionFile, oid, getResourceInstance(i), + controller -> { + createAttributes(controller, A_SINGLE_NAME, singleValuedMappings, false); + createAttributes(controller, A_MULTI_NAME, multiValuedMappings, true); + controller.addAttrDef(controller.getDummyResource().getAccountObjectClass(), + A_MEMBERSHIP, String.class, false, true); + controller.addAttrDef(controller.getDummyResource().getGroupObjectClass(), + DummyGroup.ATTR_MEMBERS_NAME, String.class, false, true); + })); + } + return resources; + } + + private String createResourceDefinition(int index, String oid) { + String generatedFileName = String.format("generated-resource-target-%03d.xml", index); + + File generated = new File(TARGET_DIR, generatedFileName); + VelocityGenerator.generate(RESOURCE_TARGET_TEMPLATE_FILE, generated, + Map.of("resourceOid", oid, + "resourceInstance", getResourceInstance(index), + "multiValuedIndexList", Util.createIndexList(multiValuedMappings), + "singleValuedIndexList", Util.createIndexList(singleValuedMappings))); + + return generatedFileName; + } + + @NotNull + private String getResourceInstance(int i) { + return String.format(RESOURCE_INSTANCE_TEMPLATE, i); + } + + private void createAttributes(DummyResourceContoller controller, String name, int number, boolean multi) + throws ConflictException, FileNotFoundException, SchemaViolationException, InterruptedException, ConnectException { + DummyObjectClass objectClass = controller.getDummyResource().getAccountObjectClass(); + for (int i = 0; i < number; i++) { + controller.addAttrDef(objectClass, String.format(name, i), String.class, false, multi); + } + } + + private void generateRoleTargets() { + List targetOidList = generatedResources.stream() + .map(r -> r.oid) + .collect(Collectors.toList()); + VelocityGenerator.generate(ROLE_TARGETS_TEMPLATE_FILE, ROLE_TARGETS.file, + Map.of("oidList", targetOidList)); + } + + List getGeneratedResources() { + return generatedResources; + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TemplateVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TemplateVariant.java deleted file mode 100644 index e969496753e..00000000000 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TemplateVariant.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ - -package com.evolveum.midpoint.testing.story.sysperf; - -enum TemplateVariant { - - NONE("none"), - T0010("t0010"), - T0100("t0100"); - - private static final String PROP_TEMPLATE = "template"; - - private final String name; - - TemplateVariant(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public static TemplateVariant setup() { - String configuredName = System.getProperty(PROP_TEMPLATE, NONE.name); - TemplateVariant variant = fromName(configuredName); - System.out.println("Template variant: " + variant); - return variant; - } - - private static TemplateVariant fromName(String name) { - for (TemplateVariant value : values()) { - if (value.name.equals(name)) { - return value; - } - } - throw new IllegalArgumentException("Unknown template variant: " + name); - } -} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java index ab4b89cf977..7286a2b7855 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java @@ -7,20 +7,24 @@ package com.evolveum.midpoint.testing.story.sysperf; -import static com.evolveum.midpoint.tools.testng.TestMonitor.PERF_REPORT_PREFIX_PROPERTY_NAME; - import static org.assertj.core.api.Assertions.assertThat; +import static com.evolveum.midpoint.test.util.MidPointTestConstants.TARGET_DIR_PATH; +import static com.evolveum.midpoint.tools.testng.TestMonitor.PERF_REPORT_PREFIX_PROPERTY_NAME; + import java.io.File; import java.io.IOException; - -import com.evolveum.midpoint.tools.testng.PerformanceTestClassMixin; -import com.evolveum.midpoint.tools.testng.TestReportSection; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; +import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismObjectDefinition; @@ -36,46 +40,60 @@ import com.evolveum.midpoint.test.TestResource; import com.evolveum.midpoint.test.util.MidPointTestConstants; import com.evolveum.midpoint.testing.story.AbstractStoryTest; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationStatsType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.tools.testng.PerformanceTestClassMixin; +import com.evolveum.midpoint.tools.testng.TestReportSection; +import com.evolveum.midpoint.util.exception.SystemException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; /** * Tests the overall system performance. Can be parameterized using Java properties. * * Examples: * - * -Dpopulation=10k -Dthreading=16t -Dschema=basic -Dsource=ms2-5 - * -Dpopulation=100k -Dthreading=4t -Dschema=indexed -Dsource=ms110-5 - * -Dpopulation=10k -Dthreading=16t -Dschema=basic -Dsource=ms110-1000 + * -Dsources.resources=2 -Dtargets.resources=3 -Droles.business.count=10 -Droles.technical.count=20 -Droles.assignments.count=4 -Droles.inducements.count=5 */ +@SuppressWarnings("BusyWait") @ContextConfiguration(locations = { "classpath:ctx-story-test-main.xml" }) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class TestSystemPerformance extends AbstractStoryTest implements PerformanceTestClassMixin { public static final File TEST_DIR = new File(MidPointTestConstants.TEST_RESOURCES_DIR, "system-perf"); - static final String TARGET_DIR = "./target"; + static final File TARGET_DIR = new File(TARGET_DIR_PATH); private static final File SYSTEM_CONFIGURATION_FILE = new File(TEST_DIR, "system-configuration.xml"); static final ExtensionSchemaVariant EXTENSION_SCHEMA_VARIANT; - static final SourceVariant SOURCE_VARIANT; - static final ThreadingVariant THREADING_VARIANT; - private static final TemplateVariant TEMPLATE_VARIANT; - static final PopulationVariant POPULATION_VARIANT; + static final SourcesConfiguration SOURCES_CONFIGURATION; + static final TargetsConfiguration TARGETS_CONFIGURATION; + static final RolesConfiguration ROLES_CONFIGURATION; + static final ImportsConfiguration IMPORTS_CONFIGURATION; + static final ReconciliationsConfiguration RECONCILIATIONS_CONFIGURATION; + static final RecomputationConfiguration RECOMPUTATION_CONFIGURATION; + private static final OtherParameters OTHER_PARAMETERS; - private static final DummyTestResource RESOURCE_SOURCE; - private static final TestResource TASK_IMPORT; + private static final List RESOURCE_SOURCE_LIST; + private static final List RESOURCE_TARGET_LIST; + + private static final TestResource ARCHETYPE_BASIC_USER = + new TestResource<>(TEST_DIR, "archetype-basic-user.xml", "463e21c5-9959-48e9-bc2a-5356eafb0589"); + + static final TestResource ROLE_TARGETS = new TestResource<>(TARGET_DIR, "generated-role-targets.xml", "3b65aad7-7d6b-412e-bfc7-2cee44d22c32"); + private static final TestResource TEMPLATE_USER = new TestResource<>(TEST_DIR, "template-user.xml", "0c77fde5-4ad5-49ce-8ee9-14f330660d8e"); + + private static final List> BUSINESS_ROLE_LIST; + private static final List> TECHNICAL_ROLE_LIST; + private static final List> TASK_IMPORT_LIST; + private static final List> TASK_RECONCILIATION_LIST; private static final TestResource TASK_RECOMPUTE; static final long START = System.currentTimeMillis(); - private static final String REPORT_FILE_PREFIX = TARGET_DIR + "/" + START + "-report"; + private static final String REPORT_FILE_PREFIX = TARGET_DIR_PATH + "/" + START + "-report"; private static final String REPORT_SECTION_SUMMARY_NAME = "summary"; - private static final String REPORT_SECTION_TEST_SUMMARY_NAME = "testSummary"; + private static final String REPORT_SECTION_TASK_EXECUTION_NAME = "taskExecution"; - private TestReportSection testSummaryReportSection; + private TestReportSection taskExecutionReportSection; private final ProgressOutputFile progressOutputFile = new ProgressOutputFile(); private final SummaryOutputFile summaryOutputFile = new SummaryOutputFile(); @@ -83,19 +101,24 @@ public class TestSystemPerformance extends AbstractStoryTest implements Performa private long lastProgress; - private SourceInitializer sourceInitializer; - static { EXTENSION_SCHEMA_VARIANT = ExtensionSchemaVariant.setup(); - SOURCE_VARIANT = SourceVariant.setup(); - THREADING_VARIANT = ThreadingVariant.setup(); - TEMPLATE_VARIANT = TemplateVariant.setup(); - POPULATION_VARIANT = PopulationVariant.setup(); + SOURCES_CONFIGURATION = SourcesConfiguration.setup(); + TARGETS_CONFIGURATION = TargetsConfiguration.setup(); + ROLES_CONFIGURATION = RolesConfiguration.setup(); + IMPORTS_CONFIGURATION = ImportsConfiguration.setup(); + RECONCILIATIONS_CONFIGURATION = ReconciliationsConfiguration.setup(); + RECOMPUTATION_CONFIGURATION = RecomputationConfiguration.setup(); + OTHER_PARAMETERS = OtherParameters.setup(); - RESOURCE_SOURCE = SOURCE_VARIANT.createDummyTestResource(); - TASK_IMPORT = THREADING_VARIANT.getImportTaskResource(); - TASK_RECOMPUTE = THREADING_VARIANT.getRecomputeTaskResource(); + RESOURCE_SOURCE_LIST = SOURCES_CONFIGURATION.getGeneratedResources(); + RESOURCE_TARGET_LIST = TARGETS_CONFIGURATION.getGeneratedResources(); + BUSINESS_ROLE_LIST = ROLES_CONFIGURATION.getGeneratedBusinessRoles(); + TECHNICAL_ROLE_LIST = ROLES_CONFIGURATION.getGeneratedTechnicalRoles(); + TASK_IMPORT_LIST = IMPORTS_CONFIGURATION.getGeneratedTasks(); + TASK_RECONCILIATION_LIST = RECONCILIATIONS_CONFIGURATION.getGeneratedTasks(); + TASK_RECOMPUTE = RECOMPUTATION_CONFIGURATION.getGeneratedTask(); System.setProperty(PERF_REPORT_PREFIX_PROPERTY_NAME, REPORT_FILE_PREFIX); } @@ -111,11 +134,23 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti InternalsConfig.turnOffAllChecks(); - sourceInitializer = new SourceInitializer(this, RESOURCE_SOURCE, SOURCE_VARIANT, POPULATION_VARIANT, initTask); - sourceInitializer.run(initResult); + new SourceInitializer(this, RESOURCE_SOURCE_LIST, initTask) + .run(initResult); + + new TargetInitializer(this, RESOURCE_TARGET_LIST, initTask) + .run(initResult); + + repoAdd(ARCHETYPE_BASIC_USER, initResult); + repoAdd(ROLE_TARGETS, initResult); + repoAdd(TEMPLATE_USER, initResult); - addObject(TASK_IMPORT.file, initTask, initResult, workerThreadsCustomizer(THREADING_VARIANT.getThreads())); - addObject(TASK_RECOMPUTE.file, initTask, initResult, workerThreadsCustomizer(THREADING_VARIANT.getThreads())); + for (TestResource resource : TECHNICAL_ROLE_LIST) { + addObject(resource, initTask, initResult); // creates resource objects + } + + for (TestResource resource : BUSINESS_ROLE_LIST) { + repoAdd(resource, initResult); + } } @Override @@ -137,29 +172,39 @@ protected void importSystemTasks(OperationResult initResult) { public void test000LogStart() { testMonitor().addReportSection(REPORT_SECTION_SUMMARY_NAME) - .withColumns("schema", "source", "singleValuedAttributes", "multiValuedAttributes", "attributeValues", - "threading", "threads", "tasks", - "population", "accounts") + .withColumns("schema", + "sources", "accounts", "singleValuedInboundMappings", "multiValuedInboundMappings", "attributeValues", + "targets", "singleValuedOutboundMappings", "multiValuedOutboundMappings", + "importTaskThreads", + "reconciliationTaskThreads", + "recomputationTaskThreads") .addRow(EXTENSION_SCHEMA_VARIANT.getName(), - SOURCE_VARIANT.getName(), - SOURCE_VARIANT.getSingleValuedAttributes(), - SOURCE_VARIANT.getMultiValuedAttributes(), - SOURCE_VARIANT.getAttributeValues(), - THREADING_VARIANT.getName(), - THREADING_VARIANT.getThreads(), - THREADING_VARIANT.getTasks(), - POPULATION_VARIANT.getName(), - POPULATION_VARIANT.getAccounts()); + SOURCES_CONFIGURATION.getNumberOfResources(), + SOURCES_CONFIGURATION.getNumberOfAccounts(), + SOURCES_CONFIGURATION.getSingleValuedMappings(), + SOURCES_CONFIGURATION.getMultiValuedMappings(), + SOURCES_CONFIGURATION.getAttributeValues(), + + TARGETS_CONFIGURATION.getNumberOfResources(), + TARGETS_CONFIGURATION.getSingleValuedMappings(), + TARGETS_CONFIGURATION.getMultiValuedMappings(), + + IMPORTS_CONFIGURATION.getThreads(), + RECONCILIATIONS_CONFIGURATION.getThreads(), + RECOMPUTATION_CONFIGURATION.getThreads()); - testSummaryReportSection = testMonitor().addReportSection(REPORT_SECTION_TEST_SUMMARY_NAME) - .withColumns("test", "time", "timePerAccount"); + taskExecutionReportSection = testMonitor().addReportSection(REPORT_SECTION_TASK_EXECUTION_NAME) + .withColumns("task", "time", "timePerAccount"); logger.info("********** STARTED **********\n"); - logger.info("Extension schema variant: {}", EXTENSION_SCHEMA_VARIANT); - logger.info("Source variant: {}", SOURCE_VARIANT); - logger.info("Threading variant: {}", THREADING_VARIANT); - logger.info("Population variant: {}", POPULATION_VARIANT); + logger.info("Extension schema: {}", EXTENSION_SCHEMA_VARIANT); + logger.info("Sources: {}", SOURCES_CONFIGURATION); + logger.info("Targets: {}", TARGETS_CONFIGURATION); + logger.info("Roles: {}", ROLES_CONFIGURATION); + logger.info("Imports: {}", IMPORTS_CONFIGURATION); + logger.info("Reconciliations: {}", RECONCILIATIONS_CONFIGURATION); + logger.info("Recomputation: {}", RECOMPUTATION_CONFIGURATION); logger.info("Progress file: {}", ProgressOutputFile.FILE); summaryOutputFile.logStart(); @@ -181,34 +226,81 @@ public void test100Import() throws Exception { int usersBefore = repositoryService.countObjects(UserType.class, null, null, result); - when(); + for (int taskIndex = 0; taskIndex < TASK_IMPORT_LIST.size(); taskIndex++) { + String importName = "import #" + taskIndex; - restartTask(TASK_IMPORT.oid, result); - Thread.sleep(500); + when(importName); - waitForTaskFinish(TASK_IMPORT.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, - builder -> builder.taskConsumer(this::recordProgress)); + TestResource taskImport = TASK_IMPORT_LIST.get(taskIndex); - then(); + lastProgress = 0; + addTask(taskImport, result); + waitForTaskFinish(taskImport.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, + builder -> builder.taskConsumer(this::recordProgress)); + + then(importName); - int usersAfter = repositoryService.countObjects(UserType.class, null, null, result); - assertThat(usersAfter - usersBefore).as("users created").isEqualTo(POPULATION_VARIANT.getAccounts()); + // Note: after first import the number of users should be constant + int usersAfter = repositoryService.countObjects(UserType.class, null, null, result); + assertThat(usersAfter - usersBefore) + .as("users after " + importName) + .isEqualTo(SOURCES_CONFIGURATION.getNumberOfAccounts()); - assertUserAfterByUsername(sourceInitializer.getAccountName(0)) - .assertLinks(1, 0) + PrismObject taskAfter = assertTask(taskImport.oid, "after") + .display() + .getObject(); + + logTaskFinish(taskAfter, "initial-run-of-"); + } + + String accountName = SourceInitializer.getAccountName(0); + + DummyAccount account = RESOURCE_SOURCE_LIST.get(0).controller.getDummyResource().getAccountByUsername(accountName); + Set roles = account.getAttributeValues(SourcesConfiguration.A_ROLE, String.class); + displayValue("Roles for " + accountName, roles); + + Set memberships = RESOURCE_TARGET_LIST.stream() + .flatMap(r -> getMemberships(accountName, r).stream()) + .collect(Collectors.toSet()); + displayValue("Memberships for " + accountName, memberships); + + Set technicalRoles = memberships.stream() + .map(this::getTechnicalRoleName) + .collect(Collectors.toSet()); + displayValue("Technical roles for " + accountName, technicalRoles); + + assertUserAfterByUsername(accountName) + .assertAssignments(roles.size() + 1) // 1. archetype + .assertRoleMemberhipRefs(roles.size() + technicalRoles.size() + 2) // 1. archetype, 2. role-targets + .assertLinks(SOURCES_CONFIGURATION.getNumberOfResources() + TARGETS_CONFIGURATION.getNumberOfResources(), 0) .extension() - .assertSize(SOURCE_VARIANT.getSingleValuedAttributes() + SOURCE_VARIANT.getMultiValuedAttributes()) + .assertSize(SOURCES_CONFIGURATION.getSingleValuedMappings() + SOURCES_CONFIGURATION.getMultiValuedMappings()) .property(ItemPath.create(getSingleValuedPropertyName(0))) .assertSize(1) .end() .property(ItemPath.create(getMultiValuedPropertyName(0))) - .assertSize(SOURCE_VARIANT.getAttributeValues()); + .assertSize(SOURCES_CONFIGURATION.getAttributeValues() * SOURCES_CONFIGURATION.getNumberOfResources()) + .end() + .end(); + } - PrismObject taskAfter = assertTask(TASK_IMPORT.oid, "after") - .display() - .getObject(); + private String getTechnicalRoleName(String membership) { + Matcher matcher = Pattern.compile("business-[0-9]+-(technical-[0-9]+)").matcher(membership); + if (matcher.matches()) { + return matcher.group(1); + } else { + return null; + } + } - logTestFinish(taskAfter); + private Set getMemberships(String accountName, DummyTestResource r) { + try { + return r.controller.getDummyResource() + .getAccountByUsername(accountName) + .getAttributeValues(TargetsConfiguration.A_MEMBERSHIP, String.class); + } catch (Exception e) { + throw new SystemException(e); + } } @Test @@ -220,40 +312,83 @@ public void test110ImportAgain() throws Exception { int usersBefore = repositoryService.countObjects(UserType.class, null, null, result); - when(); + for (int retry = 0; retry < IMPORTS_CONFIGURATION.getNoOpRuns(); retry++) { + for (int taskIndex = 0; taskIndex < TASK_IMPORT_LIST.size(); taskIndex++) { + String importName = String.format("re-import #%d of resource #%d", retry, taskIndex); - restartTask(TASK_IMPORT.oid, result); - Thread.sleep(500); + when(importName); - lastProgress = 0; - waitForTaskFinish(TASK_IMPORT.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, - builder -> builder.taskConsumer(this::recordProgress)); + TestResource taskImport = TASK_IMPORT_LIST.get(taskIndex); - then(); + lastProgress = 0; + restartTask(taskImport.oid, result); + Thread.sleep(500); - int usersAfter = repositoryService.countObjects(UserType.class, null, null, result); - assertThat(usersAfter - usersBefore).as("users created").isEqualTo(0); + waitForTaskFinish(taskImport.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, + builder -> builder.taskConsumer(this::recordProgress)); - PrismObject taskAfter = assertTask(TASK_IMPORT.oid, "after") - .display() - .getObject(); + then(importName); + + int usersAfter = repositoryService.countObjects(UserType.class, null, null, result); + assertThat(usersAfter - usersBefore).as("users created").isEqualTo(0); - logTestFinish(taskAfter); + PrismObject taskAfter = assertTask(taskImport.oid, "after") + .display() + .getObject(); + + logTaskFinish(taskAfter, String.format("no-op-run-%d-of-", retry+1)); + } + } } @Test - public void test120RecomputeUsers() throws Exception { + public void test120Reconciliation() throws Exception { given(); Task task = getTestTask(); OperationResult result = task.getResult(); - when(); + for (int run = 0; run < RECONCILIATIONS_CONFIGURATION.getRuns(); run++) { + for (int taskIndex = 0; taskIndex < TASK_RECONCILIATION_LIST.size(); taskIndex++) { + String importName = String.format("reconciliation #%d of resource #%d", run, taskIndex); + + when(importName); - restartTask(TASK_RECOMPUTE.oid, result); - Thread.sleep(500); + TestResource reconTask = TASK_RECONCILIATION_LIST.get(taskIndex); + + lastProgress = 0; + if (run == 0) { + addTask(reconTask, result); + } else { + restartTask(reconTask.oid, result); + Thread.sleep(500); + } + + waitForTaskFinish(reconTask.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, + builder -> builder.taskConsumer(this::recordProgress)); + + then(importName); + + PrismObject taskAfter = assertTask(reconTask.oid, "after") + .display() + .getObject(); + + logTaskFinish(taskAfter, String.format("recon-run-%d-of-", run+1)); + } + } + } + + @Test + public void test130RecomputeUsers() throws Exception { + given(); + + Task task = getTestTask(); + OperationResult result = task.getResult(); + + when(); lastProgress = 0; + addTask(TASK_RECOMPUTE, result); waitForTaskFinish(TASK_RECOMPUTE.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, builder -> builder.taskConsumer(this::recordProgress)); @@ -263,7 +398,7 @@ public void test120RecomputeUsers() throws Exception { .display() .getObject(); - logTestFinish(taskAfter); + logTaskFinish(taskAfter, ""); } private long getExecutionTime(PrismObject taskAfter) { @@ -282,24 +417,24 @@ private String getMultiValuedPropertyName(int i) { return String.format("p-multi-%04d", i); } - private void logTestFinish(PrismObject taskAfter) { + private void logTaskFinish(PrismObject taskAfter, String label) { + String desc = label + taskAfter.getName().getOrig(); + TaskPerformanceInformation performanceInformation = TaskPerformanceInformation.fromTaskTree(taskAfter.asObjectable()); long executionTime = getExecutionTime(taskAfter); - double timePerAccount = (double) executionTime / (double) POPULATION_VARIANT.getAccounts(); - - String testName = getTestNameShort(); + double timePerAccount = (double) executionTime / (double) SOURCES_CONFIGURATION.getNumberOfAccounts(); - logger.info("********** {} FINISHED **********\n", testName); + logger.info("********** FINISHED: {} **********\n", desc); logger.info(String.format("Task execution time: %,d ms", executionTime)); logger.info(String.format("Time per account: %,.1f ms", timePerAccount)); logger.info(TaskOperationStatsUtil.format(taskAfter.asObjectable().getOperationStats())); logger.info(performanceInformation.debugDump()); - summaryOutputFile.logTestFinish(testName, executionTime, timePerAccount); - detailsOutputFile.logTestFinish(testName, taskAfter.asObjectable(), performanceInformation); + summaryOutputFile.logTaskFinish(desc, executionTime, timePerAccount); + detailsOutputFile.logTaskFinish(desc, taskAfter.asObjectable(), performanceInformation); - testSummaryReportSection - .addRow(testName, executionTime, timePerAccount); + taskExecutionReportSection + .addRow(desc, executionTime, timePerAccount); } private void recordProgress(Task task) { diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java deleted file mode 100644 index cf5b0f368f0..00000000000 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ThreadingVariant.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ - -package com.evolveum.midpoint.testing.story.sysperf; - -import com.evolveum.midpoint.test.TestResource; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; - -import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TEST_DIR; - -enum ThreadingVariant { - - T1("1t", "", 1, 1), - T4("4t", "", 4, 1), - T6("6t", "", 6, 1), - T8("8t", "", 8, 1), - T12("12t", "", 12, 1), - T16("16t", "", 16, 1), - T40_N4("40t-4n", "", 40, 4); - - private static final String PROP_THREADING = "threading"; - - private static final String IMPORT_TASK_OID = "c32d4da6-bdd3-481d-931a-60ca8a5a01ba"; - private static final String IMPORT_TASK_FILE_NAME_PATTERN = "task-import%s.xml"; - - private static final String RECOMPUTE_TASK_OID = "f5920848-6c8f-4eda-ae26-2b961d6dae1b"; - private static final String RECOMPUTE_TASK_FILE_NAME_PATTERN = "task-recompute%s.xml"; - - private final String name; - private final String taskNameSuffix; - private final int threads; - private final int tasks; - - ThreadingVariant(String name, String taskNameSuffix, int threads, int tasks) { - this.name = name; - this.taskNameSuffix = taskNameSuffix; - this.threads = threads; - this.tasks = tasks; - } - - public String getName() { - return name; - } - - public int getThreads() { - return threads; - } - - public int getTasks() { - return tasks; - } - - public static ThreadingVariant setup() { - String configuredName = System.getProperty(PROP_THREADING, T1.name); - ThreadingVariant variant = fromName(configuredName); - System.out.println("Threading variant: " + variant); - return variant; - } - - public TestResource getImportTaskResource() { - String fileName = String.format(IMPORT_TASK_FILE_NAME_PATTERN, taskNameSuffix); - return new TestResource<>(TEST_DIR, fileName, IMPORT_TASK_OID); - } - - public TestResource getRecomputeTaskResource() { - String fileName = String.format(RECOMPUTE_TASK_FILE_NAME_PATTERN, taskNameSuffix); - return new TestResource<>(TEST_DIR, fileName, RECOMPUTE_TASK_OID); - } - - private static ThreadingVariant fromName(String name) { - for (ThreadingVariant value : values()) { - if (value.name.equals(name)) { - return value; - } - } - throw new IllegalArgumentException("Unknown threading variant: " + name); - } -} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/Util.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/Util.java new file mode 100644 index 00000000000..84dc1ef9c87 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/Util.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +class Util { + + static List createIndexList(int count) { + return IntStream.range(0, count) + .mapToObj(i -> String.format("%04d", i)) + .collect(Collectors.toList()); + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/VelocityGenerator.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/VelocityGenerator.java new file mode 100644 index 00000000000..f147966831f --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/VelocityGenerator.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Map; + +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; + +import com.evolveum.midpoint.util.exception.SystemException; + +public class VelocityGenerator { + + public static void generate(File templateFile, File outputFile, Map parameters) { + + VelocityContext ctx = new VelocityContext(); + parameters.forEach(ctx::put); + try { + try (FileWriter writer = new FileWriter(outputFile); + FileReader reader = new FileReader(templateFile)) { + Velocity.evaluate(ctx, writer, "", reader); + } + } catch (IOException e) { + throw new SystemException(e); + } + } +} diff --git a/testing/story/src/test/resources/system-perf/archetype-basic-user.xml b/testing/story/src/test/resources/system-perf/archetype-basic-user.xml new file mode 100644 index 00000000000..552dcfb8098 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/archetype-basic-user.xml @@ -0,0 +1,14 @@ + + + + basic-user + + + + \ No newline at end of file diff --git a/testing/story/src/test/resources/system-perf/resource-source-ms0020.xml b/testing/story/src/test/resources/system-perf/resource-source-ms0020.xml deleted file mode 100644 index 147f561b878..00000000000 --- a/testing/story/src/test/resources/system-perf/resource-source-ms0020.xml +++ /dev/null @@ -1,363 +0,0 @@ - - - - - - Dummy Resource - - - - - connectorType - com.evolveum.icf.dummy.connector.DummyConnector - - - connectorVersion - 2.0 - - - - - - - source - - - false - false - false - - - - - account - default - Default Account - true - ri:AccountObjectClass - - icfs:name - - - name - - - - - ri:a-single-0000 - - - - - - extension/p-single-0000 - - - - - ri:a-single-0001 - - - - - - extension/p-single-0001 - - - - - ri:a-single-0002 - - - - - - extension/p-single-0002 - - - - - ri:a-single-0003 - - - - - - extension/p-single-0003 - - - - - ri:a-single-0004 - - - - - - extension/p-single-0004 - - - - - ri:a-single-0005 - - - - - - extension/p-single-0005 - - - - - ri:a-single-0006 - - - - - - extension/p-single-0006 - - - - - ri:a-single-0007 - - - - - - extension/p-single-0007 - - - - - ri:a-single-0008 - - - - - - extension/p-single-0008 - - - - - ri:a-single-0009 - - - - - - extension/p-single-0009 - - - - - ri:a-multi-0000 - - - - - - extension/p-multi-0000 - - - - - ri:a-multi-0001 - - - - - - extension/p-multi-0001 - - - - - ri:a-multi-0002 - - - - - - extension/p-multi-0002 - - - - - ri:a-multi-0003 - - - - - - extension/p-multi-0003 - - - - - ri:a-multi-0004 - - - - - - extension/p-multi-0004 - - - - - ri:a-multi-0005 - - - - - - extension/p-multi-0005 - - - - - ri:a-multi-0006 - - - - - - extension/p-multi-0006 - - - - - ri:a-multi-0007 - - - - - - extension/p-multi-0007 - - - - - ri:a-multi-0008 - - - - - - extension/p-multi-0008 - - - - - ri:a-multi-0009 - - - - - - extension/p-multi-0009 - - - - - - - - - ri:AccountObjectClass - account - true - - - name - - $projection/attributes/icfs:name - - - - - linked - true - - - deleted - true - - http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink - - - - unlinked - true - - http://midpoint.evolveum.com/xml/ns/public/model/action-3#link - - - - unmatched - true - - http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus - - - - - diff --git a/testing/story/src/test/resources/system-perf/resource-source-ms0110.xml b/testing/story/src/test/resources/system-perf/resource-source-ms0110.xml deleted file mode 100644 index ae0e929ecc7..00000000000 --- a/testing/story/src/test/resources/system-perf/resource-source-ms0110.xml +++ /dev/null @@ -1,1535 +0,0 @@ - - - - - - Dummy Resource - - - - - connectorType - com.evolveum.icf.dummy.connector.DummyConnector - - - connectorVersion - 2.0 - - - - - - - source - - - false - false - false - - - - - account - default - Default Account - true - ri:AccountObjectClass - - icfs:name - - - name - - - - - ri:a-single-0000 - - - - - - extension/p-single-0000 - - - - - ri:a-single-0001 - - - - - - extension/p-single-0001 - - - - - ri:a-single-0002 - - - - - - extension/p-single-0002 - - - - - ri:a-single-0003 - - - - - - extension/p-single-0003 - - - - - ri:a-single-0004 - - - - - - extension/p-single-0004 - - - - - ri:a-single-0005 - - - - - - extension/p-single-0005 - - - - - ri:a-single-0006 - - - - - - extension/p-single-0006 - - - - - ri:a-single-0007 - - - - - - extension/p-single-0007 - - - - - ri:a-single-0008 - - - - - - extension/p-single-0008 - - - - - ri:a-single-0009 - - - - - - extension/p-single-0009 - - - - - ri:a-single-0010 - - - - - - extension/p-single-0010 - - - - - ri:a-single-0011 - - - - - - extension/p-single-0011 - - - - - ri:a-single-0012 - - - - - - extension/p-single-0012 - - - - - ri:a-single-0013 - - - - - - extension/p-single-0013 - - - - - ri:a-single-0014 - - - - - - extension/p-single-0014 - - - - - ri:a-single-0015 - - - - - - extension/p-single-0015 - - - - - ri:a-single-0016 - - - - - - extension/p-single-0016 - - - - - ri:a-single-0017 - - - - - - extension/p-single-0017 - - - - - ri:a-single-0018 - - - - - - extension/p-single-0018 - - - - - ri:a-single-0019 - - - - - - extension/p-single-0019 - - - - - ri:a-single-0020 - - - - - - extension/p-single-0020 - - - - - ri:a-single-0021 - - - - - - extension/p-single-0021 - - - - - ri:a-single-0022 - - - - - - extension/p-single-0022 - - - - - ri:a-single-0023 - - - - - - extension/p-single-0023 - - - - - ri:a-single-0024 - - - - - - extension/p-single-0024 - - - - - ri:a-single-0025 - - - - - - extension/p-single-0025 - - - - - ri:a-single-0026 - - - - - - extension/p-single-0026 - - - - - ri:a-single-0027 - - - - - - extension/p-single-0027 - - - - - ri:a-single-0028 - - - - - - extension/p-single-0028 - - - - - ri:a-single-0029 - - - - - - extension/p-single-0029 - - - - - ri:a-single-0030 - - - - - - extension/p-single-0030 - - - - - ri:a-single-0031 - - - - - - extension/p-single-0031 - - - - - ri:a-single-0032 - - - - - - extension/p-single-0032 - - - - - ri:a-single-0033 - - - - - - extension/p-single-0033 - - - - - ri:a-single-0034 - - - - - - extension/p-single-0034 - - - - - ri:a-single-0035 - - - - - - extension/p-single-0035 - - - - - ri:a-single-0036 - - - - - - extension/p-single-0036 - - - - - ri:a-single-0037 - - - - - - extension/p-single-0037 - - - - - ri:a-single-0038 - - - - - - extension/p-single-0038 - - - - - ri:a-single-0039 - - - - - - extension/p-single-0039 - - - - - - ri:a-single-0040 - - - - - - extension/p-single-0040 - - - - - ri:a-single-0041 - - - - - - extension/p-single-0041 - - - - - ri:a-single-0042 - - - - - - extension/p-single-0042 - - - - - ri:a-single-0043 - - - - - - extension/p-single-0043 - - - - - ri:a-single-0044 - - - - - - extension/p-single-0044 - - - - - ri:a-single-0045 - - - - - - extension/p-single-0045 - - - - - ri:a-single-0046 - - - - - - extension/p-single-0046 - - - - - ri:a-single-0047 - - - - - - extension/p-single-0047 - - - - - ri:a-single-0048 - - - - - - extension/p-single-0048 - - - - - ri:a-single-0049 - - - - - - extension/p-single-0049 - - - - - - ri:a-single-0050 - - - - - - extension/p-single-0050 - - - - - ri:a-single-0051 - - - - - - extension/p-single-0051 - - - - - ri:a-single-0052 - - - - - - extension/p-single-0052 - - - - - ri:a-single-0053 - - - - - - extension/p-single-0053 - - - - - ri:a-single-0054 - - - - - - extension/p-single-0054 - - - - - ri:a-single-0055 - - - - - - extension/p-single-0055 - - - - - ri:a-single-0056 - - - - - - extension/p-single-0056 - - - - - ri:a-single-0057 - - - - - - extension/p-single-0057 - - - - - ri:a-single-0058 - - - - - - extension/p-single-0058 - - - - - ri:a-single-0059 - - - - - - extension/p-single-0059 - - - - - ri:a-single-0060 - - - - - - extension/p-single-0060 - - - - - ri:a-single-0061 - - - - - - extension/p-single-0061 - - - - - ri:a-single-0062 - - - - - - extension/p-single-0062 - - - - - ri:a-single-0063 - - - - - - extension/p-single-0063 - - - - - ri:a-single-0064 - - - - - - extension/p-single-0064 - - - - - ri:a-single-0065 - - - - - - extension/p-single-0065 - - - - - ri:a-single-0066 - - - - - - extension/p-single-0066 - - - - - ri:a-single-0067 - - - - - - extension/p-single-0067 - - - - - ri:a-single-0068 - - - - - - extension/p-single-0068 - - - - - ri:a-single-0069 - - - - - - extension/p-single-0069 - - - - - ri:a-single-0070 - - - - - - extension/p-single-0070 - - - - - ri:a-single-0071 - - - - - - extension/p-single-0071 - - - - - ri:a-single-0072 - - - - - - extension/p-single-0072 - - - - - ri:a-single-0073 - - - - - - extension/p-single-0073 - - - - - ri:a-single-0074 - - - - - - extension/p-single-0074 - - - - - ri:a-single-0075 - - - - - - extension/p-single-0075 - - - - - ri:a-single-0076 - - - - - - extension/p-single-0076 - - - - - ri:a-single-0077 - - - - - - extension/p-single-0077 - - - - - ri:a-single-0078 - - - - - - extension/p-single-0078 - - - - - ri:a-single-0079 - - - - - - extension/p-single-0079 - - - - - ri:a-single-0080 - - - - - - extension/p-single-0080 - - - - - ri:a-single-0081 - - - - - - extension/p-single-0081 - - - - - ri:a-single-0082 - - - - - - extension/p-single-0082 - - - - - ri:a-single-0083 - - - - - - extension/p-single-0083 - - - - - ri:a-single-0084 - - - - - - extension/p-single-0084 - - - - - ri:a-single-0085 - - - - - - extension/p-single-0085 - - - - - ri:a-single-0086 - - - - - - extension/p-single-0086 - - - - - ri:a-single-0087 - - - - - - extension/p-single-0087 - - - - - ri:a-single-0088 - - - - - - extension/p-single-0088 - - - - - ri:a-single-0089 - - - - - - extension/p-single-0089 - - - - - ri:a-single-0090 - - - - - - extension/p-single-0090 - - - - - ri:a-single-0091 - - - - - - extension/p-single-0091 - - - - - ri:a-single-0092 - - - - - - extension/p-single-0092 - - - - - ri:a-single-0093 - - - - - - extension/p-single-0093 - - - - - ri:a-single-0094 - - - - - - extension/p-single-0094 - - - - - ri:a-single-0095 - - - - - - extension/p-single-0095 - - - - - ri:a-single-0096 - - - - - - extension/p-single-0096 - - - - - ri:a-single-0097 - - - - - - extension/p-single-0097 - - - - - ri:a-single-0098 - - - - - - extension/p-single-0098 - - - - - ri:a-single-0099 - - - - - - extension/p-single-0099 - - - - - ri:a-multi-0000 - - - - - - extension/p-multi-0000 - - - - - ri:a-multi-0001 - - - - - - extension/p-multi-0001 - - - - - ri:a-multi-0002 - - - - - - extension/p-multi-0002 - - - - - ri:a-multi-0003 - - - - - - extension/p-multi-0003 - - - - - ri:a-multi-0004 - - - - - - extension/p-multi-0004 - - - - - ri:a-multi-0005 - - - - - - extension/p-multi-0005 - - - - - ri:a-multi-0006 - - - - - - extension/p-multi-0006 - - - - - ri:a-multi-0007 - - - - - - extension/p-multi-0007 - - - - - ri:a-multi-0008 - - - - - - extension/p-multi-0008 - - - - - ri:a-multi-0009 - - - - - - extension/p-multi-0009 - - - - - - - - - ri:AccountObjectClass - account - true - - - name - - $projection/attributes/icfs:name - - - - - linked - true - - - deleted - true - - http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink - - - - unlinked - true - - http://midpoint.evolveum.com/xml/ns/public/model/action-3#link - - - - unmatched - true - - http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus - - - - - diff --git a/testing/story/src/test/resources/system-perf/resource-source.vm.xml b/testing/story/src/test/resources/system-perf/resource-source.vm.xml new file mode 100644 index 00000000000..dc1082e6aa1 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/resource-source.vm.xml @@ -0,0 +1,194 @@ + + + + + + + + $resourceInstance + + + + + connectorType + com.evolveum.icf.dummy.connector.DummyConnector + + + connectorVersion + 2.0 + + + + + + + $resourceInstance + + + false + false + false + + + + + account + default + Default Account + true + ri:AccountObjectClass + + icfs:name + + + name + + + + + + ArchetypeType + 463e21c5-9959-48e9-bc2a-5356eafb0589 + + + + assignment + + + +#foreach($index in $singleValuedIndexList) + + ri:a-single-$index + + + + + + extension/p-single-$index + + + +#end +#foreach($index in $multiValuedIndexList) + + ri:a-multi-$index + + + + + + extension/p-multi-$index + + + + + + + + +#end +#if($primary) + + ri:role + + + + RoleType + + + polyStringNorm + c:name + + + + + + + auto-business-role + + + + + assignment + + + + + + + + +#end + + + + + + ri:AccountObjectClass + account + true + + + name + + $projection/attributes/icfs:name + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + diff --git a/testing/story/src/test/resources/system-perf/resource-source-ms0002.xml b/testing/story/src/test/resources/system-perf/resource-target.vm.xml similarity index 65% rename from testing/story/src/test/resources/system-perf/resource-source-ms0002.xml rename to testing/story/src/test/resources/system-perf/resource-target.vm.xml index ac76a8f97c8..8b2cf2ebee1 100644 --- a/testing/story/src/test/resources/system-perf/resource-source-ms0002.xml +++ b/testing/story/src/test/resources/system-perf/resource-target.vm.xml @@ -6,7 +6,15 @@ ~ and European Union Public License. See LICENSE file for details. --> -attribute mappings (e.g. 0000, 0001, ...) + - singleValuedIndexList: list of formatted indices of single-valued property->attribute mappings (e.g. 0000, 0001, ...) +--> + + - Dummy Resource + $resourceInstance @@ -34,7 +42,7 @@ - source + $resourceInstance false @@ -51,39 +59,75 @@ ri:AccountObjectClass icfs:name - - + + name - - + + +#foreach($index in $singleValuedIndexList) - ri:a-single-0000 - + ri:a-single-$index + + + extension/p-single-$index + - - extension/p-single-0000 - - + +#end +#foreach($index in $multiValuedIndexList) - ri:a-multi-0000 - + ri:a-multi-$index + + + extension/p-multi-$index + - - extension/p-multi-0000 - - + + +#end + + + ri:membership + + + + + ri:group + true + entitlement + group + objectToSubject + ri:members + icfs:name + + + + + + entitlement + group + true + ri:GroupObjectClass + + icfs:name + + + identifier + + + @@ -105,24 +149,18 @@ deleted - true http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink unlinked - true http://midpoint.evolveum.com/xml/ns/public/model/action-3#link unmatched - true - - http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus - diff --git a/testing/story/src/test/resources/system-perf/role-business.vm.xml b/testing/story/src/test/resources/system-perf/role-business.vm.xml new file mode 100644 index 00000000000..ea058401c27 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/role-business.vm.xml @@ -0,0 +1,23 @@ + + + + + $name + +#foreach($inducedOid in $inducedOidList) + + + +#end + diff --git a/testing/story/src/test/resources/system-perf/role-targets.vm.xml b/testing/story/src/test/resources/system-perf/role-targets.vm.xml new file mode 100644 index 00000000000..4acb01a251b --- /dev/null +++ b/testing/story/src/test/resources/system-perf/role-targets.vm.xml @@ -0,0 +1,19 @@ + + + + targets + +#foreach($oid in $oidList) + + + + + +#end + diff --git a/testing/story/src/test/resources/system-perf/role-technical.vm.xml b/testing/story/src/test/resources/system-perf/role-technical.vm.xml new file mode 100644 index 00000000000..becfe4088b6 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/role-technical.vm.xml @@ -0,0 +1,59 @@ + + + + + technical-$index + + + + entitlement + group + + + + g-$index + + + + + + ri:membership + + + + + + + + ri:group + + + + + entitlement + group + + + + + + + + diff --git a/testing/story/src/test/resources/system-perf/system-configuration.xml b/testing/story/src/test/resources/system-perf/system-configuration.xml index 654c998f43f..d7d12d41d9e 100644 --- a/testing/story/src/test/resources/system-perf/system-configuration.xml +++ b/testing/story/src/test/resources/system-perf/system-configuration.xml @@ -35,6 +35,10 @@ true + + UserType + + true diff --git a/testing/story/src/test/resources/system-perf/task-import.xml b/testing/story/src/test/resources/system-perf/task-import.vm.xml similarity index 72% rename from testing/story/src/test/resources/system-perf/task-import.xml rename to testing/story/src/test/resources/system-perf/task-import.vm.xml index 6f5872231f9..3176fd0e311 100644 --- a/testing/story/src/test/resources/system-perf/task-import.xml +++ b/testing/story/src/test/resources/system-perf/task-import.vm.xml @@ -6,22 +6,31 @@ ~ and European Union Public License. See LICENSE file for details. --> - + + - Import + task-import-$index ri:AccountObjectClass + $workerThreads - closed + runnable http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/import/handler-3 - + single diff --git a/testing/story/src/test/resources/system-perf/task-recompute.xml b/testing/story/src/test/resources/system-perf/task-recompute.vm.xml similarity index 85% rename from testing/story/src/test/resources/system-perf/task-recompute.xml rename to testing/story/src/test/resources/system-perf/task-recompute.vm.xml index 4a17cd4afea..b2fd4fb1318 100644 --- a/testing/story/src/test/resources/system-perf/task-recompute.xml +++ b/testing/story/src/test/resources/system-perf/task-recompute.vm.xml @@ -6,12 +6,17 @@ ~ and European Union Public License. See LICENSE file for details. --> + + - Recompute + task-recompute UserType @@ -24,10 +29,11 @@ + $workerThreads - closed + runnable http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/recompute/handler-3 diff --git a/testing/story/src/test/resources/system-perf/task-reconciliation.vm.xml b/testing/story/src/test/resources/system-perf/task-reconciliation.vm.xml new file mode 100644 index 00000000000..062e18f4bc8 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/task-reconciliation.vm.xml @@ -0,0 +1,36 @@ + + + + + + + + task-reconciliation-$index + + + ri:AccountObjectClass + $workerThreads + + + + runnable + + http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/reconciliation/handler-3 + + + single + diff --git a/testing/story/src/test/resources/system-perf/template-user.xml b/testing/story/src/test/resources/system-perf/template-user.xml new file mode 100644 index 00000000000..9668d3a314b --- /dev/null +++ b/testing/story/src/test/resources/system-perf/template-user.xml @@ -0,0 +1,30 @@ + + + + template-user + + + + + + + + + + + + + + + + + + + + From bb30b55986c1f4010098701be740accbae0ec2bd Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 3 May 2021 17:06:15 +0200 Subject: [PATCH 11/33] Fix style and dependency errors --- testing/story/pom.xml | 4 ++++ .../src/test/resources/system-perf/archetype-basic-user.xml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/testing/story/pom.xml b/testing/story/pom.xml index 31af5e5bab1..0f7d7023445 100644 --- a/testing/story/pom.xml +++ b/testing/story/pom.xml @@ -181,6 +181,10 @@ ch.qos.logback logback-classic + + org.apache.velocity + velocity + diff --git a/testing/story/src/test/resources/system-perf/archetype-basic-user.xml b/testing/story/src/test/resources/system-perf/archetype-basic-user.xml index 552dcfb8098..6428103fbd2 100644 --- a/testing/story/src/test/resources/system-perf/archetype-basic-user.xml +++ b/testing/story/src/test/resources/system-perf/archetype-basic-user.xml @@ -11,4 +11,4 @@ - \ No newline at end of file + From 03848f27bd88f9b9bd013ad5ecdd3e4f6b880651 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Mon, 3 May 2021 08:56:08 +0200 Subject: [PATCH 12/33] repo: *SupportService merged into *RepoContext classes This is another consolidation where two concepts collapse into one, support service can be provided by repository context component, it is more natural. --- .../repo/sqale/SqaleQueryContext.java | 35 +++--- .../midpoint/repo/sqale/SqaleRepoContext.java | 34 +++++- .../repo/sqale/SqaleRepositoryService.java | 40 ++++--- .../repo/sqale/SqaleSupportService.java | 72 ------------- .../delta/item/RefItemDeltaProcessor.java | 3 +- .../item/RefTableItemDeltaProcessor.java | 2 +- .../delta/item/UriItemDeltaProcessor.java | 2 +- .../filtering/UriItemFilterProcessor.java | 2 +- .../sqale/operations/AddObjectOperation.java | 18 ++-- .../repo/sqale/qmodel/SqaleTableMapping.java | 16 +-- .../sqale/qmodel/object/QObjectMapping.java | 10 +- .../repo/sqale/update/RootUpdateContext.java | 11 +- .../repo/sqale/update/SqaleUpdateContext.java | 23 ++-- .../evolveum/midpoint/repo/sql/AuditTest.java | 7 +- .../repo/sql/SqlAuditServiceImpl.java | 7 +- .../repo/sql/audit/AuditSqlQueryContext.java | 10 +- .../sql/audit/mapping/AuditTableMapping.java | 4 +- .../sql/audit/mapping/QAuditDeltaMapping.java | 6 +- .../mapping/QAuditEventRecordMapping.java | 6 +- .../sqlbase/RepositoryObjectParseResult.java | 23 ++++ .../repo/sqlbase/SqlQueryContext.java | 18 ++-- .../midpoint/repo/sqlbase/SqlRepoContext.java | 57 +++++++++- .../repo/sqlbase/SqlSupportService.java | 100 ------------------ 23 files changed, 211 insertions(+), 295 deletions(-) delete mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleSupportService.java create mode 100644 repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/RepositoryObjectParseResult.java delete mode 100644 repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlSupportService.java diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java index 4379a1f2e24..1c603666c79 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java @@ -15,7 +15,6 @@ import com.evolveum.midpoint.repo.sqale.filtering.InOidFilterProcessor; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqlbase.SqlQueryContext; -import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.filtering.FilterProcessor; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; @@ -24,8 +23,8 @@ public class SqaleQueryContext, R> extends SqlQueryContext { public static , R> SqaleQueryContext from( - Class schemaType, SqaleSupportService sqaleSupportService, - SqlRepoContext sqlRepoContext) { + Class schemaType, + SqaleRepoContext sqlRepoContext) { SqaleTableMapping rootMapping = sqlRepoContext.getMappingBySchemaType(schemaType); Q rootPath = rootMapping.defaultAlias(); @@ -35,16 +34,20 @@ public static , R> SqaleQueryContext< query.getMetadata().setValidate(true); return new SqaleQueryContext<>( - rootPath, rootMapping, sqaleSupportService, sqlRepoContext, query); + rootPath, rootMapping, sqlRepoContext, query); } private SqaleQueryContext( Q entityPath, SqaleTableMapping mapping, - SqaleSupportService sqaleSupportService, - SqlRepoContext sqlRepoContext, + SqaleRepoContext sqlRepoContext, SQLQuery query) { - super(entityPath, mapping, sqaleSupportService, query); + super(entityPath, mapping, sqlRepoContext, query); + } + + @Override + public SqaleRepoContext repositoryContext() { + return (SqaleRepoContext) super.repositoryContext(); } @Override @@ -53,23 +56,19 @@ public FilterProcessor createInOidFilter(SqlQueryContext c } public @NotNull Integer searchCachedRelationId(QName qName) { - return supportService().searchCachedRelationId(qName); + return repositoryContext().searchCachedRelationId(qName); } /** - * Returns {@link SqaleQueryContext} - lot of ugly casting here, but it is not possible to - * use covariant return type with covariant parametric types (narrower generics). + * Returns derived {@link SqaleQueryContext} for join or subquery. */ - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override protected , TR> SqlQueryContext deriveNew(TQ newPath, QueryTableMapping newMapping) { - return (SqlQueryContext) new SqaleQueryContext( - newPath, (SqaleTableMapping) newMapping, - supportService(), sqlRepoContext, sqlQuery); - } - - private SqaleSupportService supportService() { - return (SqaleSupportService) sqlSupportService; + return new SqaleQueryContext<>( + newPath, + (SqaleTableMapping) newMapping, + repositoryContext(), + sqlQuery); } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java index 6be2920d497..8e0e022fa75 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java @@ -14,6 +14,7 @@ import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainerType; +import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType; import com.evolveum.midpoint.repo.sqale.qmodel.ref.MReferenceType; import com.evolveum.midpoint.repo.sqlbase.JdbcRepositoryConfiguration; @@ -21,6 +22,7 @@ import com.evolveum.midpoint.repo.sqlbase.mapping.QueryModelMappingRegistry; import com.evolveum.midpoint.repo.sqlbase.querydsl.QuerydslJsonbType; import com.evolveum.midpoint.schema.SchemaService; +import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; /** @@ -28,6 +30,8 @@ */ public class SqaleRepoContext extends SqlRepoContext { + private static SqaleRepoContext instance; + private final UriCache uriCache; public SqaleRepoContext( @@ -61,6 +65,13 @@ public SqaleRepoContext( querydslConfig.register(new QuerydslJsonbType()); uriCache = new UriCache(); + + instance = this; + } + + @Deprecated + public static SqaleRepoContext getInstance() { + return instance; } // This has nothing to do with "repo cache" which is higher than this. @@ -80,12 +91,21 @@ public Integer searchCachedUriId(String uri) { return uriCache.searchId(uri); } - /** @see UriCache#resolveUriToId(String) */ + /** + * Returns ID for relation QName or {@link UriCache#UNKNOWN_ID} without going to the database. + * Relation is normalized before consulting {@link UriCache}. + * Never returns null; returns default ID for configured default relation if provided with null. + */ + public @NotNull Integer searchCachedRelationId(QName qName) { + return searchCachedUriId(QNameUtil.qNameToUri(normalizeRelation(qName))); + } + + /** Returns ID for cached URI without going to the database. */ public @NotNull Integer resolveUriToId(String uri) { return uriCache.resolveUriToId(uri); } - /** @see UriCache#resolveUriToId(QName) */ + /** Returns ID for cached URI without going to the database. */ public Integer resolveUriToId(QName uri) { return uriCache.resolveUriToId(uri); } @@ -94,4 +114,14 @@ public Integer resolveUriToId(QName uri) { public Integer processCacheableUri(String uri) { return uriCache.processCacheableUri(uri); } + + /** + * Returns ID for relation QName creating new {@link QUri} row in DB as needed. + * Relation is normalized before consulting the cache. + * Never returns null, returns default ID for configured default relation. + */ + public Integer processCacheableRelation(QName qName) { + return processCacheableUri( + QNameUtil.qNameToUri(normalizeRelation(qName))); + } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java index 41822a14438..8613d581234 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java @@ -69,10 +69,9 @@ public class SqaleRepositoryService implements RepositoryService { private static final int MAX_CONFLICT_WATCHERS = 10; - private final SqaleRepoContext sqlRepoContext; + private final SqaleRepoContext repositoryContext; private final SchemaService schemaService; private final SqlQueryExecutor sqlQueryExecutor; - private final SqaleSupportService supportService; private final SqlPerformanceMonitorsCollection sqlPerformanceMonitorsCollection; // TODO: see comment in the SystemConfigurationChangeDispatcherImpl for related issues @@ -84,17 +83,16 @@ public class SqaleRepositoryService implements RepositoryService { private SqlPerformanceMonitorImpl performanceMonitor; // set to null in destroy public SqaleRepositoryService( - SqaleRepoContext sqlRepoContext, + SqaleRepoContext repositoryContext, SchemaService schemaService, SqlPerformanceMonitorsCollection sqlPerformanceMonitorsCollection) { - this.sqlRepoContext = sqlRepoContext; + this.repositoryContext = repositoryContext; this.schemaService = schemaService; - this.sqlQueryExecutor = new SqlQueryExecutor(sqlRepoContext); - this.supportService = new SqaleSupportService(schemaService, sqlRepoContext); + this.sqlQueryExecutor = new SqlQueryExecutor(repositoryContext); this.sqlPerformanceMonitorsCollection = sqlPerformanceMonitorsCollection; // monitor initialization and registration - JdbcRepositoryConfiguration config = sqlRepoContext.getJdbcRepositoryConfiguration(); + JdbcRepositoryConfiguration config = repositoryContext.getJdbcRepositoryConfiguration(); performanceMonitor = new SqlPerformanceMonitorImpl( config.getPerformanceStatisticsLevel(), config.getPerformanceStatisticsFile()); sqlPerformanceMonitorsCollection.register(performanceMonitor); @@ -123,7 +121,7 @@ public SqaleRepositoryService( try { PrismObject object; try (JdbcSession jdbcSession = - sqlRepoContext.newJdbcSession().startReadOnlyTransaction()) { + repositoryContext.newJdbcSession().startReadOnlyTransaction()) { //noinspection unchecked object = (PrismObject) readByOid(jdbcSession, type, oidUuid, options) .asPrismObject(); @@ -169,10 +167,10 @@ private S readByOid( throws SchemaException, ObjectNotFoundException { SqaleTableMapping, MObject> rootMapping = - sqlRepoContext.getMappingBySchemaType(schemaType); + repositoryContext.getMappingBySchemaType(schemaType); QObject root = rootMapping.defaultAlias(); - Tuple result = sqlRepoContext.newQuery(jdbcSession.connection()) + Tuple result = repositoryContext.newQuery(jdbcSession.connection()) .from(root) .select(rootMapping.selectExpressions(root, options)) .where(root.oid.eq(oid)) @@ -255,7 +253,7 @@ public String addObject( // TODO use executeAttempts String oid = new AddObjectOperation<>(object, options, operationResult) - .execute(supportService); + .execute(repositoryContext); invokeConflictWatchers((w) -> w.afterAddObject(oid, object)); return oid; /* @@ -356,7 +354,7 @@ public ModifyObjectResult modifyObject( logTraceModifications(modifications); // TODO: THIS is real start of modifyObjectAttempt - try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) { + try (JdbcSession jdbcSession = repositoryContext.newJdbcSession().startTransaction()) { RootUpdateContext, MObject> updateContext = prepareUpdateContext(jdbcSession, type, oidUuid); PrismObject prismObject = updateContext.getPrismObject(); @@ -399,10 +397,10 @@ RootUpdateContext prepareUpdateContext( throws SchemaException, ObjectNotFoundException { SqaleTableMapping, R> rootMapping = - sqlRepoContext.getMappingBySchemaType(schemaType); + repositoryContext.getMappingBySchemaType(schemaType); QObject root = rootMapping.defaultAlias(); - Tuple result = sqlRepoContext.newQuery(jdbcSession.connection()) + Tuple result = repositoryContext.newQuery(jdbcSession.connection()) .select(root.oid, root.fullObject, root.containerIdSeq) .from(root) .where(root.oid.eq(oid)) @@ -422,7 +420,7 @@ RootUpdateContext prepareUpdateContext( rootRow.objectType = MObjectType.fromSchemaType(object.getClass()); // we don't care about full object in row - return new RootUpdateContext<>(supportService, jdbcSession, object, rootRow); + return new RootUpdateContext<>(repositoryContext, jdbcSession, object, rootRow); } private void logTraceModifications(@NotNull Collection> modifications) { @@ -459,7 +457,7 @@ private void logTraceModifications(@NotNull Collection .addParam("oid", oid) .build(); try { - try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) { + try (JdbcSession jdbcSession = repositoryContext.newJdbcSession().startTransaction()) { DeleteObjectResult result = deleteObjectAttempt(type, oidUuid, jdbcSession); invokeConflictWatchers((w) -> w.afterDeleteObject(oid)); @@ -480,7 +478,7 @@ private void logTraceModifications(@NotNull Collection DeleteObjectResult deleteObjectAttempt(Class type, UUID oid, JdbcSession jdbcSession) throws ObjectNotFoundException { - QueryTableMapping mapping = sqlRepoContext.getMappingBySchemaType(type); + QueryTableMapping mapping = repositoryContext.getMappingBySchemaType(type); Q entityPath = mapping.defaultAlias(); byte[] fullObject = jdbcSession.newQuery() .select(entityPath.fullObject) @@ -517,7 +515,7 @@ public int countObjects(Class type, ObjectQuery query, .build(); try { - var queryContext = SqaleQueryContext.from(type, supportService, sqlRepoContext); + var queryContext = SqaleQueryContext.from(type, repositoryContext); return sqlQueryExecutor.count(queryContext, query, options); } catch (RepositoryException | RuntimeException e) { throw handledGeneralException(e, operationResult); @@ -545,7 +543,7 @@ public int countObjects(Class type, ObjectQuery query, .build(); try { - var queryContext = SqaleQueryContext.from(type, supportService, sqlRepoContext); + var queryContext = SqaleQueryContext.from(type, repositoryContext); SearchResultList result = sqlQueryExecutor.list(queryContext, query, options); // TODO see the commented code from old repo lower, problems for each object must be caught @@ -628,7 +626,7 @@ public SearchResultList searchContainers( .build(); try { - var queryContext = SqaleQueryContext.from(type, supportService, sqlRepoContext); + var queryContext = SqaleQueryContext.from(type, repositoryContext); SearchResultList result = sqlQueryExecutor.list(queryContext, query, options); return result; @@ -833,7 +831,7 @@ private SystemException handledGeneralException(@NotNull Throwable ex, Operation // TODO reconsider this whole mechanism including isFatalException decision LOGGER.error("General checked exception occurred.", ex); recordException(ex, result, - sqlRepoContext.getJdbcRepositoryConfiguration().isFatalException(ex)); + repositoryContext.getJdbcRepositoryConfiguration().isFatalException(ex)); return ex instanceof SystemException ? (SystemException) ex diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleSupportService.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleSupportService.java deleted file mode 100644 index 8bbde61260c..00000000000 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleSupportService.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqale; - -import javax.xml.namespace.QName; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri; -import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; -import com.evolveum.midpoint.schema.SchemaService; -import com.evolveum.midpoint.util.QNameUtil; - -/** - * Extension of {@link SqlSupportService} adding Sqale features like {@link UriCache} support. - */ -public class SqaleSupportService extends SqlSupportService { - - private static SqaleSupportService instance; - - public SqaleSupportService(SchemaService schemaService, SqaleRepoContext sqaleRepoContext) { - super(schemaService, sqaleRepoContext); - instance = this; - } - - public static SqaleSupportService getInstance() { - return instance; - } - - private SqaleRepoContext sqaleRepoContext() { - return (SqaleRepoContext) sqlRepoContext; - } - - /** - * Returns ID for relation QName or {@link UriCache#UNKNOWN_ID} without going to the database. - * Relation is normalized before consulting {@link UriCache}. - * Never returns null; returns default ID for configured default relation if provided with null. - */ - public @NotNull Integer searchCachedRelationId(QName qName) { - return sqaleRepoContext().searchCachedUriId(QNameUtil.qNameToUri(normalizeRelation(qName))); - } - - /** Returns ID for cached URI without going to the database. */ - public Integer resolveUriToId(String uri) { - return sqaleRepoContext().resolveUriToId(uri); - } - - /** Returns ID for cached URI without going to the database. */ - public Integer resolveUriToId(QName uri) { - return sqaleRepoContext().resolveUriToId(uri); - } - - /** - * Returns ID for relation QName creating new {@link QUri} row in DB as needed. - * Relation is normalized before consulting the cache. - * Never returns null, returns default ID for configured default relation. - */ - public Integer processCacheableRelation(QName qName) { - return processCacheableUri( - QNameUtil.qNameToUri(normalizeRelation(qName))); - } - - /** Returns ID for URI creating new cache row in DB as needed. */ - public Integer processCacheableUri(String uri) { - return sqaleRepoContext().processCacheableUri(uri); - } -} - diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefItemDeltaProcessor.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefItemDeltaProcessor.java index c31601cc86c..a9256c5d88d 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefItemDeltaProcessor.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefItemDeltaProcessor.java @@ -57,7 +57,8 @@ , R> RefItemDeltaProcessor( public void setValue(Referencable value) { context.set(oidPath, UUID.fromString(value.getOid())); context.set(typePath, MObjectType.fromTypeQName(value.getType())); - context.set(relationIdPath, context.processCacheableRelation(value.getRelation())); + context.set(relationIdPath, + context.repositoryContext().processCacheableRelation(value.getRelation())); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java index 7b068645f6b..2b106886e84 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java @@ -46,7 +46,7 @@ public void addValues(Collection values) { public void deleteValues(Collection values) { Q r = refTableMapping.defaultAlias(); for (Referencable ref : values) { - Integer relId = context.supportService().searchCachedRelationId(ref.getRelation()); + Integer relId = context.repositoryContext().searchCachedRelationId(ref.getRelation()); context.jdbcSession().newDelete(r) .where(r.isOwnedBy(context.row()) .and(r.targetOid.eq(UUID.fromString(ref.getOid()))) diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/UriItemDeltaProcessor.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/UriItemDeltaProcessor.java index c1acaf69af4..00e02ed2c52 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/UriItemDeltaProcessor.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/UriItemDeltaProcessor.java @@ -29,6 +29,6 @@ public , R> UriItemDeltaProcessor( @Override public @Nullable Integer convertRealValue(Object realValue) { - return context.processCacheableUri((String) realValue); + return context.repositoryContext().processCacheableUri((String) realValue); } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/filtering/UriItemFilterProcessor.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/filtering/UriItemFilterProcessor.java index b154daed1fc..2125d540458 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/filtering/UriItemFilterProcessor.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/filtering/UriItemFilterProcessor.java @@ -36,6 +36,6 @@ public , R> UriItemFilterProcessor( public Predicate process(PropertyValueFilter filter) throws QueryException { return createBinaryCondition(filter, path, ValueFilterValues.from(filter, - u -> ((SqaleRepoContext) context.sqlRepoContext()).searchCachedUriId(u))); + u -> ((SqaleRepoContext) context.repositoryContext()).searchCachedUriId(u))); } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java index aa63319d799..c0614196cad 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java @@ -18,7 +18,7 @@ import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.repo.api.RepoAddOptions; import com.evolveum.midpoint.repo.sqale.ContainerValueIdGenerator; -import com.evolveum.midpoint.repo.sqale.SqaleSupportService; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObject; @@ -46,7 +46,7 @@ public class AddObjectOperation, R ex private final RepoAddOptions options; private final OperationResult result; - private SqlRepoContext sqlRepoContext; + private SqlRepoContext repositoryContext; private Q root; private QObjectMapping rootMapping; private MObjectType objectType; @@ -58,15 +58,17 @@ public AddObjectOperation(@NotNull PrismObject object, this.result = result; } - /** Inserts the object provided to the constructor and returns its OID. */ - public String execute(SqaleSupportService supportService) + /** + * Inserts the object provided to the constructor and returns its OID. + */ + public String execute(SqaleRepoContext repositoryContext) throws SchemaException, ObjectAlreadyExistsException { try { // TODO utilize options and result - sqlRepoContext = supportService.sqlRepoContext(); + this.repositoryContext = repositoryContext; Class schemaObjectClass = object.getCompileTimeClass(); objectType = MObjectType.fromSchemaType(schemaObjectClass); - rootMapping = sqlRepoContext.getMappingBySchemaType(schemaObjectClass); + rootMapping = repositoryContext.getMappingBySchemaType(schemaObjectClass); root = rootMapping.defaultAlias(); // we don't want CID generation here, because overwrite works different then normal add @@ -94,7 +96,7 @@ private String overwriteObject() { private String addObjectWithOid() throws SchemaException { long lastCid = new ContainerValueIdGenerator().generateForNewObject(object); - try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) { + try (JdbcSession jdbcSession = repositoryContext.newJdbcSession().startTransaction()) { S schemaObject = object.asObjectable(); R row = rootMapping.toRowObjectWithoutFullObject(schemaObject, jdbcSession); row.containerIdSeq = lastCid + 1; @@ -115,7 +117,7 @@ private String addObjectWithOid() throws SchemaException { } private String addObjectWithoutOid() throws SchemaException { - try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) { + try (JdbcSession jdbcSession = repositoryContext.newJdbcSession().startTransaction()) { S schemaObject = object.asObjectable(); R row = rootMapping.toRowObjectWithoutFullObject(schemaObject, jdbcSession); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java index 26df02bc71a..5b26fb0fa1b 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java @@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import com.evolveum.midpoint.repo.sqale.SqaleSupportService; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.delta.item.*; import com.evolveum.midpoint.repo.sqale.filtering.RefItemFilterProcessor; import com.evolveum.midpoint.repo.sqale.filtering.UriItemFilterProcessor; @@ -232,7 +232,7 @@ protected ObjectReferenceType objectReferenceType( return new ObjectReferenceType() .oid(oid) - .type(SqaleSupportService.getInstance() + .type(SqaleRepoContext.getInstance() .schemaClassToQName(repoObjectType.getSchemaType())) .description(targetName) .targetName(targetName); @@ -251,12 +251,12 @@ protected ObjectReferenceType objectReferenceType( } protected @NotNull Integer searchCachedRelationId(QName qName) { - return SqaleSupportService.getInstance().searchCachedRelationId(qName); + return SqaleRepoContext.getInstance().searchCachedRelationId(qName); } /** Returns ID for cached URI without going to the database. */ protected Integer resolveUriToId(String uri) { - return SqaleSupportService.getInstance().resolveUriToId(uri); + return SqaleRepoContext.getInstance().resolveUriToId(uri); } /** @@ -265,20 +265,20 @@ protected Integer resolveUriToId(String uri) { * Never returns null, returns default ID for configured default relation. */ protected Integer processCacheableRelation(QName qName) { - return SqaleSupportService.getInstance().processCacheableRelation(qName); + return SqaleRepoContext.getInstance().processCacheableRelation(qName); } /** Returns ID for URI creating new cache row in DB as needed. */ protected Integer processCacheableUri(String uri) { return uri != null - ? SqaleSupportService.getInstance().processCacheableUri(uri) + ? SqaleRepoContext.getInstance().processCacheableUri(uri) : null; } /** Returns ID for URI creating new cache row in DB as needed. */ protected Integer processCacheableUri(QName qName) { return qName != null - ? SqaleSupportService.getInstance() + ? SqaleRepoContext.getInstance() .processCacheableUri(QNameUtil.qNameToUri(qName)) : null; } @@ -303,7 +303,7 @@ protected Integer[] processCacheableUris(List uris) { protected MObjectType schemaTypeToObjectType(QName schemaType) { return schemaType == null ? null : MObjectType.fromSchemaType( - SqaleSupportService.getInstance().qNameToSchemaClass(schemaType)); + SqaleRepoContext.getInstance().qNameToSchemaClass(schemaType)); } protected void setPolyString(PolyStringType polyString, diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java index 1c34ee9a277..2b92bbce8a4 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java @@ -22,14 +22,14 @@ import com.evolveum.midpoint.prism.PrismConstants; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.SerializationOptions; -import com.evolveum.midpoint.repo.sqale.SqaleSupportService; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.SqaleUtils; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentMapping; import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; +import com.evolveum.midpoint.repo.sqlbase.RepositoryObjectParseResult; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -198,8 +198,8 @@ public S toSchemaObject(Tuple row, Q entityPath, PrismObject prismObject; String serializedForm = new String(fullObject, StandardCharsets.UTF_8); try { - SqlSupportService.ParseResult result = - SqaleSupportService.getInstance().parsePrismObject(serializedForm); + RepositoryObjectParseResult result = + SqaleRepoContext.getInstance().parsePrismObject(serializedForm); prismObject = result.prismObject; if (result.parsingContext.hasWarnings()) { logger.warn("Object {} parsed with {} warnings", @@ -354,7 +354,7 @@ public byte[] createFullObject(S schemaObject) throws SchemaException { "Serialized object must have assigned OID and version: " + schemaObject); } - return SqaleSupportService.getInstance().createStringSerializer() + return SqaleRepoContext.getInstance().createStringSerializer() .itemsToSkip(fullObjectItemsToSkip()) .options(SerializationOptions .createSerializeReferenceNamesForNullOids() diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java index adacfc59bb8..2d137a9bccd 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/RootUpdateContext.java @@ -18,7 +18,7 @@ import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy; import com.evolveum.midpoint.repo.sqale.ContainerValueIdGenerator; -import com.evolveum.midpoint.repo.sqale.SqaleSupportService; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.SqaleUtils; import com.evolveum.midpoint.repo.sqale.delta.DelegatingItemDeltaProcessor; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; @@ -49,13 +49,12 @@ public class RootUpdateContext, R ext private ContainerValueIdGenerator cidGenerator; - public RootUpdateContext(SqaleSupportService supportService, + public RootUpdateContext(SqaleRepoContext repositoryContext, JdbcSession jdbcSession, S object, R rootRow) { - super(supportService, jdbcSession, rootRow); + super(repositoryContext, jdbcSession, rootRow); this.object = object; - mapping = supportService.sqlRepoContext() - .getMappingBySchemaType(SqaleUtils.getClass(object)); + mapping = repositoryContext.getMappingBySchemaType(SqaleUtils.getClass(object)); rootPath = mapping.defaultAlias(); objectVersion = objectVersionAsInt(object); // root context always updates, at least version and full object, so we can create it early @@ -101,7 +100,7 @@ public QueryTableMapping mapping() { } } - supportService.normalizeAllRelations(prismObject); + repositoryContext().normalizeAllRelations(prismObject); finishExecution(); return modifications; diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java index 0f419fc2786..7cc1b9823f4 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/update/SqaleUpdateContext.java @@ -8,13 +8,12 @@ import java.util.LinkedHashMap; import java.util.Map; -import javax.xml.namespace.QName; import com.querydsl.core.types.Path; import com.evolveum.midpoint.prism.path.ItemName; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.repo.sqale.SqaleSupportService; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.delta.ItemDeltaValueProcessor; import com.evolveum.midpoint.repo.sqale.delta.item.UriItemDeltaProcessor; import com.evolveum.midpoint.repo.sqale.qmodel.QOwnedByMapping; @@ -60,7 +59,7 @@ public abstract class SqaleUpdateContext> subcontexts = new LinkedHashMap<>(); public SqaleUpdateContext( - SqaleSupportService supportService, + SqaleRepoContext repositoryContext, JdbcSession jdbcSession, R row) { - this.supportService = supportService; + this.repositoryContext = repositoryContext; this.jdbcSession = jdbcSession; this.row = row; @@ -93,21 +92,13 @@ public SqaleUpdateContext( R row) { this.parentContext = parentContext; // registering this with parent context must happen outside of constructor! - this.supportService = parentContext.supportService; + this.repositoryContext = parentContext.repositoryContext; this.jdbcSession = parentContext.jdbcSession(); this.row = row; } - public SqaleSupportService supportService() { - return supportService; - } - - public Integer processCacheableRelation(QName relation) { - return supportService.processCacheableRelation(relation); - } - - public Integer processCacheableUri(String uri) { - return supportService.processCacheableUri(uri); + public SqaleRepoContext repositoryContext() { + return repositoryContext; } public JdbcSession jdbcSession() { diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java index 11f91808e79..a9e33b37b51 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java @@ -8,8 +8,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.evolveum.midpoint.schema.result.OperationResult; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; @@ -27,6 +25,7 @@ import com.evolveum.midpoint.repo.sql.util.RUtil; import com.evolveum.midpoint.repo.sqlbase.*; import com.evolveum.midpoint.schema.ObjectDeltaOperation; +import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.test.NullTaskImpl; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; @@ -153,10 +152,8 @@ private MAuditEventRecord getAuditEventRecord(int expectedCount, int index) throws QueryException { // "create" does not actually create a new audit service, but returns the existing one SqlRepoContext sqlRepoContext = auditServiceFactory.createAuditService().getSqlRepoContext(); - SqlSupportService transformerSupport = new SqlSupportService(schemaService, sqlRepoContext); SqlQueryContext context = - AuditSqlQueryContext.from( - AuditEventRecordType.class, transformerSupport, sqlRepoContext); + AuditSqlQueryContext.from(AuditEventRecordType.class, sqlRepoContext); QAuditEventRecord aer = context.root(); context.sqlQuery().orderBy(aer.id.asc()); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java index e4995e88a30..7d265373196 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java @@ -102,9 +102,7 @@ public class SqlAuditServiceImpl extends SqlBaseService implements AuditService private final BaseHelper baseHelper; // only for logging/exception handling private final SqlRepoContext sqlRepoContext; private final SchemaService schemaService; - private final SqlQueryExecutor sqlQueryExecutor; - private final SqlSupportService transformerSupport; private volatile SystemConfigurationAuditType auditConfiguration; @@ -116,7 +114,6 @@ public SqlAuditServiceImpl( this.sqlRepoContext = sqlRepoContext; this.schemaService = schemaService; this.sqlQueryExecutor = new SqlQueryExecutor(sqlRepoContext); - this.transformerSupport = new SqlSupportService(schemaService, sqlRepoContext); } public SqlRepoContext getSqlRepoContext() { @@ -1129,7 +1126,7 @@ public int countObjects( try { var queryContext = AuditSqlQueryContext.from( - AuditEventRecordType.class, transformerSupport, sqlRepoContext); + AuditEventRecordType.class, sqlRepoContext); return sqlQueryExecutor.count(queryContext, query, options); } catch (RepositoryException | RuntimeException e) { baseHelper.handleGeneralException(e, operationResult); @@ -1155,7 +1152,7 @@ public SearchResultList searchObjects( try { var queryContext = AuditSqlQueryContext.from( - AuditEventRecordType.class, transformerSupport, sqlRepoContext); + AuditEventRecordType.class, sqlRepoContext); SearchResultList result = sqlQueryExecutor.list(queryContext, query, options); return result; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java index 080a52b9c60..516d6e65d6c 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/AuditSqlQueryContext.java @@ -10,7 +10,6 @@ import com.evolveum.midpoint.repo.sqlbase.SqlQueryContext; import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; -import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; @@ -24,7 +23,7 @@ public class AuditSqlQueryContext, R> // Type parameters the same as in the class documentation. public static , R> AuditSqlQueryContext from( - Class schemaType, SqlSupportService sqlSupportService, SqlRepoContext sqlRepoContext) { + Class schemaType, SqlRepoContext sqlRepoContext) { QueryTableMapping rootMapping = sqlRepoContext.getMappingBySchemaType(schemaType); Q rootPath = rootMapping.defaultAlias(); @@ -34,22 +33,21 @@ public static , R> AuditSqlQueryConte query.getMetadata().setValidate(true); return new AuditSqlQueryContext<>( - rootPath, rootMapping, sqlRepoContext, sqlSupportService, query); + rootPath, rootMapping, sqlRepoContext, query); } private AuditSqlQueryContext( Q entityPath, QueryTableMapping mapping, SqlRepoContext sqlRepoContext, - SqlSupportService sqlSupportService, SQLQuery query) { - super(entityPath, mapping, sqlSupportService, query); + super(entityPath, mapping, sqlRepoContext, query); } @Override protected , TR> SqlQueryContext deriveNew(TQ newPath, QueryTableMapping newMapping) { return new AuditSqlQueryContext<>( - newPath, newMapping, sqlRepoContext, sqlSupportService, sqlQuery); + newPath, newMapping, repositoryContext(), sqlQuery); } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java index 3fc847bcc75..1077a29423c 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java @@ -14,7 +14,7 @@ import org.jetbrains.annotations.Nullable; import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; -import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -63,7 +63,7 @@ protected ObjectReferenceType objectReferenceType( return new ObjectReferenceType() .oid(oid) - .type(SqlSupportService.getInstance() + .type(SqlRepoContext.getInstance() .schemaClassToQName(repoObjectType.getJaxbClass())) .description(targetName) .targetName(targetName); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java index e1b45b5102f..5baa0d1c207 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java @@ -15,7 +15,7 @@ import com.evolveum.midpoint.repo.sql.audit.beans.MAuditDelta; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditDelta; import com.evolveum.midpoint.repo.sql.util.RUtil; -import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectDeltaOperationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; @@ -45,7 +45,7 @@ protected QAuditDelta newAliasInstance(String alias) { public ObjectDeltaOperationType toSchemaObject(MAuditDelta row) { ObjectDeltaOperationType odo = new ObjectDeltaOperationType(); SQLTemplates querydslTemplates = - SqlSupportService.getInstance().sqlRepoContext().getQuerydslTemplates(); + SqlRepoContext.getInstance().getQuerydslTemplates(); boolean usingSqlServer = querydslTemplates instanceof SQLServerTemplates; odo.setObjectDelta(parseBytes(row.delta, usingSqlServer, ObjectDeltaType.class)); @@ -70,7 +70,7 @@ private T parseBytes(byte[] bytes, boolean usingSqlServer, Class clazz) { } try { - return SqlSupportService.getInstance() + return SqlRepoContext.getInstance() .createStringParser(RUtil.getSerializedFormFromBytes(bytes, usingSqlServer)) .compat() .parseRealValue(clazz); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java index 67e6d7839a4..11bc617d30d 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java @@ -28,7 +28,7 @@ import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventType; import com.evolveum.midpoint.repo.sql.data.common.enums.ROperationResultStatus; import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; -import com.evolveum.midpoint.repo.sqlbase.SqlSupportService; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.filtering.item.CanonicalItemPathItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.DetailTableItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.EnumOrdinalItemFilterProcessor; @@ -149,7 +149,7 @@ public AuditEventRecordType toSchemaObject(MAuditEventRecord row) { private AuditEventRecordType mapSimpleAttributes(MAuditEventRecord row) { // prismContext in constructor ensures complex type definition - return new AuditEventRecordType(SqlSupportService.getInstance().prismContext()) + return new AuditEventRecordType(SqlRepoContext.getInstance().prismContext()) .repoId(row.id) .channel(row.channel) .eventIdentifier(row.eventIdentifier) @@ -326,7 +326,7 @@ public MAuditEventRecord toRowObject(AuditEventRecord record) { private Integer targetTypeToRepoOrdinal(PrismReferenceValue targetOwner) { //noinspection rawtypes - Class objectClass = SqlSupportService.getInstance() + Class objectClass = SqlRepoContext.getInstance() .qNameToSchemaClass(targetOwner.getTargetType()); //noinspection unchecked return MiscUtil.enumOrdinal(RObjectType.getByJaxbType(objectClass)); diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/RepositoryObjectParseResult.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/RepositoryObjectParseResult.java new file mode 100644 index 00000000000..6c6fc5eaa5c --- /dev/null +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/RepositoryObjectParseResult.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.repo.sqlbase; + +import com.evolveum.midpoint.prism.Objectable; +import com.evolveum.midpoint.prism.ParsingContext; +import com.evolveum.midpoint.prism.PrismObject; + +/** Result for deserialization of prism object stored in the repository. */ +public class RepositoryObjectParseResult { + + public final ParsingContext parsingContext; + public final PrismObject prismObject; + + public RepositoryObjectParseResult(ParsingContext parsingContext, PrismObject prismObject) { + this.parsingContext = parsingContext; + this.prismObject = prismObject; + } +} diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java index ea3df4f487b..eeda9965227 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlQueryContext.java @@ -73,8 +73,7 @@ public abstract class SqlQueryContext protected final Q entityPath; protected final QueryTableMapping entityPathMapping; - protected final SqlRepoContext sqlRepoContext; - protected final SqlSupportService sqlSupportService; + private final SqlRepoContext sqlRepoContext; protected boolean notFilterUsed = false; @@ -84,12 +83,11 @@ public abstract class SqlQueryContext protected SqlQueryContext( Q entityPath, QueryTableMapping mapping, - SqlSupportService sqlSupportService, + SqlRepoContext sqlRepoContext, SQLQuery query) { this.entityPath = entityPath; this.entityPathMapping = mapping; - this.sqlSupportService = sqlSupportService; - this.sqlRepoContext = sqlSupportService.sqlRepoContext(); + this.sqlRepoContext = sqlRepoContext; this.sqlQuery = query; } @@ -338,25 +336,25 @@ public boolean isNotFilterUsed() { return notFilterUsed; } - public SqlRepoContext sqlRepoContext() { + public SqlRepoContext repositoryContext() { return sqlRepoContext; } public PrismContext prismContext() { - return sqlSupportService.prismContext(); + return sqlRepoContext.prismContext(); } public Class qNameToSchemaClass(@NotNull QName qName) { - return sqlSupportService.qNameToSchemaClass(qName); + return sqlRepoContext.qNameToSchemaClass(qName); } public CanonicalItemPath createCanonicalItemPath(@NotNull ItemPath itemPath) { - return sqlSupportService.prismContext().createCanonicalItemPath(itemPath); + return sqlRepoContext.prismContext().createCanonicalItemPath(itemPath); } @NotNull public QName normalizeRelation(QName qName) { - return sqlSupportService.normalizeRelation(qName); + return sqlRepoContext.normalizeRelation(qName); } public FilterProcessor createInOidFilter(SqlQueryContext context) { diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java index f991327184e..5e6e65a2427 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java @@ -9,6 +9,7 @@ import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; +import javax.xml.namespace.QName; import com.querydsl.sql.Configuration; import com.querydsl.sql.RelationalPath; @@ -17,12 +18,16 @@ import com.querydsl.sql.dml.SQLDeleteClause; import com.querydsl.sql.dml.SQLInsertClause; import com.querydsl.sql.dml.SQLUpdateClause; +import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryModelMappingRegistry; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.repo.sqlbase.querydsl.QuerydslUtils; import com.evolveum.midpoint.schema.SchemaService; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; /** @@ -36,16 +41,19 @@ public class SqlRepoContext { private final JdbcRepositoryConfiguration jdbcRepositoryConfiguration; protected final Configuration querydslConfig; + protected final SchemaService schemaService; private final QueryModelMappingRegistry mappingRegistry; private final DataSource dataSource; public SqlRepoContext( JdbcRepositoryConfiguration jdbcRepositoryConfiguration, DataSource dataSource, - SchemaService schemaService, QueryModelMappingRegistry mappingRegistry) { + SchemaService schemaService, + QueryModelMappingRegistry mappingRegistry) { this.jdbcRepositoryConfiguration = jdbcRepositoryConfiguration; this.querydslConfig = QuerydslUtils.querydslConfiguration( jdbcRepositoryConfiguration.getDatabaseType()); + this.schemaService = schemaService; this.mappingRegistry = mappingRegistry; this.dataSource = dataSource; @@ -53,6 +61,7 @@ public SqlRepoContext( instance = this; } + @Deprecated public static SqlRepoContext getInstance() { return instance; } @@ -115,4 +124,50 @@ public JdbcSession newJdbcSession() { throw new SystemException("Cannot create JDBC connection", e); } } + + // TODO review from here - this is stuff merged from support service + public Class qNameToSchemaClass(QName qName) { + return schemaService.typeQNameToSchemaClass(qName); + } + + public QName schemaClassToQName(Class schemaClass) { + return schemaService.schemaClassToTypeQName(schemaClass); + } + + public @NotNull QName normalizeRelation(QName qName) { + return schemaService.normalizeRelation(qName); + } + + @NotNull + public PrismSerializer createStringSerializer() { + return schemaService.createStringSerializer( + getJdbcRepositoryConfiguration().getFullObjectFormat()); + } + + public RepositoryObjectParseResult parsePrismObject(String serializedForm) + throws SchemaException { + PrismContext prismContext = schemaService.prismContext(); + // "Postel mode": be tolerant what you read. We need this to tolerate (custom) schema changes + ParsingContext parsingContext = prismContext.createParsingContextForCompatibilityMode(); + PrismObject prismObject = prismContext.parserFor(serializedForm) + .context(parsingContext).parse(); + return new RepositoryObjectParseResult<>(parsingContext, prismObject); + } + + @NotNull + public PrismParserNoIO createStringParser(String serializedResult) { + return schemaService.parserFor(serializedResult); + } + + /** + * Sometimes delegation is not enough - we need Prism context for schema type construction + * with definitions (parameter to constructor). + */ + public PrismContext prismContext() { + return schemaService.prismContext(); + } + + public void normalizeAllRelations(PrismObject prismObject) { + ObjectTypeUtil.normalizeAllRelations(prismObject, schemaService.relationRegistry()); + } } diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlSupportService.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlSupportService.java deleted file mode 100644 index cabc9e9347a..00000000000 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlSupportService.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sqlbase; - -import javax.xml.namespace.QName; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.schema.SchemaService; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.util.exception.SchemaException; - -/** - * Holds various component dependencies that are for query and update contexts and in mappers. - * Components can be obtained to execute calls on them, but preferably the needed logic - * can be implemented here (better abstraction). - * - * TODO: Unify/merge with SqlRepoContext and let it provide all the "services". - */ -public class SqlSupportService { - - private static SqlSupportService instance; - - protected final SchemaService schemaService; - protected final SqlRepoContext sqlRepoContext; - - public SqlSupportService(SchemaService schemaService, SqlRepoContext sqlRepoContext) { - this.schemaService = schemaService; - this.sqlRepoContext = sqlRepoContext; - instance = this; - } - - public static SqlSupportService getInstance() { - return instance; - } - - public Class qNameToSchemaClass(QName qName) { - return schemaService.typeQNameToSchemaClass(qName); - } - - public QName schemaClassToQName(Class schemaClass) { - return schemaService.schemaClassToTypeQName(schemaClass); - } - - public @NotNull QName normalizeRelation(QName qName) { - return schemaService.normalizeRelation(qName); - } - - @NotNull - public PrismSerializer createStringSerializer() { - return schemaService.createStringSerializer( - sqlRepoContext.getJdbcRepositoryConfiguration().getFullObjectFormat()); - } - - public ParseResult parsePrismObject(String serializedForm) - throws SchemaException { - PrismContext prismContext = schemaService.prismContext(); - // "Postel mode": be tolerant what you read. We need this to tolerate (custom) schema changes - ParsingContext parsingContext = prismContext.createParsingContextForCompatibilityMode(); - PrismObject prismObject = prismContext.parserFor(serializedForm) - .context(parsingContext).parse(); - return new ParseResult<>(parsingContext, prismObject); - } - - @NotNull - public PrismParserNoIO createStringParser(String serializedResult) { - return schemaService.parserFor(serializedResult); - } - - /** - * Sometimes delegation is not enough - we need Prism context for schema type construction - * with definitions (parameter to constructor). - */ - public PrismContext prismContext() { - return schemaService.prismContext(); - } - - public SqlRepoContext sqlRepoContext() { - return sqlRepoContext; - } - - public void normalizeAllRelations(PrismObject prismObject) { - ObjectTypeUtil.normalizeAllRelations(prismObject, schemaService.relationRegistry()); - } - - public static class ParseResult { - public final ParsingContext parsingContext; - public final PrismObject prismObject; - - public ParseResult(ParsingContext parsingContext, PrismObject prismObject) { - this.parsingContext = parsingContext; - this.prismObject = prismObject; - } - } -} From 20ef7b011613b2a77cced3b53528c3c0994c7fb2 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Mon, 3 May 2021 11:03:55 +0200 Subject: [PATCH 13/33] repo-sqale+audit: usage of *RepoContext.getInstance() hidden in mappings --- .../repo/sqale/qmodel/SqaleTableMapping.java | 25 ++++++++------ .../sqale/qmodel/object/QObjectMapping.java | 5 ++- .../sql/audit/mapping/AuditTableMapping.java | 3 +- .../sql/audit/mapping/QAuditDeltaMapping.java | 6 ++-- .../mapping/QAuditEventRecordMapping.java | 6 ++-- .../sqlbase/mapping/QueryTableMapping.java | 34 +++++++++++++++++++ 6 files changed, 56 insertions(+), 23 deletions(-) diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java index 5b26fb0fa1b..274b7089838 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java @@ -66,6 +66,14 @@ protected SqaleTableMapping( super(tableName, defaultAliasName, schemaType, queryType); } + public SqaleRepoContext repositoryContext() { + SqaleRepoContext repositoryContext = (SqaleRepoContext) super.repositoryContext(); + return repositoryContext != null + ? repositoryContext + // TODO remove this branch + : SqaleRepoContext.getInstance(); + } + /** * Returns the mapper creating the string filter/delta processors from context. * @@ -232,8 +240,7 @@ protected ObjectReferenceType objectReferenceType( return new ObjectReferenceType() .oid(oid) - .type(SqaleRepoContext.getInstance() - .schemaClassToQName(repoObjectType.getSchemaType())) + .type(repositoryContext().schemaClassToQName(repoObjectType.getSchemaType())) .description(targetName) .targetName(targetName); } @@ -251,12 +258,12 @@ protected ObjectReferenceType objectReferenceType( } protected @NotNull Integer searchCachedRelationId(QName qName) { - return SqaleRepoContext.getInstance().searchCachedRelationId(qName); + return repositoryContext().searchCachedRelationId(qName); } /** Returns ID for cached URI without going to the database. */ protected Integer resolveUriToId(String uri) { - return SqaleRepoContext.getInstance().resolveUriToId(uri); + return repositoryContext().resolveUriToId(uri); } /** @@ -265,21 +272,20 @@ protected Integer resolveUriToId(String uri) { * Never returns null, returns default ID for configured default relation. */ protected Integer processCacheableRelation(QName qName) { - return SqaleRepoContext.getInstance().processCacheableRelation(qName); + return repositoryContext().processCacheableRelation(qName); } /** Returns ID for URI creating new cache row in DB as needed. */ protected Integer processCacheableUri(String uri) { return uri != null - ? SqaleRepoContext.getInstance().processCacheableUri(uri) + ? repositoryContext().processCacheableUri(uri) : null; } /** Returns ID for URI creating new cache row in DB as needed. */ protected Integer processCacheableUri(QName qName) { return qName != null - ? SqaleRepoContext.getInstance() - .processCacheableUri(QNameUtil.qNameToUri(qName)) + ? repositoryContext().processCacheableUri(QNameUtil.qNameToUri(qName)) : null; } @@ -302,8 +308,7 @@ protected Integer[] processCacheableUris(List uris) { protected MObjectType schemaTypeToObjectType(QName schemaType) { return schemaType == null ? null : - MObjectType.fromSchemaType( - SqaleRepoContext.getInstance().qNameToSchemaClass(schemaType)); + MObjectType.fromSchemaType(repositoryContext().qNameToSchemaClass(schemaType)); } protected void setPolyString(PolyStringType polyString, diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java index 2b92bbce8a4..c582382241a 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java @@ -22,7 +22,6 @@ import com.evolveum.midpoint.prism.PrismConstants; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.SerializationOptions; -import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.SqaleUtils; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentMapping; @@ -199,7 +198,7 @@ public S toSchemaObject(Tuple row, Q entityPath, String serializedForm = new String(fullObject, StandardCharsets.UTF_8); try { RepositoryObjectParseResult result = - SqaleRepoContext.getInstance().parsePrismObject(serializedForm); + repositoryContext().parsePrismObject(serializedForm); prismObject = result.prismObject; if (result.parsingContext.hasWarnings()) { logger.warn("Object {} parsed with {} warnings", @@ -354,7 +353,7 @@ public byte[] createFullObject(S schemaObject) throws SchemaException { "Serialized object must have assigned OID and version: " + schemaObject); } - return SqaleRepoContext.getInstance().createStringSerializer() + return repositoryContext().createStringSerializer() .itemsToSkip(fullObjectItemsToSkip()) .options(SerializationOptions .createSerializeReferenceNamesForNullOids() diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java index 1077a29423c..bd1b6ee3bdf 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java @@ -63,8 +63,7 @@ protected ObjectReferenceType objectReferenceType( return new ObjectReferenceType() .oid(oid) - .type(SqlRepoContext.getInstance() - .schemaClassToQName(repoObjectType.getJaxbClass())) + .type(repositoryContext().schemaClassToQName(repoObjectType.getJaxbClass())) .description(targetName) .targetName(targetName); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java index 5baa0d1c207..776e0e41127 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java @@ -15,7 +15,6 @@ import com.evolveum.midpoint.repo.sql.audit.beans.MAuditDelta; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditDelta; import com.evolveum.midpoint.repo.sql.util.RUtil; -import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectDeltaOperationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; @@ -44,8 +43,7 @@ protected QAuditDelta newAliasInstance(String alias) { public ObjectDeltaOperationType toSchemaObject(MAuditDelta row) { ObjectDeltaOperationType odo = new ObjectDeltaOperationType(); - SQLTemplates querydslTemplates = - SqlRepoContext.getInstance().getQuerydslTemplates(); + SQLTemplates querydslTemplates = repositoryContext().getQuerydslTemplates(); boolean usingSqlServer = querydslTemplates instanceof SQLServerTemplates; odo.setObjectDelta(parseBytes(row.delta, usingSqlServer, ObjectDeltaType.class)); @@ -70,7 +68,7 @@ private T parseBytes(byte[] bytes, boolean usingSqlServer, Class clazz) { } try { - return SqlRepoContext.getInstance() + return repositoryContext() .createStringParser(RUtil.getSerializedFormFromBytes(bytes, usingSqlServer)) .compat() .parseRealValue(clazz); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java index 11bc617d30d..84d889c7d89 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java @@ -28,7 +28,6 @@ import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventType; import com.evolveum.midpoint.repo.sql.data.common.enums.ROperationResultStatus; import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; -import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.filtering.item.CanonicalItemPathItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.DetailTableItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.EnumOrdinalItemFilterProcessor; @@ -149,7 +148,7 @@ public AuditEventRecordType toSchemaObject(MAuditEventRecord row) { private AuditEventRecordType mapSimpleAttributes(MAuditEventRecord row) { // prismContext in constructor ensures complex type definition - return new AuditEventRecordType(SqlRepoContext.getInstance().prismContext()) + return new AuditEventRecordType(repositoryContext().prismContext()) .repoId(row.id) .channel(row.channel) .eventIdentifier(row.eventIdentifier) @@ -326,8 +325,7 @@ public MAuditEventRecord toRowObject(AuditEventRecord record) { private Integer targetTypeToRepoOrdinal(PrismReferenceValue targetOwner) { //noinspection rawtypes - Class objectClass = SqlRepoContext.getInstance() - .qNameToSchemaClass(targetOwner.getTargetType()); + Class objectClass = repositoryContext().qNameToSchemaClass(targetOwner.getTargetType()); //noinspection unchecked return MiscUtil.enumOrdinal(RObjectType.getByJaxbType(objectClass)); } diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java index 110f0dd41fc..9b9dd85af01 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.repo.sqlbase.QueryException; import com.evolveum.midpoint.repo.sqlbase.RepositoryException; import com.evolveum.midpoint.repo.sqlbase.SqlQueryContext; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.filtering.item.PolyStringItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.SimpleItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.TimestampItemFilterProcessor; @@ -68,6 +69,7 @@ public abstract class QueryTableMapping schemaType, + @NotNull Class queryType, + @NotNull SqlRepoContext repositoryContext) { + super(schemaType, queryType); + this.tableName = tableName; + this.defaultAliasName = defaultAliasName; + this.repositoryContext = repositoryContext; + } + + /** + * Creates metamodel for the table described by designated type (Q-class) related to schema type. + * Allows registration of any number of columns - typically used for static properties + * (non-extensions). + * + * @param tableName database table name + * @param defaultAliasName default alias name, some short abbreviation, must be unique + * across mapped types + */ + @Deprecated protected QueryTableMapping( @NotNull String tableName, @NotNull String defaultAliasName, @@ -96,6 +120,9 @@ protected QueryTableMapping( super(schemaType, queryType); this.tableName = tableName; this.defaultAliasName = defaultAliasName; + + // TODO remove this constructor, use the one above only + this.repositoryContext = null; } /** @@ -219,6 +246,13 @@ public String defaultAliasName() { return defaultAliasName; } + public SqlRepoContext repositoryContext() { + return repositoryContext != null + ? repositoryContext + // TODO remove this branch + : SqlRepoContext.getInstance(); + } + /** * Creates new alias (entity path instance) with a defined name. * You can also use {@link #defaultAlias()} if one alias in a query is enough. From 20cf510cc32af5e18986748eaae170cabc343104 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Mon, 3 May 2021 11:43:50 +0200 Subject: [PATCH 14/33] repo-sqlbase+audit: mappings use constructor injection for repo context --- .../midpoint/repo/sqale/SqaleRepoContext.java | 16 ------- .../repo/sqale/qmodel/SqaleTableMapping.java | 18 +++----- .../sqale/qmodel/object/QObjectMapping.java | 2 +- .../repo/sql/AuditCleanupPerformanceTest.java | 4 +- .../midpoint/repo/sql/CleanupTest.java | 14 +++--- .../repo/sql/SqlAuditServiceFactory.java | 45 ++++++++++++------- .../repo/sql/SqlAuditServiceImpl.java | 18 ++++---- .../sql/audit/mapping/AuditTableMapping.java | 9 +++- .../sql/audit/mapping/QAuditDeltaMapping.java | 17 +++++-- .../mapping/QAuditEventRecordMapping.java | 19 ++++++-- .../sql/audit/mapping/QAuditItemMapping.java | 18 ++++++-- .../mapping/QAuditPropertyValueMapping.java | 18 ++++++-- .../audit/mapping/QAuditRefValueMapping.java | 18 ++++++-- .../audit/mapping/QAuditResourceMapping.java | 18 ++++++-- .../midpoint/repo/sqlbase/SqlRepoContext.java | 10 ----- .../sqlbase/mapping/QueryTableMapping.java | 32 +++---------- 16 files changed, 154 insertions(+), 122 deletions(-) diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java index 8e0e022fa75..d81ecd98e71 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java @@ -80,12 +80,6 @@ public void clearCaches() { uriCache.initialize(this::newJdbcSession); } - /** @see UriCache#searchId(QName) */ - @NotNull - public Integer searchCachedUriId(QName qName) { - return uriCache.searchId(qName); - } - /** @see UriCache#searchId(String) */ public Integer searchCachedUriId(String uri) { return uriCache.searchId(uri); @@ -100,16 +94,6 @@ public Integer searchCachedUriId(String uri) { return searchCachedUriId(QNameUtil.qNameToUri(normalizeRelation(qName))); } - /** Returns ID for cached URI without going to the database. */ - public @NotNull Integer resolveUriToId(String uri) { - return uriCache.resolveUriToId(uri); - } - - /** Returns ID for cached URI without going to the database. */ - public Integer resolveUriToId(QName uri) { - return uriCache.resolveUriToId(uri); - } - /** Returns ID for URI creating new cache row in DB as needed. */ public Integer processCacheableUri(String uri) { return uriCache.processCacheableUri(uri); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java index 274b7089838..ce1401d7d75 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java @@ -30,6 +30,7 @@ import com.evolveum.midpoint.repo.sqale.qmodel.ref.MReference; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.filtering.item.EnumItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.PolyStringItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.SimpleItemFilterProcessor; @@ -62,15 +63,17 @@ protected SqaleTableMapping( @NotNull String tableName, @NotNull String defaultAliasName, @NotNull Class schemaType, - @NotNull Class queryType) { - super(tableName, defaultAliasName, schemaType, queryType); + @NotNull Class queryType, + @NotNull SqlRepoContext repositoryContext) { + super(tableName, defaultAliasName, schemaType, queryType, repositoryContext); } public SqaleRepoContext repositoryContext() { +// return (SqaleRepoContext) super.repositoryContext(); + // TODO remove this version when mapping is provided properly in config SqaleRepoContext repositoryContext = (SqaleRepoContext) super.repositoryContext(); return repositoryContext != null ? repositoryContext - // TODO remove this branch : SqaleRepoContext.getInstance(); } @@ -257,15 +260,6 @@ protected ObjectReferenceType objectReferenceType( return MiscUtil.trimString(value, columnMetadata.getSize()); } - protected @NotNull Integer searchCachedRelationId(QName qName) { - return repositoryContext().searchCachedRelationId(qName); - } - - /** Returns ID for cached URI without going to the database. */ - protected Integer resolveUriToId(String uri) { - return repositoryContext().resolveUriToId(uri); - } - /** * Returns ID for relation QName creating new {@link QUri} row in DB as needed. * Relation is normalized before consulting the cache. diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java index c582382241a..d8e18c265fe 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java @@ -57,7 +57,7 @@ protected QObjectMapping( @NotNull String defaultAliasName, @NotNull Class schemaType, @NotNull Class queryType) { - super(tableName, defaultAliasName, schemaType, queryType); + super(tableName, defaultAliasName, schemaType, queryType, null); addItemMapping(PrismConstants.T_ID, uuidMapper(q -> q.oid)); addItemMapping(F_NAME, polyStringMapper( diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditCleanupPerformanceTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditCleanupPerformanceTest.java index a12e6c0b926..1f4aef88e34 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditCleanupPerformanceTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditCleanupPerformanceTest.java @@ -52,7 +52,7 @@ public void testAuditCleanup() throws Exception { then(); assertThat(result.isSuccess()).isTrue(); - assertThat(count(QAuditEventRecordMapping.INSTANCE)).isEqualTo(1); + assertThat(count(QAuditEventRecordMapping.get())).isEqualTo(1); } } @@ -72,7 +72,7 @@ private void prepareAuditEventRecords() throws Exception { } } - assertThat(count(QAuditEventRecordMapping.INSTANCE)).isEqualTo(RECORDS); + assertThat(count(QAuditEventRecordMapping.get())).isEqualTo(RECORDS); } private ObjectDeltaOperation createObjectDeltaOperation(int i) throws Exception { diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CleanupTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CleanupTest.java index 3a4ca692283..4b573fe4919 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CleanupTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/CleanupTest.java @@ -74,12 +74,12 @@ private CleanupPolicyType createPolicy(int maxRecords) { @AfterMethod public void cleanup() { try (JdbcSession jdbcSession = createJdbcSession().startTransaction()) { - jdbcSession.newDelete(QAuditDeltaMapping.INSTANCE.defaultAlias()).execute(); - jdbcSession.newDelete(QAuditItemMapping.INSTANCE.defaultAlias()).execute(); - jdbcSession.newDelete(QAuditPropertyValueMapping.INSTANCE.defaultAlias()).execute(); - jdbcSession.newDelete(QAuditResourceMapping.INSTANCE.defaultAlias()).execute(); - jdbcSession.newDelete(QAuditRefValueMapping.INSTANCE.defaultAlias()).execute(); - jdbcSession.newDelete(QAuditEventRecordMapping.INSTANCE.defaultAlias()).execute(); + jdbcSession.newDelete(QAuditDeltaMapping.get().defaultAlias()).execute(); + jdbcSession.newDelete(QAuditItemMapping.get().defaultAlias()).execute(); + jdbcSession.newDelete(QAuditPropertyValueMapping.get().defaultAlias()).execute(); + jdbcSession.newDelete(QAuditResourceMapping.get().defaultAlias()).execute(); + jdbcSession.newDelete(QAuditRefValueMapping.get().defaultAlias()).execute(); + jdbcSession.newDelete(QAuditEventRecordMapping.get().defaultAlias()).execute(); jdbcSession.commit(); } } @@ -168,7 +168,7 @@ private ObjectDeltaOperation createObjectDeltaOperation(int i) throws Excepti } private MAuditEventRecord assertAndReturnAuditEventRecord(int expectedCount) { - List records = select(QAuditEventRecordMapping.INSTANCE); + List records = select(QAuditEventRecordMapping.get()); AssertJUnit.assertEquals(expectedCount, records.size()); return records.get(0); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceFactory.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceFactory.java index 3cb7af8244f..e15f9d7499d 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceFactory.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceFactory.java @@ -27,10 +27,7 @@ import com.evolveum.midpoint.repo.sql.audit.mapping.*; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditEventRecord; import com.evolveum.midpoint.repo.sql.helpers.BaseHelper; -import com.evolveum.midpoint.repo.sqlbase.DataSourceFactory; -import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; -import com.evolveum.midpoint.repo.sqlbase.SqlTableMetadata; +import com.evolveum.midpoint.repo.sqlbase.*; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryModelMappingRegistry; import com.evolveum.midpoint.schema.SchemaService; import com.evolveum.midpoint.util.exception.SystemException; @@ -81,15 +78,6 @@ public synchronized void init(@NotNull Configuration configuration) throws Audit private SqlRepoContext createSqlRepoContext(Configuration configuration) throws RepositoryServiceFactoryException { - final QueryModelMappingRegistry auditModelMapping = new QueryModelMappingRegistry() - .register(AuditEventRecordType.COMPLEX_TYPE, QAuditEventRecordMapping.INSTANCE) - .register(QAuditItemMapping.INSTANCE) - .register(QAuditPropertyValueMapping.INSTANCE) - .register(QAuditRefValueMapping.INSTANCE) - .register(QAuditResourceMapping.INSTANCE) - .register(QAuditDeltaMapping.INSTANCE) - .seal(); - // one of these properties must be present to trigger separate audit datasource config if (configuration.getString(PROPERTY_JDBC_URL) == null && configuration.getString(PROPERTY_DATASOURCE) == null) { @@ -97,8 +85,10 @@ private SqlRepoContext createSqlRepoContext(Configuration configuration) // NOTE: If default BaseHelper is used, it's used to configure PerformanceMonitor // in SqlBaseService. Perhaps the base class is useless and these factories can provide // PerformanceMonitor for the services. - return new SqlRepoContext(defaultBaseHelper.getConfiguration(), - defaultBaseHelper.dataSource(), schemaService, auditModelMapping); + return createSqlRepoContext( + defaultBaseHelper.getConfiguration(), + defaultBaseHelper.dataSource(), + schemaService); } LOGGER.info("Configuring SQL audit service to use a different datasource"); @@ -110,7 +100,28 @@ private SqlRepoContext createSqlRepoContext(Configuration configuration) DataSourceFactory dataSourceFactory = new DataSourceFactory(config); DataSource dataSource = dataSourceFactory.createDataSource(); - return new SqlRepoContext(config, dataSource, schemaService, auditModelMapping); + return createSqlRepoContext(config, dataSource, schemaService); + } + + private SqlRepoContext createSqlRepoContext( + JdbcRepositoryConfiguration config, + DataSource dataSource, + SchemaService schemaService) { + QueryModelMappingRegistry mappingRegistry = new QueryModelMappingRegistry(); + SqlRepoContext repositoryContext = + new SqlRepoContext(config, dataSource, schemaService, mappingRegistry); + // Registered mapping needs repository context which needs registry - but we fill it now: + mappingRegistry + .register(AuditEventRecordType.COMPLEX_TYPE, + QAuditEventRecordMapping.init(repositoryContext)) + .register(QAuditItemMapping.init(repositoryContext)) + .register(QAuditPropertyValueMapping.init(repositoryContext)) + .register(QAuditRefValueMapping.init(repositoryContext)) + .register(QAuditResourceMapping.init(repositoryContext)) + .register(QAuditDeltaMapping.init(repositoryContext)) + .seal(); + + return repositoryContext; } private void initCustomColumns( @@ -142,7 +153,7 @@ private void initCustomColumns( ColumnMetadata columnMetadata = ColumnMetadata.named(columnName).ofType(Types.NVARCHAR).withSize(255); - QAuditEventRecordMapping.INSTANCE.addExtensionColumn(propertyName, columnMetadata); + QAuditEventRecordMapping.get().addExtensionColumn(propertyName, columnMetadata); if (tableMetadata != null && tableMetadata.get(columnName) == null) { // Fails on SQL Server with snapshot transaction, so different isolation is used. try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession() diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java index 7d265373196..ad4a2ffc2e0 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java @@ -174,7 +174,7 @@ private void auditAttempt(AuditEventRecord record) { */ private Long insertAuditEventRecord( JdbcSession jdbcSession, AuditEventRecord record) { - QAuditEventRecordMapping aerMapping = QAuditEventRecordMapping.INSTANCE; + QAuditEventRecordMapping aerMapping = QAuditEventRecordMapping.get(); QAuditEventRecord aer = aerMapping.defaultAlias(); MAuditEventRecord aerBean = aerMapping.toRowObject(record); SQLInsertClause insert = jdbcSession.newInsert(aer).populate(aerBean); @@ -208,7 +208,7 @@ private Collection insertAuditDeltas( if (!deltasByChecksum.isEmpty()) { SQLInsertClause insertBatch = jdbcSession.newInsert( - QAuditDeltaMapping.INSTANCE.defaultAlias()); + QAuditDeltaMapping.get().defaultAlias()); for (MAuditDelta value : deltasByChecksum.values()) { // NULLs are important to keep the value count consistent during the batch insertBatch.populate(value, DefaultMapper.WITH_NULL_BINDINGS).addBatch(); @@ -300,7 +300,7 @@ private void insertChangedItemPaths( } } if (!changedItemPaths.isEmpty()) { - QAuditItem qAuditItem = QAuditItemMapping.INSTANCE.defaultAlias(); + QAuditItem qAuditItem = QAuditItemMapping.get().defaultAlias(); SQLInsertClause insertBatch = jdbcSession.newInsert(qAuditItem); for (String changedItemPath : changedItemPaths) { insertBatch.set(qAuditItem.recordId, recordId) @@ -318,7 +318,7 @@ private void insertProperties( return; } - QAuditPropertyValue qAuditPropertyValue = QAuditPropertyValueMapping.INSTANCE.defaultAlias(); + QAuditPropertyValue qAuditPropertyValue = QAuditPropertyValueMapping.get().defaultAlias(); SQLInsertClause insertBatch = jdbcSession.newInsert(qAuditPropertyValue); for (String propertyName : properties.keySet()) { for (String propertyValue : properties.get(propertyName)) { @@ -343,7 +343,7 @@ private void insertReferences(JdbcSession jdbcSession, return; } - QAuditRefValue qAuditRefValue = QAuditRefValueMapping.INSTANCE.defaultAlias(); + QAuditRefValue qAuditRefValue = QAuditRefValueMapping.get().defaultAlias(); SQLInsertClause insertBatch = jdbcSession.newInsert(qAuditRefValue); for (String refName : references.keySet()) { for (AuditReferenceValue refValue : references.get(refName)) { @@ -372,7 +372,7 @@ private void insertResourceOids( return; } - QAuditResource qAuditResource = QAuditResourceMapping.INSTANCE.defaultAlias(); + QAuditResource qAuditResource = QAuditResourceMapping.get().defaultAlias(); SQLInsertClause insertBatch = jdbcSession.newInsert(qAuditResource); for (String resourceOid : resourceOids) { insertBatch.set(qAuditResource.recordId, recordId) @@ -496,7 +496,7 @@ private AuditEventRecord createAuditEventRecordAggregate( throws SQLException { AuditEventRecord audit = createAuditEventRecord(resultList); final Map customColumns = - QAuditEventRecordMapping.INSTANCE.getExtensionColumns(); + QAuditEventRecordMapping.get().getExtensionColumns(); for (Entry entry : customColumns.entrySet()) { audit.getCustomColumnProperty().put(entry.getKey(), resultList.getString(entry.getValue().getName())); @@ -974,7 +974,7 @@ private int batchDeletionAttempt( private int selectRecordsByMaxAge( JdbcSession jdbcSession, String tempTable, Date minValue) { - QAuditEventRecord aer = QAuditEventRecordMapping.INSTANCE.defaultAlias(); + QAuditEventRecord aer = QAuditEventRecordMapping.get().defaultAlias(); SQLQuery populateQuery = jdbcSession.newQuery() .select(aer.id) .from(aer) @@ -989,7 +989,7 @@ private int selectRecordsByMaxAge( private int selectRecordsByNumberToKeep( JdbcSession jdbcSession, String tempTable, int recordsToKeep) { - QAuditEventRecord aer = QAuditEventRecordMapping.INSTANCE.defaultAlias(); + QAuditEventRecord aer = QAuditEventRecordMapping.get().defaultAlias(); long totalAuditRecords = jdbcSession.newQuery().from(aer).fetchCount(); // we will find the number to delete and limit it to range [0,CLEANUP_AUDIT_BATCH_SIZE] diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java index bd1b6ee3bdf..e1bbe198867 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/AuditTableMapping.java @@ -28,8 +28,13 @@ public abstract class AuditTableMapping, R> extends QueryTableMapping { - protected AuditTableMapping(@NotNull String tableName, @NotNull String defaultAliasName, @NotNull Class schemaType, @NotNull Class queryType) { - super(tableName, defaultAliasName, schemaType, queryType); + protected AuditTableMapping( + @NotNull String tableName, + @NotNull String defaultAliasName, + @NotNull Class schemaType, + @NotNull Class queryType, + @NotNull SqlRepoContext repositoryContext) { + super(tableName, defaultAliasName, schemaType, queryType, repositoryContext); } @Override diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java index 776e0e41127..bcf7e09661c 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java @@ -10,11 +10,13 @@ import com.querydsl.sql.SQLServerTemplates; import com.querydsl.sql.SQLTemplates; +import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.repo.sql.audit.beans.MAuditDelta; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditDelta; import com.evolveum.midpoint.repo.sql.util.RUtil; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectDeltaOperationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; @@ -29,11 +31,20 @@ public class QAuditDeltaMapping public static final String DEFAULT_ALIAS_NAME = "ad"; - public static final QAuditDeltaMapping INSTANCE = new QAuditDeltaMapping(); + private static QAuditDeltaMapping instance; - private QAuditDeltaMapping() { + public static QAuditDeltaMapping init(@NotNull SqlRepoContext repositoryContext) { + instance = new QAuditDeltaMapping(repositoryContext); + return instance; + } + + public static QAuditDeltaMapping get() { + return instance; + } + + private QAuditDeltaMapping(@NotNull SqlRepoContext repositoryContext) { super(TABLE_NAME, DEFAULT_ALIAS_NAME, - ObjectDeltaOperationType.class, QAuditDelta.class); + ObjectDeltaOperationType.class, QAuditDelta.class, repositoryContext); } @Override diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java index 84d889c7d89..6b5855da59c 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java @@ -15,6 +15,7 @@ import javax.xml.namespace.QName; import com.querydsl.core.Tuple; +import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.prism.PrismReferenceValue; @@ -28,6 +29,7 @@ import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventType; import com.evolveum.midpoint.repo.sql.data.common.enums.ROperationResultStatus; import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.filtering.item.CanonicalItemPathItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.DetailTableItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.EnumOrdinalItemFilterProcessor; @@ -47,11 +49,20 @@ public class QAuditEventRecordMapping public static final String DEFAULT_ALIAS_NAME = "aer"; - public static final QAuditEventRecordMapping INSTANCE = new QAuditEventRecordMapping(); + private static QAuditEventRecordMapping instance; - private QAuditEventRecordMapping() { + public static QAuditEventRecordMapping init(@NotNull SqlRepoContext repositoryContext) { + instance = new QAuditEventRecordMapping(repositoryContext); + return instance; + } + + public static QAuditEventRecordMapping get() { + return instance; + } + + private QAuditEventRecordMapping(@NotNull SqlRepoContext repositoryContext) { super(TABLE_NAME, DEFAULT_ALIAS_NAME, - AuditEventRecordType.class, QAuditEventRecord.class); + AuditEventRecordType.class, QAuditEventRecord.class, repositoryContext); addItemMapping(F_REPO_ID, longMapper(q -> q.id)); addItemMapping(F_CHANNEL, stringMapper(q -> q.channel)); @@ -189,7 +200,7 @@ private void mapDeltas(AuditEventRecordType record, List deltas) { } for (MAuditDelta delta : deltas) { - record.delta(QAuditDeltaMapping.INSTANCE.toSchemaObject(delta)); + record.delta(QAuditDeltaMapping.get().toSchemaObject(delta)); } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java index cc38d987160..17a28f00fe1 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java @@ -8,8 +8,11 @@ import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditItem.TABLE_NAME; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sql.audit.beans.MAuditItem; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditItem; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; /** @@ -20,11 +23,20 @@ public class QAuditItemMapping public static final String DEFAULT_ALIAS_NAME = "ai"; - public static final QAuditItemMapping INSTANCE = new QAuditItemMapping(); + private static QAuditItemMapping instance; + + public static QAuditItemMapping init(@NotNull SqlRepoContext repositoryContext) { + instance = new QAuditItemMapping(repositoryContext); + return instance; + } + + public static QAuditItemMapping get() { + return instance; + } - private QAuditItemMapping() { + private QAuditItemMapping(@NotNull SqlRepoContext repositoryContext) { super(TABLE_NAME, DEFAULT_ALIAS_NAME, - ItemPathType.class, QAuditItem.class); + ItemPathType.class, QAuditItem.class, repositoryContext); } @Override diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java index 36f9a15c9fc..86e52f2bc14 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java @@ -8,8 +8,11 @@ import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditPropertyValue.TABLE_NAME; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sql.audit.beans.MAuditPropertyValue; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditPropertyValue; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordPropertyType; /** @@ -20,11 +23,20 @@ public class QAuditPropertyValueMapping public static final String DEFAULT_ALIAS_NAME = "apv"; - public static final QAuditPropertyValueMapping INSTANCE = new QAuditPropertyValueMapping(); + private static QAuditPropertyValueMapping instance; + + public static QAuditPropertyValueMapping init(@NotNull SqlRepoContext repositoryContext) { + instance = new QAuditPropertyValueMapping(repositoryContext); + return instance; + } + + public static QAuditPropertyValueMapping get() { + return instance; + } - private QAuditPropertyValueMapping() { + private QAuditPropertyValueMapping(@NotNull SqlRepoContext repositoryContext) { super(TABLE_NAME, DEFAULT_ALIAS_NAME, - AuditEventRecordPropertyType.class, QAuditPropertyValue.class); + AuditEventRecordPropertyType.class, QAuditPropertyValue.class, repositoryContext); } @Override diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java index 15396686744..bc3e5ec0891 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java @@ -8,8 +8,11 @@ import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditItem.TABLE_NAME; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sql.audit.beans.MAuditRefValue; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditRefValue; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordReferenceType; /** @@ -20,11 +23,20 @@ public class QAuditRefValueMapping public static final String DEFAULT_ALIAS_NAME = "aref"; - public static final QAuditRefValueMapping INSTANCE = new QAuditRefValueMapping(); + private static QAuditRefValueMapping instance; + + public static QAuditRefValueMapping init(@NotNull SqlRepoContext repositoryContext) { + instance = new QAuditRefValueMapping(repositoryContext); + return instance; + } + + public static QAuditRefValueMapping get() { + return instance; + } - private QAuditRefValueMapping() { + private QAuditRefValueMapping(@NotNull SqlRepoContext repositoryContext) { super(TABLE_NAME, DEFAULT_ALIAS_NAME, - AuditEventRecordReferenceType.class, QAuditRefValue.class); + AuditEventRecordReferenceType.class, QAuditRefValue.class, repositoryContext); } @Override diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java index 34898aed5bf..c72605edbc5 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java @@ -8,8 +8,11 @@ import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditItem.TABLE_NAME; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sql.audit.beans.MAuditResource; import com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditResource; +import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; /** * Mapping for {@link QAuditResource}. @@ -19,11 +22,20 @@ public class QAuditResourceMapping public static final String DEFAULT_ALIAS_NAME = "ares"; - public static final QAuditResourceMapping INSTANCE = new QAuditResourceMapping(); + private static QAuditResourceMapping instance; + + public static QAuditResourceMapping init(@NotNull SqlRepoContext repositoryContext) { + instance = new QAuditResourceMapping(repositoryContext); + return instance; + } + + public static QAuditResourceMapping get() { + return instance; + } - private QAuditResourceMapping() { + private QAuditResourceMapping(@NotNull SqlRepoContext repositoryContext) { super(TABLE_NAME, DEFAULT_ALIAS_NAME, - String.class, QAuditResource.class); + String.class, QAuditResource.class, repositoryContext); } @Override diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java index 5e6e65a2427..1936b8b1823 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlRepoContext.java @@ -37,8 +37,6 @@ */ public class SqlRepoContext { - private static SqlRepoContext instance; - private final JdbcRepositoryConfiguration jdbcRepositoryConfiguration; protected final Configuration querydslConfig; protected final SchemaService schemaService; @@ -56,14 +54,6 @@ public SqlRepoContext( this.schemaService = schemaService; this.mappingRegistry = mappingRegistry; this.dataSource = dataSource; - - // TODO later inject directly into mappers - instance = this; - } - - @Deprecated - public static SqlRepoContext getInstance() { - return instance; } public SQLQuery newQuery() { diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java index 9b9dd85af01..a8d69609b3f 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/QueryTableMapping.java @@ -60,6 +60,10 @@ * That's why these methods have flexible schema type parameter. * Because such nested mapping still uses the same table, types `Q` and `R` remain the same. * + * Mapping for tables is initialized once and requires {@link SqlRepoContext}. + * The mapping is accessible by static `get()` method; if multiple mapping instances exist + * for the same type the method uses suffix to differentiate them. + * * @param schema type * @param type of entity path * @param row type related to the {@link Q} @@ -102,29 +106,6 @@ protected QueryTableMapping( this.repositoryContext = repositoryContext; } - /** - * Creates metamodel for the table described by designated type (Q-class) related to schema type. - * Allows registration of any number of columns - typically used for static properties - * (non-extensions). - * - * @param tableName database table name - * @param defaultAliasName default alias name, some short abbreviation, must be unique - * across mapped types - */ - @Deprecated - protected QueryTableMapping( - @NotNull String tableName, - @NotNull String defaultAliasName, - @NotNull Class schemaType, - @NotNull Class queryType) { - super(schemaType, queryType); - this.tableName = tableName; - this.defaultAliasName = defaultAliasName; - - // TODO remove this constructor, use the one above only - this.repositoryContext = null; - } - /** * Returns the mapper creating the string filter processor from context. * @@ -247,10 +228,7 @@ public String defaultAliasName() { } public SqlRepoContext repositoryContext() { - return repositoryContext != null - ? repositoryContext - // TODO remove this branch - : SqlRepoContext.getInstance(); + return repositoryContext; } /** From 1f361869f53c515be8bdb5d8f7b596dcfe55ff78 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Mon, 3 May 2021 17:57:04 +0200 Subject: [PATCH 15/33] repo-sqlbase: mappings use constructor injection for repo context Previous static final instances are gone, private static instances are available for some mappings, the rest is accessible only via registry. --- .../midpoint/repo/sqale/SqaleRepoContext.java | 9 - .../repo/sqale/SqaleRepositoryBeanConfig.java | 96 +++++---- .../sqale/qmodel/QObjectTemplateMapping.java | 13 +- .../repo/sqale/qmodel/SqaleMappingMixin.java | 2 + .../repo/sqale/qmodel/SqaleTableMapping.java | 24 ++- ...QAccessCertificationDefinitionMapping.java | 12 +- .../qmodel/assignment/QAssignmentMapping.java | 68 ++++-- .../QAssignmentReferenceMapping.java | 55 ++++- .../repo/sqale/qmodel/cases/QCaseMapping.java | 11 +- .../qmodel/common/QContainerMapping.java | 16 +- .../connector/QConnectorHostMapping.java | 9 +- .../qmodel/connector/QConnectorMapping.java | 10 +- .../sqale/qmodel/focus/QFocusMapping.java | 34 ++- .../qmodel/focus/QGenericObjectMapping.java | 9 +- .../repo/sqale/qmodel/focus/QUserMapping.java | 9 +- .../lookuptable/QLookupTableMapping.java | 14 +- .../lookuptable/QLookupTableRowMapping.java | 22 +- .../repo/sqale/qmodel/node/QNodeMapping.java | 10 +- .../object/QAssignmentHolderMapping.java | 12 +- .../sqale/qmodel/object/QObjectMapping.java | 115 +++------- .../object/QOperationExecutionMapping.java | 25 ++- .../sqale/qmodel/object/QTriggerMapping.java | 24 ++- .../sqale/qmodel/other/QDashboardMapping.java | 11 +- .../repo/sqale/qmodel/other/QFormMapping.java | 11 +- .../qmodel/other/QFunctionLibraryMapping.java | 11 +- .../other/QObjectCollectionMapping.java | 11 +- .../sqale/qmodel/other/QSequenceMapping.java | 11 +- .../qmodel/ref/QObjectReferenceMapping.java | 197 +++++++++++++++--- .../sqale/qmodel/ref/QReferenceMapping.java | 23 +- .../qmodel/report/QReportDataMapping.java | 9 +- .../sqale/qmodel/report/QReportMapping.java | 9 +- .../qmodel/resource/QResourceMapping.java | 15 +- .../qmodel/role/QAbstractRoleMapping.java | 26 +-- .../sqale/qmodel/role/QArchetypeMapping.java | 11 +- .../repo/sqale/qmodel/role/QRoleMapping.java | 9 +- .../sqale/qmodel/role/QServiceMapping.java | 9 +- .../sqale/qmodel/shadow/QShadowMapping.java | 10 +- .../qmodel/system/QSecurityPolicyMapping.java | 11 +- .../system/QSystemConfigurationMapping.java | 11 +- .../qmodel/system/QValuePolicyMapping.java | 11 +- .../repo/sqale/qmodel/task/QTaskMapping.java | 9 +- .../func/SqaleRepoAddDeleteObjectTest.java | 10 +- .../sqale/func/SqaleRepoModifyObjectTest.java | 40 ++-- .../sql/audit/mapping/QAuditDeltaMapping.java | 4 +- .../mapping/QAuditEventRecordMapping.java | 3 +- .../sql/audit/mapping/QAuditItemMapping.java | 4 +- .../mapping/QAuditPropertyValueMapping.java | 4 +- .../audit/mapping/QAuditRefValueMapping.java | 4 +- .../audit/mapping/QAuditResourceMapping.java | 4 +- 49 files changed, 716 insertions(+), 371 deletions(-) diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java index d81ecd98e71..bfbc3dccb50 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java @@ -30,8 +30,6 @@ */ public class SqaleRepoContext extends SqlRepoContext { - private static SqaleRepoContext instance; - private final UriCache uriCache; public SqaleRepoContext( @@ -65,13 +63,6 @@ public SqaleRepoContext( querydslConfig.register(new QuerydslJsonbType()); uriCache = new UriCache(); - - instance = this; - } - - @Deprecated - public static SqaleRepoContext getInstance() { - return instance; } // This has nothing to do with "repo cache" which is higher than this. diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java index 50b9da2b697..408168f3cf4 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java @@ -112,52 +112,64 @@ public SqaleRepoContext sqlRepoContext( SqaleRepositoryConfiguration repositoryConfiguration, SchemaService schemaService, DataSource dataSource) { - QueryModelMappingRegistry mappingRegistry = new QueryModelMappingRegistry() - // ordered alphabetically here, mappings without schema type at the end - .register(AbstractRoleType.COMPLEX_TYPE, QAbstractRoleMapping.INSTANCE) + QueryModelMappingRegistry mappingRegistry = new QueryModelMappingRegistry(); + SqaleRepoContext repositoryContext = new SqaleRepoContext( + repositoryConfiguration, dataSource, schemaService, mappingRegistry); + + // Registered mapping needs repository context which needs registry. Now we can fill it. + // Mappings are ordered alphabetically here, mappings without schema type are at the end. + mappingRegistry + .register(AbstractRoleType.COMPLEX_TYPE, + QAbstractRoleMapping.init(repositoryContext)) .register(AccessCertificationDefinitionType.COMPLEX_TYPE, - QAccessCertificationDefinitionMapping.INSTANCE) - .register(ArchetypeType.COMPLEX_TYPE, QArchetypeMapping.INSTANCE) - .register(AssignmentHolderType.COMPLEX_TYPE, QAssignmentHolderMapping.INSTANCE) - .register(AssignmentType.COMPLEX_TYPE, QAssignmentMapping.INSTANCE) - .register(CaseType.COMPLEX_TYPE, QCaseMapping.INSTANCE) - .register(DashboardType.COMPLEX_TYPE, QDashboardMapping.INSTANCE) - .register(FocusType.COMPLEX_TYPE, QFocusMapping.INSTANCE) - .register(FormType.COMPLEX_TYPE, QFormMapping.INSTANCE) - .register(FunctionLibraryType.COMPLEX_TYPE, QFunctionLibraryMapping.INSTANCE) - .register(ConnectorType.COMPLEX_TYPE, QConnectorMapping.INSTANCE) - .register(ConnectorHostType.COMPLEX_TYPE, QConnectorHostMapping.INSTANCE) - .register(GenericObjectType.COMPLEX_TYPE, QGenericObjectMapping.INSTANCE) - .register(LookupTableType.COMPLEX_TYPE, QLookupTableMapping.INSTANCE) - .register(LookupTableRowType.COMPLEX_TYPE, QLookupTableRowMapping.INSTANCE) - .register(NodeType.COMPLEX_TYPE, QNodeMapping.INSTANCE) - .register(ObjectType.COMPLEX_TYPE, QObjectMapping.INSTANCE) - .register(ObjectTemplateType.COMPLEX_TYPE, QObjectTemplateMapping.INSTANCE) - .register(ObjectCollectionType.COMPLEX_TYPE, QObjectCollectionMapping.INSTANCE) - .register(OperationExecutionType.COMPLEX_TYPE, QOperationExecutionMapping.INSTANCE) - .register(ReportType.COMPLEX_TYPE, QReportMapping.INSTANCE) - .register(ReportDataType.COMPLEX_TYPE, QReportDataMapping.INSTANCE) - .register(ResourceType.COMPLEX_TYPE, QResourceMapping.INSTANCE) - .register(RoleType.COMPLEX_TYPE, QRoleMapping.INSTANCE) - .register(SecurityPolicyType.COMPLEX_TYPE, QSecurityPolicyMapping.INSTANCE) - .register(SequenceType.COMPLEX_TYPE, QSequenceMapping.INSTANCE) - .register(ServiceType.COMPLEX_TYPE, QServiceMapping.INSTANCE) - .register(ShadowType.COMPLEX_TYPE, QShadowMapping.INSTANCE) + QAccessCertificationDefinitionMapping.init(repositoryContext)) + .register(ArchetypeType.COMPLEX_TYPE, QArchetypeMapping.init(repositoryContext)) + .register(AssignmentHolderType.COMPLEX_TYPE, + QAssignmentHolderMapping.init(repositoryContext)) + .register(AssignmentType.COMPLEX_TYPE, + QAssignmentMapping.initAssignment(repositoryContext)) + .register(CaseType.COMPLEX_TYPE, QCaseMapping.init(repositoryContext)) + .register(DashboardType.COMPLEX_TYPE, QDashboardMapping.init(repositoryContext)) + .register(FocusType.COMPLEX_TYPE, QFocusMapping.init(repositoryContext)) + .register(FormType.COMPLEX_TYPE, QFormMapping.init(repositoryContext)) + .register(FunctionLibraryType.COMPLEX_TYPE, + QFunctionLibraryMapping.init(repositoryContext)) + .register(ConnectorType.COMPLEX_TYPE, QConnectorMapping.init(repositoryContext)) + .register(ConnectorHostType.COMPLEX_TYPE, + QConnectorHostMapping.init(repositoryContext)) + .register(GenericObjectType.COMPLEX_TYPE, + QGenericObjectMapping.init(repositoryContext)) + .register(LookupTableType.COMPLEX_TYPE, QLookupTableMapping.init(repositoryContext)) + .register(LookupTableRowType.COMPLEX_TYPE, + QLookupTableRowMapping.init(repositoryContext)) + .register(NodeType.COMPLEX_TYPE, QNodeMapping.init(repositoryContext)) + .register(ObjectType.COMPLEX_TYPE, QObjectMapping.init(repositoryContext)) + .register(ObjectCollectionType.COMPLEX_TYPE, + QObjectCollectionMapping.init(repositoryContext)) + .register(ObjectTemplateType.COMPLEX_TYPE, + QObjectTemplateMapping.init(repositoryContext)) + .register(OperationExecutionType.COMPLEX_TYPE, + QOperationExecutionMapping.init(repositoryContext)) + .register(ReportType.COMPLEX_TYPE, QReportMapping.init(repositoryContext)) + .register(ReportDataType.COMPLEX_TYPE, QReportDataMapping.init(repositoryContext)) + .register(ResourceType.COMPLEX_TYPE, QResourceMapping.init(repositoryContext)) + .register(RoleType.COMPLEX_TYPE, QRoleMapping.init(repositoryContext)) + .register(SecurityPolicyType.COMPLEX_TYPE, + QSecurityPolicyMapping.init(repositoryContext)) + .register(SequenceType.COMPLEX_TYPE, QSequenceMapping.init(repositoryContext)) + .register(ServiceType.COMPLEX_TYPE, QServiceMapping.init(repositoryContext)) + .register(ShadowType.COMPLEX_TYPE, QShadowMapping.init(repositoryContext)) .register(SystemConfigurationType.COMPLEX_TYPE, - QSystemConfigurationMapping.INSTANCE) - .register(TaskType.COMPLEX_TYPE, QTaskMapping.INSTANCE) - .register(TriggerType.COMPLEX_TYPE, QTriggerMapping.INSTANCE) - .register(UserType.COMPLEX_TYPE, QUserMapping.INSTANCE) - .register(ValuePolicyType.COMPLEX_TYPE, QValuePolicyMapping.INSTANCE) - .register(QContainerMapping.INSTANCE) - .register(QReferenceMapping.INSTANCE) + QSystemConfigurationMapping.init(repositoryContext)) + .register(TaskType.COMPLEX_TYPE, QTaskMapping.init(repositoryContext)) + .register(TriggerType.COMPLEX_TYPE, QTriggerMapping.init(repositoryContext)) + .register(UserType.COMPLEX_TYPE, QUserMapping.init(repositoryContext)) + .register(ValuePolicyType.COMPLEX_TYPE, QValuePolicyMapping.init(repositoryContext)) + .register(QContainerMapping.initContainerMapping(repositoryContext)) + .register(QReferenceMapping.init(repositoryContext)) .seal(); - return new SqaleRepoContext( - repositoryConfiguration, - dataSource, - schemaService, - mappingRegistry); + return repositoryContext; } @Bean diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java index f492dfda53f..7bf93c339ee 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; @@ -24,13 +25,15 @@ public class QObjectTemplateMapping public static final String DEFAULT_ALIAS_NAME = "ot"; - public static final QObjectTemplateMapping INSTANCE = new QObjectTemplateMapping(); + public static QObjectTemplateMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QObjectTemplateMapping(repositoryContext); + } - private QObjectTemplateMapping() { + private QObjectTemplateMapping(@NotNull SqaleRepoContext repositoryContext) { super(QObjectTemplate.TABLE_NAME, DEFAULT_ALIAS_NAME, - ObjectTemplateType.class, QObjectTemplate.class); + ObjectTemplateType.class, QObjectTemplate.class, repositoryContext); - addRefMapping(F_INCLUDE_REF, QObjectReferenceMapping.INSTANCE_INCLUDE); + addRefMapping(F_INCLUDE_REF, QObjectReferenceMapping.initForInclude(repositoryContext)); } @Override @@ -49,6 +52,6 @@ public void storeRelatedEntities(@NotNull MObject row, super.storeRelatedEntities(row, schemaObject, jdbcSession); storeRefs(row, schemaObject.getIncludeRef(), - QObjectReferenceMapping.INSTANCE_INCLUDE, jdbcSession); + QObjectReferenceMapping.getForInclude(), jdbcSession); } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleMappingMixin.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleMappingMixin.java index f9f7a8fdf78..dc005cf2743 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleMappingMixin.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleMappingMixin.java @@ -1,5 +1,6 @@ package com.evolveum.midpoint.repo.sqale.qmodel; +import java.util.Objects; import java.util.function.BiFunction; import javax.xml.namespace.QName; @@ -65,6 +66,7 @@ default SqaleNestedMapping addNestedMapping( /** Defines reference mapping for both query and modifications. */ default SqaleMappingMixin addRefMapping( @NotNull QName itemName, @NotNull QReferenceMapping referenceMapping) { + Objects.requireNonNull(referenceMapping, "referenceMapping"); addItemMapping(itemName, new SqaleItemSqlMapper<>( ctx -> new RefTableItemFilterProcessor<>(ctx, referenceMapping), ctx -> new RefTableItemDeltaProcessor<>(ctx, referenceMapping))); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java index ce1401d7d75..d5d836e7fb0 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java @@ -30,11 +30,11 @@ import com.evolveum.midpoint.repo.sqale.qmodel.ref.MReference; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; -import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.filtering.item.EnumItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.PolyStringItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.SimpleItemFilterProcessor; import com.evolveum.midpoint.repo.sqlbase.filtering.item.TimestampItemFilterProcessor; +import com.evolveum.midpoint.repo.sqlbase.mapping.QueryModelMappingRegistry; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; import com.evolveum.midpoint.repo.sqlbase.querydsl.UuidPath; @@ -50,6 +50,19 @@ * Mapping superclass with common functions for {@link QObject} and non-objects (e.g. containers). * See javadoc in {@link QueryTableMapping} for more. * + * Mappings are often initialized using static `init*(repositoryContext)` methods, various + * suffixes are used for these reasons: + * + * * To differentiate various instances for the same mapping type, e.g. various references + * stored in separate tables; + * * or to avoid return type clash of the `init` method, even though they are static + * and technically independent Java meddles too much. + * + * Some subclasses (typically containers and refs) track their instances and avoid unnecessary + * instance creation for the same init method; the instance is available via matching `get*()`. + * Other subclasses (most objects) don't have `get()` methods but can be obtained using + * {@link QueryModelMappingRegistry#getByQueryType(Class)}, or by schema type (e.g. in tests). + * * @param schema type * @param type of entity path * @param row type related to the {@link Q} @@ -64,17 +77,12 @@ protected SqaleTableMapping( @NotNull String defaultAliasName, @NotNull Class schemaType, @NotNull Class queryType, - @NotNull SqlRepoContext repositoryContext) { + @NotNull SqaleRepoContext repositoryContext) { super(tableName, defaultAliasName, schemaType, queryType, repositoryContext); } public SqaleRepoContext repositoryContext() { -// return (SqaleRepoContext) super.repositoryContext(); - // TODO remove this version when mapping is provided properly in config - SqaleRepoContext repositoryContext = (SqaleRepoContext) super.repositoryContext(); - return repositoryContext != null - ? repositoryContext - : SqaleRepoContext.getInstance(); + return (SqaleRepoContext) super.repositoryContext(); } /** diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java index 450f04ee3e3..0c782c0d664 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.util.MiscUtil; @@ -25,12 +26,15 @@ public class QAccessCertificationDefinitionMapping public static final String DEFAULT_ALIAS_NAME = "acd"; - public static final QAccessCertificationDefinitionMapping INSTANCE = - new QAccessCertificationDefinitionMapping(); + public static QAccessCertificationDefinitionMapping init( + @NotNull SqaleRepoContext repositoryContext) { + return new QAccessCertificationDefinitionMapping(repositoryContext); + } - private QAccessCertificationDefinitionMapping() { + private QAccessCertificationDefinitionMapping(@NotNull SqaleRepoContext repositoryContext) { super(QAccessCertificationDefinition.TABLE_NAME, DEFAULT_ALIAS_NAME, - AccessCertificationDefinitionType.class, QAccessCertificationDefinition.class); + AccessCertificationDefinitionType.class, QAccessCertificationDefinition.class, + repositoryContext); addItemMapping(F_HANDLER_URI, uriMapper(q -> q.handlerUriId)); addItemMapping(F_LAST_CAMPAIGN_STARTED_TIMESTAMP, diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java index f6d7928c836..b66cda08b24 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java @@ -8,11 +8,14 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType.*; +import java.util.Objects; + +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainerType; import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping; -import com.evolveum.midpoint.repo.sqale.qmodel.role.MAbstractRole; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; @@ -35,20 +38,48 @@ public class QAssignmentMapping public static final String DEFAULT_ALIAS_NAME = "a"; /** Default assignment mapping instance, for queries it works for inducements too. */ - public static final QAssignmentMapping INSTANCE = - new QAssignmentMapping<>(MContainerType.ASSIGNMENT); + private static QAssignmentMapping instanceAssignment; /** Inducement mapping instance, this must be used for inserting inducements. */ - public static final QAssignmentMapping INSTANCE_INDUCEMENT = - new QAssignmentMapping<>(MContainerType.INDUCEMENT); + private static QAssignmentMapping instanceInducement; + + public static QAssignmentMapping + initAssignment(@NotNull SqaleRepoContext repositoryContext) { + if (instanceAssignment == null) { + instanceAssignment = new QAssignmentMapping<>( + MContainerType.ASSIGNMENT, repositoryContext); + } + return getAssignment(); + } + + public static QAssignmentMapping getAssignment() { + //noinspection unchecked + return (QAssignmentMapping) Objects.requireNonNull(instanceAssignment); + } + + public static QAssignmentMapping + initInducement(@NotNull SqaleRepoContext repositoryContext) { + if (instanceInducement == null) { + instanceInducement = new QAssignmentMapping<>( + MContainerType.INDUCEMENT, repositoryContext); + } + return getInducement(); + } + + public static QAssignmentMapping getInducement() { + //noinspection unchecked + return (QAssignmentMapping) Objects.requireNonNull(instanceInducement); + } private final MContainerType containerType; // We can't declare Class>.class, so we cheat a bit. @SuppressWarnings({ "unchecked", "rawtypes" }) - private QAssignmentMapping(MContainerType containerType) { + private QAssignmentMapping( + @NotNull MContainerType containerType, + @NotNull SqaleRepoContext repositoryContext) { super(QAssignment.TABLE_NAME, DEFAULT_ALIAS_NAME, - AssignmentType.class, (Class) QAssignment.class); + AssignmentType.class, (Class) QAssignment.class, repositoryContext); this.containerType = containerType; // TODO OWNER_TYPE is new thing and can help avoid join to concrete object table @@ -112,17 +143,12 @@ private QAssignmentMapping(MContainerType containerType) { uriMapper(q -> q.modifyChannelId)) .addItemMapping(MetadataType.F_MODIFY_TIMESTAMP, timestampMapper(q -> q.modifyTimestamp)) - .addRefMapping(MetadataType.F_CREATE_APPROVER_REF, referenceMapping( - QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_CREATE_APPROVER)) - .addRefMapping(MetadataType.F_MODIFY_APPROVER_REF, referenceMapping( - QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_MODIFY_APPROVER)); - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - private QReferenceMapping, MAssignment> referenceMapping( - QAssignmentReferenceMapping referenceMapping) { - //noinspection unchecked - return (QAssignmentReferenceMapping) referenceMapping; + .addRefMapping(MetadataType.F_CREATE_APPROVER_REF, + QAssignmentReferenceMapping.initForAssignmentCreateApprover( + repositoryContext)) + .addRefMapping(MetadataType.F_MODIFY_APPROVER_REF, + QAssignmentReferenceMapping.initForAssignmentModifyApprover( + repositoryContext)); } @Override @@ -216,9 +242,9 @@ public MAssignment insert(AssignmentType assignment, OR ownerRow, JdbcSession jd if (metadata != null) { storeRefs(row, metadata.getCreateApproverRef(), - QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_CREATE_APPROVER, jdbcSession); + QAssignmentReferenceMapping.getForAssignmentCreateApprover(), jdbcSession); storeRefs(row, metadata.getModifyApproverRef(), - QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_MODIFY_APPROVER, jdbcSession); + QAssignmentReferenceMapping.getForAssignmentModifyApprover(), jdbcSession); } return row; diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentReferenceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentReferenceMapping.java index 56fe38d3f24..a434fd16c0a 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentReferenceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentReferenceMapping.java @@ -6,31 +6,68 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.assignment; +import java.util.Objects; import java.util.function.BiFunction; import com.querydsl.core.types.Predicate; +import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; -import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReference; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; /** - * Mapping between {@link QObjectReference} and {@link ObjectReferenceType}. - * The mapping is the same for all subtypes, see different `INSTANCE_*` constants below. + * Mapping between {@link QAssignmentReference} and {@link ObjectReferenceType}. + * The mapping is the same for all subtypes, see various static `get*()` methods below. + * Both mapping instances are initialized (`init*()` methods) in {@link QAssignmentMapping}. + * Init methods can be called multiple times, only one instance for each sub-tables is created. * * @param type of the row (M-bean) of the assignment owner */ public class QAssignmentReferenceMapping extends QReferenceMapping, MAssignment> { - public static final QAssignmentReferenceMapping INSTANCE_ASSIGNMENT_CREATE_APPROVER = - new QAssignmentReferenceMapping<>("m_assignment_ref_create_approver", "arefca"); - public static final QAssignmentReferenceMapping INSTANCE_ASSIGNMENT_MODIFY_APPROVER = - new QAssignmentReferenceMapping<>("m_assignment_ref_create_approver", "arefma"); + private static QAssignmentReferenceMapping instanceAssignmentCreateApprover; + private static QAssignmentReferenceMapping instanceAssignmentModifyApprover; - private QAssignmentReferenceMapping(String tableName, String defaultAliasName) { - super(tableName, defaultAliasName, QAssignmentReference.class); + public static QAssignmentReferenceMapping + initForAssignmentCreateApprover(@NotNull SqaleRepoContext repositoryContext) { + if (instanceAssignmentCreateApprover == null) { + instanceAssignmentCreateApprover = new QAssignmentReferenceMapping<>( + "m_assignment_ref_create_approver", "arefca", repositoryContext); + } + return getForAssignmentCreateApprover(); + } + + public static QAssignmentReferenceMapping + getForAssignmentCreateApprover() { + //noinspection unchecked + return (QAssignmentReferenceMapping) + Objects.requireNonNull(instanceAssignmentCreateApprover); + } + + public static QAssignmentReferenceMapping + initForAssignmentModifyApprover(@NotNull SqaleRepoContext repositoryContext) { + if (instanceAssignmentModifyApprover == null) { + instanceAssignmentModifyApprover = new QAssignmentReferenceMapping<>( + "m_assignment_ref_modify_approver", "arefma", repositoryContext); + } + return getForAssignmentModifyApprover(); + } + + public static QAssignmentReferenceMapping + getForAssignmentModifyApprover() { + //noinspection unchecked + return (QAssignmentReferenceMapping) + Objects.requireNonNull(instanceAssignmentModifyApprover); + } + + private QAssignmentReferenceMapping( + String tableName, + String defaultAliasName, + @NotNull SqaleRepoContext repositoryContext) { + super(tableName, defaultAliasName, QAssignmentReference.class, repositoryContext); // assignmentCid probably can't be mapped directly } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java index 39c63f052f8..9ee84f7589a 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java @@ -8,6 +8,9 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.CaseType.*; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.xml.ns._public.common.common_3.CaseType; @@ -19,11 +22,13 @@ public class QCaseMapping public static final String DEFAULT_ALIAS_NAME = "cs"; - public static final QCaseMapping INSTANCE = new QCaseMapping(); + public static QCaseMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QCaseMapping(repositoryContext); + } - private QCaseMapping() { + private QCaseMapping(@NotNull SqaleRepoContext repositoryContext) { super(QCase.TABLE_NAME, DEFAULT_ALIAS_NAME, - CaseType.class, QCase.class); + CaseType.class, QCase.class, repositoryContext); addItemMapping(F_STATE, stringMapper(q -> q.state)); addItemMapping(F_CLOSE_TIMESTAMP, timestampMapper(q -> q.closeTimestamp)); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java index 0bb4cb72005..b78cd02cdc5 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.QOwnedByMapping; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; @@ -27,17 +28,20 @@ public class QContainerMapping, MContainer, Object> INSTANCE = - new QContainerMapping<>(QContainer.TABLE_NAME, DEFAULT_ALIAS_NAME, - Containerable.class, QContainer.CLASS); + public static QContainerMapping initContainerMapping(@NotNull SqaleRepoContext repositoryContext) { + return new QContainerMapping<>( + QContainer.TABLE_NAME, DEFAULT_ALIAS_NAME, + Containerable.class, QContainer.CLASS, + repositoryContext); + } protected QContainerMapping( @NotNull String tableName, @NotNull String defaultAliasName, @NotNull Class schemaType, - @NotNull Class queryType) { - super(tableName, defaultAliasName, schemaType, queryType); + @NotNull Class queryType, + @NotNull SqaleRepoContext repositoryContext) { + super(tableName, defaultAliasName, schemaType, queryType, repositoryContext); // CID is not mapped directly, it is used by path resolver elsewhere } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java index 66e8ccf2cbe..ccf8474a3a6 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java @@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType; @@ -23,11 +24,13 @@ public class QConnectorHostMapping public static final String DEFAULT_ALIAS_NAME = "conh"; - public static final QConnectorHostMapping INSTANCE = new QConnectorHostMapping(); + public static QConnectorHostMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QConnectorHostMapping(repositoryContext); + } - private QConnectorHostMapping() { + private QConnectorHostMapping(@NotNull SqaleRepoContext repositoryContext) { super(QConnectorHost.TABLE_NAME, DEFAULT_ALIAS_NAME, - ConnectorHostType.class, QConnectorHost.class); + ConnectorHostType.class, QConnectorHost.class, repositoryContext); addItemMapping(F_HOSTNAME, stringMapper(q -> q.hostname)); addItemMapping(F_PORT, stringMapper(q -> q.port)); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java index ef9fc1aeb81..aebdedbbd45 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType; @@ -22,10 +23,13 @@ public class QConnectorMapping public static final String DEFAULT_ALIAS_NAME = "con"; - public static final QConnectorMapping INSTANCE = new QConnectorMapping(); + public static QConnectorMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QConnectorMapping(repositoryContext); + } - private QConnectorMapping() { - super(QConnector.TABLE_NAME, DEFAULT_ALIAS_NAME, ConnectorType.class, QConnector.class); + private QConnectorMapping(@NotNull SqaleRepoContext repositoryContext) { + super(QConnector.TABLE_NAME, DEFAULT_ALIAS_NAME, + ConnectorType.class, QConnector.class, repositoryContext); addItemMapping(F_CONNECTOR_BUNDLE, stringMapper(q -> q.connectorBundle)); addItemMapping(F_CONNECTOR_TYPE, stringMapper(q -> q.connectorType)); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java index d9f64fa0011..92fb26d92ae 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java @@ -13,6 +13,7 @@ import com.querydsl.core.types.Path; import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; @@ -33,16 +34,19 @@ public class QFocusMapping, R extends M public static final String DEFAULT_ALIAS_NAME = "f"; - public static final QFocusMapping, MFocus> INSTANCE = - new QFocusMapping<>(QFocus.TABLE_NAME, DEFAULT_ALIAS_NAME, - FocusType.class, QFocus.CLASS); + public static QFocusMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QFocusMapping<>(QFocus.TABLE_NAME, DEFAULT_ALIAS_NAME, + FocusType.class, QFocus.CLASS, + repositoryContext); + } protected QFocusMapping( @NotNull String tableName, @NotNull String defaultAliasName, @NotNull Class schemaType, - @NotNull Class queryType) { - super(tableName, defaultAliasName, schemaType, queryType); + @NotNull Class queryType, + @NotNull SqaleRepoContext repositoryContext) { + super(tableName, defaultAliasName, schemaType, queryType, repositoryContext); addItemMapping(F_COST_CENTER, stringMapper(q -> q.costCenter)); addItemMapping(F_EMAIL_ADDRESS, stringMapper(q -> q.emailAddress)); @@ -85,20 +89,8 @@ protected QFocusMapping( .addItemMapping(ActivationType.F_LOCKOUT_STATUS, enumMapper(q -> q.lockoutStatus)); - addRefMapping(F_PERSONA_REF, personaReferenceMapping()); - addRefMapping(F_LINK_REF, projectionReferenceMapping()); - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - public @NotNull QObjectReferenceMapping personaReferenceMapping() { - //noinspection unchecked - return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_PERSONA; - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - public @NotNull QObjectReferenceMapping projectionReferenceMapping() { - //noinspection unchecked - return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_PROJECTION; + addRefMapping(F_PERSONA_REF, QObjectReferenceMapping.initForPersona(repositoryContext)); + addRefMapping(F_LINK_REF, QObjectReferenceMapping.initForProjection(repositoryContext)); } @Override @@ -174,8 +166,8 @@ public void storeRelatedEntities( super.storeRelatedEntities(row, schemaObject, jdbcSession); storeRefs(row, schemaObject.getLinkRef(), - projectionReferenceMapping(), jdbcSession); + QObjectReferenceMapping.getForProjection(), jdbcSession); storeRefs(row, schemaObject.getPersonaRef(), - personaReferenceMapping(), jdbcSession); + QObjectReferenceMapping.getForPersona(), jdbcSession); } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java index 0bf0c08e794..cbebd42c2a8 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.GenericObjectType; @@ -19,11 +20,13 @@ public class QGenericObjectMapping public static final String DEFAULT_ALIAS_NAME = "go"; - public static final QGenericObjectMapping INSTANCE = new QGenericObjectMapping(); + public static QGenericObjectMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QGenericObjectMapping(repositoryContext); + } - private QGenericObjectMapping() { + private QGenericObjectMapping(@NotNull SqaleRepoContext repositoryContext) { super(QGenericObject.TABLE_NAME, DEFAULT_ALIAS_NAME, - GenericObjectType.class, QGenericObject.class); + GenericObjectType.class, QGenericObject.class, repositoryContext); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java index 0458fc83e95..e8941623253 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; @@ -21,11 +22,13 @@ public class QUserMapping public static final String DEFAULT_ALIAS_NAME = "u"; - public static final QUserMapping INSTANCE = new QUserMapping(); + public static QUserMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QUserMapping(repositoryContext); + } - private QUserMapping() { + private QUserMapping(@NotNull SqaleRepoContext repositoryContext) { super(QUser.TABLE_NAME, DEFAULT_ALIAS_NAME, - UserType.class, QUser.class); + UserType.class, QUser.class, repositoryContext); addItemMapping(F_ADDITIONAL_NAME, polyStringMapper( q -> q.additionalNameOrig, q -> q.additionalNameNorm)); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java index 2156eba2e29..a7723179d0f 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java @@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType; @@ -25,13 +26,16 @@ public class QLookupTableMapping public static final String DEFAULT_ALIAS_NAME = "lt"; - public static final QLookupTableMapping INSTANCE = new QLookupTableMapping(); + public static QLookupTableMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QLookupTableMapping(repositoryContext); + } - private QLookupTableMapping() { + private QLookupTableMapping(@NotNull SqaleRepoContext repositoryContext) { super(QLookupTable.TABLE_NAME, DEFAULT_ALIAS_NAME, - LookupTableType.class, QLookupTable.class); + LookupTableType.class, QLookupTable.class, repositoryContext); - addContainerTableMapping(F_ROW, QLookupTableRowMapping.INSTANCE, + addContainerTableMapping(F_ROW, + QLookupTableRowMapping.init(repositoryContext), joinOn((o, t) -> o.oid.eq(t.ownerOid))); } @@ -55,7 +59,7 @@ public void storeRelatedEntities( List rows = schemaObject.getRow(); if (!rows.isEmpty()) { rows.forEach(row -> - QLookupTableRowMapping.INSTANCE.insert(row, lookupTable, jdbcSession)); + QLookupTableRowMapping.get().insert(row, lookupTable, jdbcSession)); } } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java index df6f9cb8033..e7a295f5a91 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java @@ -8,6 +8,11 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType.*; +import java.util.Objects; + +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.util.MiscUtil; @@ -21,11 +26,22 @@ public class QLookupTableRowMapping public static final String DEFAULT_ALIAS_NAME = "ltr"; - public static final QLookupTableRowMapping INSTANCE = new QLookupTableRowMapping(); + private static QLookupTableRowMapping instance; + + public static QLookupTableRowMapping init(@NotNull SqaleRepoContext repositoryContext) { + if (instance == null) { + instance = new QLookupTableRowMapping(repositoryContext); + } + return instance; + } + + public static QLookupTableRowMapping get() { + return Objects.requireNonNull(instance); + } - private QLookupTableRowMapping() { + private QLookupTableRowMapping(@NotNull SqaleRepoContext repositoryContext) { super(QLookupTableRow.TABLE_NAME, DEFAULT_ALIAS_NAME, - LookupTableRowType.class, QLookupTableRow.class); + LookupTableRowType.class, QLookupTableRow.class, repositoryContext); addItemMapping(F_KEY, stringMapper(q -> q.key)); addItemMapping(F_LABEL, polyStringMapper( diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java index 5e0dcee34df..397cd366306 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType; @@ -22,10 +23,13 @@ public class QNodeMapping public static final String DEFAULT_ALIAS_NAME = "nod"; - public static final QNodeMapping INSTANCE = new QNodeMapping(); + public static QNodeMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QNodeMapping(repositoryContext); + } - private QNodeMapping() { - super(QNode.TABLE_NAME, DEFAULT_ALIAS_NAME, NodeType.class, QNode.class); + private QNodeMapping(@NotNull SqaleRepoContext repositoryContext) { + super(QNode.TABLE_NAME, DEFAULT_ALIAS_NAME, + NodeType.class, QNode.class, repositoryContext); addItemMapping(F_NODE_IDENTIFIER, stringMapper(q -> q.nodeIdentifier)); } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QAssignmentHolderMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QAssignmentHolderMapping.java index b4afee53417..170ce467d08 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QAssignmentHolderMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QAssignmentHolderMapping.java @@ -6,6 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.object; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType; /** @@ -21,11 +24,14 @@ public class QAssignmentHolderMapping extends QObjectMapping< public static final String DEFAULT_ALIAS_NAME = "ah"; - public static final QAssignmentHolderMapping INSTANCE = new QAssignmentHolderMapping(); + public static QAssignmentHolderMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QAssignmentHolderMapping(repositoryContext); + } - protected QAssignmentHolderMapping() { + protected QAssignmentHolderMapping(@NotNull SqaleRepoContext repositoryContext) { super(QObject.TABLE_NAME, DEFAULT_ALIAS_NAME, - AssignmentHolderType.class, QAssignmentHolder.class); + AssignmentHolderType.class, QAssignmentHolder.class, + repositoryContext); } public static class MAssignmentHolder extends MObject { diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java index d8e18c265fe..1f547918431 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java @@ -22,6 +22,7 @@ import com.evolveum.midpoint.prism.PrismConstants; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.SerializationOptions; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.SqaleUtils; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentMapping; @@ -48,16 +49,20 @@ public class QObjectMapping, R extend public static final String DEFAULT_ALIAS_NAME = "o"; - public static final QObjectMapping, MObject> INSTANCE = - new QObjectMapping<>(QObject.TABLE_NAME, DEFAULT_ALIAS_NAME, - ObjectType.class, QObject.CLASS); + public static QObjectMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QObjectMapping<>( + QObject.TABLE_NAME, DEFAULT_ALIAS_NAME, + ObjectType.class, QObject.CLASS, + repositoryContext); + } protected QObjectMapping( @NotNull String tableName, @NotNull String defaultAliasName, @NotNull Class schemaType, - @NotNull Class queryType) { - super(tableName, defaultAliasName, schemaType, queryType, null); + @NotNull Class queryType, + @NotNull SqaleRepoContext repositoryContext) { + super(tableName, defaultAliasName, schemaType, queryType, repositoryContext); addItemMapping(PrismConstants.T_ID, uuidMapper(q -> q.oid)); addItemMapping(F_NAME, polyStringMapper( @@ -90,82 +95,28 @@ protected QObjectMapping( .addItemMapping(MetadataType.F_MODIFY_TIMESTAMP, timestampMapper(q -> q.modifyTimestamp)) .addRefMapping(MetadataType.F_CREATE_APPROVER_REF, - objectCreateApproverReferenceMapping()) + QObjectReferenceMapping.initForObjectCreateApprover(repositoryContext)) .addRefMapping(MetadataType.F_MODIFY_APPROVER_REF, - objectModifyApproverReferenceMapping()); + QObjectReferenceMapping.initForObjectModifyApprover(repositoryContext)); - addRefMapping(F_PARENT_ORG_REF, objectParentOrgReferenceMapping()); + addRefMapping(F_PARENT_ORG_REF, + QObjectReferenceMapping.initForObjectParentOrg(repositoryContext)); - addContainerTableMapping(AssignmentHolderType.F_ASSIGNMENT, assignmentMapping(), + addContainerTableMapping(AssignmentHolderType.F_ASSIGNMENT, + QAssignmentMapping.initAssignment(repositoryContext), joinOn((o, a) -> o.oid.eq(a.ownerOid))); - addContainerTableMapping(F_OPERATION_EXECUTION, operationExecutionMapping(), + addContainerTableMapping(F_OPERATION_EXECUTION, + QOperationExecutionMapping.init(repositoryContext), joinOn((o, trg) -> o.oid.eq(trg.ownerOid))); - addContainerTableMapping(F_TRIGGER, triggerMapping(), + addContainerTableMapping(F_TRIGGER, + QTriggerMapping.init(repositoryContext), joinOn((o, trg) -> o.oid.eq(trg.ownerOid))); // AssignmentHolderType - addRefMapping(F_ARCHETYPE_REF, archetypeReferenceMapping()); - addRefMapping(F_DELEGATED_REF, delegatedReferenceMapping()); - addRefMapping(F_ROLE_MEMBERSHIP_REF, roleMembershipReferenceMapping()); - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - @NotNull - public QAssignmentMapping assignmentMapping() { - //noinspection unchecked - return (QAssignmentMapping) QAssignmentMapping.INSTANCE; - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - @NotNull - public QOperationExecutionMapping operationExecutionMapping() { - //noinspection unchecked - return (QOperationExecutionMapping) QOperationExecutionMapping.INSTANCE; - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - @NotNull - public QTriggerMapping triggerMapping() { - //noinspection unchecked - return (QTriggerMapping) QTriggerMapping.INSTANCE; - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - public @NotNull QObjectReferenceMapping archetypeReferenceMapping() { - //noinspection unchecked - return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_ARCHETYPE; - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - public @NotNull QObjectReferenceMapping delegatedReferenceMapping() { - //noinspection unchecked - return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_DELEGATED; - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - public @NotNull QObjectReferenceMapping objectCreateApproverReferenceMapping() { - //noinspection unchecked - return (QObjectReferenceMapping) - QObjectReferenceMapping.INSTANCE_OBJECT_CREATE_APPROVER; - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - public @NotNull QObjectReferenceMapping objectModifyApproverReferenceMapping() { - //noinspection unchecked - return (QObjectReferenceMapping) - QObjectReferenceMapping.INSTANCE_OBJECT_MODIFY_APPROVER; - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - public @NotNull QObjectReferenceMapping objectParentOrgReferenceMapping() { - //noinspection unchecked - return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_OBJECT_PARENT_ORG; - } - - /** Fixes rigid parametric types of static mapping instance to this instance. */ - public @NotNull QObjectReferenceMapping roleMembershipReferenceMapping() { - //noinspection unchecked - return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_ROLE_MEMBERSHIP; + addRefMapping(F_ARCHETYPE_REF, QObjectReferenceMapping.initForArchetype(repositoryContext)); + addRefMapping(F_DELEGATED_REF, QObjectReferenceMapping.initForDelegated(repositoryContext)); + addRefMapping(F_ROLE_MEMBERSHIP_REF, + QObjectReferenceMapping.initForRoleMembership(repositoryContext)); } @Override @@ -294,24 +245,24 @@ public void storeRelatedEntities( MetadataType metadata = schemaObject.getMetadata(); if (metadata != null) { storeRefs(row, metadata.getCreateApproverRef(), - objectCreateApproverReferenceMapping(), jdbcSession); + QObjectReferenceMapping.getForObjectCreateApprover(), jdbcSession); storeRefs(row, metadata.getModifyApproverRef(), - objectModifyApproverReferenceMapping(), jdbcSession); + QObjectReferenceMapping.getForObjectModifyApprover(), jdbcSession); } List triggers = schemaObject.getTrigger(); if (!triggers.isEmpty()) { - triggers.forEach(t -> triggerMapping().insert(t, row, jdbcSession)); + triggers.forEach(t -> QTriggerMapping.get().insert(t, row, jdbcSession)); } List operationExecutions = schemaObject.getOperationExecution(); if (!operationExecutions.isEmpty()) { operationExecutions.forEach(oe -> - operationExecutionMapping().insert(oe, row, jdbcSession)); + QOperationExecutionMapping.get().insert(oe, row, jdbcSession)); } storeRefs(row, schemaObject.getParentOrgRef(), - objectParentOrgReferenceMapping(), jdbcSession); + QObjectReferenceMapping.getForObjectParentOrg(), jdbcSession); if (schemaObject instanceof AssignmentHolderType) { storeAssignmentHolderEntities(row, (AssignmentHolderType) schemaObject, jdbcSession); @@ -329,15 +280,15 @@ private void storeAssignmentHolderEntities( List assignments = schemaObject.getAssignment(); if (!assignments.isEmpty()) { assignments.forEach(assignment -> - assignmentMapping().insert(assignment, row, jdbcSession)); + QAssignmentMapping.getAssignment().insert(assignment, row, jdbcSession)); } storeRefs(row, schemaObject.getArchetypeRef(), - archetypeReferenceMapping(), jdbcSession); + QObjectReferenceMapping.getForArchetype(), jdbcSession); storeRefs(row, schemaObject.getDelegatedRef(), - delegatedReferenceMapping(), jdbcSession); + QObjectReferenceMapping.getForDelegated(), jdbcSession); storeRefs(row, schemaObject.getRoleMembershipRef(), - roleMembershipReferenceMapping(), jdbcSession); + QObjectReferenceMapping.getForRoleMembership(), jdbcSession); } /** diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java index 25e65d8f0e5..8e1fd6c039a 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java @@ -8,6 +8,11 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.OperationExecutionType.*; +import java.util.Objects; + +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.util.MiscUtil; @@ -23,14 +28,26 @@ public class QOperationExecutionMapping public static final String DEFAULT_ALIAS_NAME = "opex"; - public static final QOperationExecutionMapping INSTANCE = - new QOperationExecutionMapping<>(); + private static QOperationExecutionMapping instance; + + public static QOperationExecutionMapping init( + @NotNull SqaleRepoContext repositoryContext) { + if (instance == null) { + instance = new QOperationExecutionMapping<>(repositoryContext); + } + return get(); + } + + public static QOperationExecutionMapping get() { + //noinspection unchecked + return (QOperationExecutionMapping) Objects.requireNonNull(instance); + } // We can't declare Class>.class, so we cheat a bit. @SuppressWarnings({ "unchecked", "rawtypes" }) - private QOperationExecutionMapping() { + private QOperationExecutionMapping(@NotNull SqaleRepoContext repositoryContext) { super(QOperationExecution.TABLE_NAME, DEFAULT_ALIAS_NAME, - OperationExecutionType.class, (Class) QOperationExecution.class); + OperationExecutionType.class, (Class) QOperationExecution.class, repositoryContext); addItemMapping(F_STATUS, enumMapper(q -> q.status)); addItemMapping(F_RECORD_TYPE, enumMapper(q -> q.recordType)); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java index 6cf8fefe560..49e0495fb21 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java @@ -6,6 +6,11 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.object; +import java.util.Objects; + +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.util.MiscUtil; @@ -21,13 +26,26 @@ public class QTriggerMapping public static final String DEFAULT_ALIAS_NAME = "trg"; - public static final QTriggerMapping INSTANCE = new QTriggerMapping<>(); + private static QTriggerMapping instance; + + public static QTriggerMapping init( + @NotNull SqaleRepoContext repositoryContext) { + if (instance == null) { + instance = new QTriggerMapping<>(repositoryContext); + } + return get(); + } + + public static QTriggerMapping get() { + //noinspection unchecked + return (QTriggerMapping) Objects.requireNonNull(instance); + } // We can't declare Class>.class, so we cheat a bit. @SuppressWarnings({ "unchecked", "rawtypes" }) - private QTriggerMapping() { + private QTriggerMapping(@NotNull SqaleRepoContext repositoryContext) { super(QTrigger.TABLE_NAME, DEFAULT_ALIAS_NAME, - TriggerType.class, (Class) QTrigger.class); + TriggerType.class, (Class) QTrigger.class, repositoryContext); addItemMapping(TriggerType.F_HANDLER_URI, uriMapper(q -> q.handlerUriId)); addItemMapping(TriggerType.F_TIMESTAMP, timestampMapper(q -> q.timestampValue)); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QDashboardMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QDashboardMapping.java index 856f3292201..6b53c75d151 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QDashboardMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QDashboardMapping.java @@ -6,6 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.other; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.xml.ns._public.common.common_3.DashboardType; @@ -18,11 +21,13 @@ public class QDashboardMapping public static final String DEFAULT_ALIAS_NAME = "d"; - public static final QDashboardMapping INSTANCE = new QDashboardMapping(); + public static QDashboardMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QDashboardMapping(repositoryContext); + } - private QDashboardMapping() { + private QDashboardMapping(@NotNull SqaleRepoContext repositoryContext) { super(QDashboard.TABLE_NAME, DEFAULT_ALIAS_NAME, - DashboardType.class, QDashboard.class); + DashboardType.class, QDashboard.class, repositoryContext); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFormMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFormMapping.java index c85a7e07553..d4d3c5fab43 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFormMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFormMapping.java @@ -6,6 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.other; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.xml.ns._public.common.common_3.FormType; @@ -17,11 +20,13 @@ public class QFormMapping extends QObjectMapping { public static final String DEFAULT_ALIAS_NAME = "form"; - public static final QFormMapping INSTANCE = new QFormMapping(); + public static QFormMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QFormMapping(repositoryContext); + } - private QFormMapping() { + private QFormMapping(@NotNull SqaleRepoContext repositoryContext) { super(QForm.TABLE_NAME, DEFAULT_ALIAS_NAME, - FormType.class, QForm.class); + FormType.class, QForm.class, repositoryContext); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFunctionLibraryMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFunctionLibraryMapping.java index f4ca68fb11e..c9840342900 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFunctionLibraryMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QFunctionLibraryMapping.java @@ -6,6 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.other; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.xml.ns._public.common.common_3.FunctionLibraryType; @@ -18,11 +21,13 @@ public class QFunctionLibraryMapping public static final String DEFAULT_ALIAS_NAME = "flib"; - public static final QFunctionLibraryMapping INSTANCE = new QFunctionLibraryMapping(); + public static QFunctionLibraryMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QFunctionLibraryMapping(repositoryContext); + } - private QFunctionLibraryMapping() { + private QFunctionLibraryMapping(@NotNull SqaleRepoContext repositoryContext) { super(QFunctionLibrary.TABLE_NAME, DEFAULT_ALIAS_NAME, - FunctionLibraryType.class, QFunctionLibrary.class); + FunctionLibraryType.class, QFunctionLibrary.class, repositoryContext); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QObjectCollectionMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QObjectCollectionMapping.java index d6b6b485bc3..2a47f1b81d6 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QObjectCollectionMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QObjectCollectionMapping.java @@ -6,6 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.other; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectCollectionType; @@ -18,11 +21,13 @@ public class QObjectCollectionMapping public static final String DEFAULT_ALIAS_NAME = "oc"; - public static final QObjectCollectionMapping INSTANCE = new QObjectCollectionMapping(); + public static QObjectCollectionMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QObjectCollectionMapping(repositoryContext); + } - private QObjectCollectionMapping() { + private QObjectCollectionMapping(@NotNull SqaleRepoContext repositoryContext) { super(QObjectCollection.TABLE_NAME, DEFAULT_ALIAS_NAME, - ObjectCollectionType.class, QObjectCollection.class); + ObjectCollectionType.class, QObjectCollection.class, repositoryContext); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QSequenceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QSequenceMapping.java index 76c62f5a41d..7a650d183c2 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QSequenceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/other/QSequenceMapping.java @@ -6,6 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.other; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.xml.ns._public.common.common_3.SequenceType; @@ -17,11 +20,13 @@ public class QSequenceMapping extends QObjectMapping`. + * The mapping is the same for all sub-tables, see various static `get*()` methods below. + * Mapping instances are initialized (`init*()` methods) in {@link QObjectMapping} subclasses. + * Both `init*` and `get*` methods are flexibly parametrized to adapt to the client code. + * Init methods can be called multiple times, only one instance for each sub-tables is created. * * @param query type of the reference owner * @param row type of the reference owner (related to {@link OQ}) @@ -29,31 +34,173 @@ public class QObjectReferenceMapping, OR extends MObject> extends QReferenceMapping, MReference, OQ, OR> { - public static final QObjectReferenceMapping INSTANCE_ARCHETYPE = - new QObjectReferenceMapping<>("m_ref_archetype", "refa"); - public static final QObjectReferenceMapping INSTANCE_DELEGATED = - new QObjectReferenceMapping<>("m_ref_delegated", "refd"); - public static final QObjectReferenceMapping INSTANCE_INCLUDE = - new QObjectReferenceMapping<>("m_ref_include", "refi"); - public static final QObjectReferenceMapping INSTANCE_PROJECTION = - new QObjectReferenceMapping<>("m_ref_projection", "refpj"); - public static final QObjectReferenceMapping INSTANCE_OBJECT_CREATE_APPROVER = - new QObjectReferenceMapping<>("m_ref_object_create_approver", "refca"); - public static final QObjectReferenceMapping INSTANCE_OBJECT_MODIFY_APPROVER = - new QObjectReferenceMapping<>("m_ref_object_modify_approver", "refma"); - public static final QObjectReferenceMapping INSTANCE_OBJECT_PARENT_ORG = - new QObjectReferenceMapping<>("m_ref_object_parent_org", "refpo"); - public static final QObjectReferenceMapping INSTANCE_PERSONA = - new QObjectReferenceMapping<>("m_ref_persona", "refp"); - public static final QObjectReferenceMapping INSTANCE_RESOURCE_BUSINESS_CONFIGURATION_APPROVER = - new QObjectReferenceMapping<>("m_ref_resource_business_configuration_approver", "refrbca"); - public static final QObjectReferenceMapping INSTANCE_ROLE_MEMBERSHIP = - new QObjectReferenceMapping<>("m_ref_role_membership", "refrm"); + public static QObjectReferenceMapping instanceArchetype; + public static QObjectReferenceMapping instanceDelegated; + public static QObjectReferenceMapping instanceInclude; + public static QObjectReferenceMapping instanceProjection; + public static QObjectReferenceMapping instanceObjectCreateApprover; + public static QObjectReferenceMapping instanceObjectModifyApprover; + public static QObjectReferenceMapping instanceObjectParentOrg; + public static QObjectReferenceMapping instancePersona; + public static QObjectReferenceMapping + instanceResourceBusinessConfigurationApprover; + public static QObjectReferenceMapping instanceRoleMembership; + + // region static init/get methods + public static , R extends MObject> + QObjectReferenceMapping initForArchetype(@NotNull SqaleRepoContext repositoryContext) { + if (instanceArchetype == null) { + instanceArchetype = new QObjectReferenceMapping<>( + "m_ref_archetype", "refa", repositoryContext); + } + return getForArchetype(); + } + + public static , R extends MObject> + QObjectReferenceMapping getForArchetype() { + //noinspection unchecked + return (QObjectReferenceMapping) Objects.requireNonNull(instanceArchetype); + } + + public static , R extends MObject> + QObjectReferenceMapping initForDelegated(@NotNull SqaleRepoContext repositoryContext) { + if (instanceDelegated == null) { + instanceDelegated = new QObjectReferenceMapping<>( + "m_ref_delegated", "refd", repositoryContext); + } + return getForDelegated(); + } + + public static , R extends MObject> + QObjectReferenceMapping getForDelegated() { + //noinspection unchecked + return (QObjectReferenceMapping) Objects.requireNonNull(instanceDelegated); + } + + public static QObjectReferenceMapping initForInclude( + @NotNull SqaleRepoContext repositoryContext) { + if (instanceInclude == null) { + instanceInclude = new QObjectReferenceMapping<>( + "m_ref_include", "refi", repositoryContext); + } + return instanceInclude; + } + + public static QObjectReferenceMapping getForInclude() { + return Objects.requireNonNull(instanceInclude); + } + + public static , R extends MObject> QObjectReferenceMapping + initForProjection(@NotNull SqaleRepoContext repositoryContext) { + if (instanceProjection == null) { + instanceProjection = new QObjectReferenceMapping<>( + "m_ref_projection", "refpj", repositoryContext); + } + return getForProjection(); + } + + public static , R extends MObject> + QObjectReferenceMapping getForProjection() { + //noinspection unchecked + return (QObjectReferenceMapping) Objects.requireNonNull(instanceProjection); + } + + public static , R extends MObject> QObjectReferenceMapping + initForObjectCreateApprover(@NotNull SqaleRepoContext repositoryContext) { + if (instanceObjectCreateApprover == null) { + instanceObjectCreateApprover = new QObjectReferenceMapping<>( + "m_ref_object_create_approver", "refca", repositoryContext); + } + return getForObjectCreateApprover(); + } + + public static , R extends MObject> + QObjectReferenceMapping getForObjectCreateApprover() { + //noinspection unchecked + return (QObjectReferenceMapping) Objects.requireNonNull(instanceObjectCreateApprover); + } + + public static , R extends MObject> QObjectReferenceMapping + initForObjectModifyApprover(@NotNull SqaleRepoContext repositoryContext) { + if (instanceObjectModifyApprover == null) { + instanceObjectModifyApprover = new QObjectReferenceMapping<>( + "m_ref_object_modify_approver", "refma", repositoryContext); + } + return getForObjectModifyApprover(); + } + + public static , R extends MObject> + QObjectReferenceMapping getForObjectModifyApprover() { + //noinspection unchecked + return (QObjectReferenceMapping) Objects.requireNonNull(instanceObjectModifyApprover); + } + + public static , R extends MObject> QObjectReferenceMapping + initForObjectParentOrg(@NotNull SqaleRepoContext repositoryContext) { + if (instanceObjectParentOrg == null) { + instanceObjectParentOrg = new QObjectReferenceMapping<>( + "m_ref_object_parent_org", "refpo", repositoryContext); + } + return getForObjectParentOrg(); + } + + public static , R extends MObject> + QObjectReferenceMapping getForObjectParentOrg() { + //noinspection unchecked + return (QObjectReferenceMapping) Objects.requireNonNull(instanceObjectParentOrg); + } + + public static , R extends MObject> + QObjectReferenceMapping initForPersona(@NotNull SqaleRepoContext repositoryContext) { + if (instancePersona == null) { + instancePersona = new QObjectReferenceMapping<>( + "m_ref_persona", "refp", repositoryContext); + } + return getForPersona(); + } + + public static , R extends MObject> + QObjectReferenceMapping getForPersona() { + //noinspection unchecked + return (QObjectReferenceMapping) Objects.requireNonNull(instancePersona); + } + + public static QObjectReferenceMapping + initForResourceBusinessConfigurationApprover(@NotNull SqaleRepoContext repositoryContext) { + if (instanceResourceBusinessConfigurationApprover == null) { + instanceResourceBusinessConfigurationApprover = new QObjectReferenceMapping<>( + "m_ref_resource_business_configuration_approver", "refrbca", repositoryContext); + } + return instanceResourceBusinessConfigurationApprover; + } + + public static QObjectReferenceMapping + getForResourceBusinessConfigurationApprover() { + return Objects.requireNonNull(instanceResourceBusinessConfigurationApprover); + } + + public static , R extends MObject> QObjectReferenceMapping + initForRoleMembership(@NotNull SqaleRepoContext repositoryContext) { + if (instanceRoleMembership == null) { + instanceRoleMembership = new QObjectReferenceMapping<>( + "m_ref_role_membership", "refrm", repositoryContext); + } + return getForRoleMembership(); + } + + public static , R extends MObject> + QObjectReferenceMapping getForRoleMembership() { + //noinspection unchecked + return (QObjectReferenceMapping) Objects.requireNonNull(instanceRoleMembership); + } + // endregion // Sad but true, we can't declare Class>.class, we declare defeat instead. @SuppressWarnings({ "unchecked", "rawtypes" }) - private QObjectReferenceMapping(String tableName, String defaultAliasName) { - super(tableName, defaultAliasName, (Class) QObjectReference.class); + private QObjectReferenceMapping(String tableName, + String defaultAliasName, + @NotNull SqaleRepoContext repositoryContext) { + super(tableName, defaultAliasName, (Class) QObjectReference.class, repositoryContext); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java index 0ad554ca371..8828c252dbb 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/QReferenceMapping.java @@ -10,8 +10,10 @@ import java.util.function.BiFunction; import com.querydsl.core.types.Predicate; +import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.prism.Referencable; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.QOwnedByMapping; import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; @@ -27,21 +29,28 @@ * @param query type of the reference owner * @param row type of the reference owner (related to {@link OQ}) */ -public class QReferenceMapping, R extends MReference, OQ extends FlexibleRelationalPathBase, OR> +public class QReferenceMapping< + Q extends QReference, + R extends MReference, + OQ extends FlexibleRelationalPathBase, + OR> extends SqaleTableMapping implements QOwnedByMapping { // see also subtype specific alias names defined for instances below public static final String DEFAULT_ALIAS_NAME = "ref"; - /** Top level "abstract" reference table, not really needed for normal queries. */ - public static final QReferenceMapping< - QReference, MReference, FlexibleRelationalPathBase, Object> INSTANCE = - new QReferenceMapping<>(QReference.TABLE_NAME, DEFAULT_ALIAS_NAME, QReference.CLASS); + public static QReferenceMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QReferenceMapping<>( + QReference.TABLE_NAME, DEFAULT_ALIAS_NAME, QReference.CLASS, repositoryContext); + } protected QReferenceMapping( - String tableName, String defaultAliasName, Class queryType) { - super(tableName, defaultAliasName, Referencable.class, queryType); + String tableName, + String defaultAliasName, + Class queryType, + @NotNull SqaleRepoContext repositoryContext) { + super(tableName, defaultAliasName, Referencable.class, queryType, repositoryContext); // TODO owner and reference type is not possible to query, probably OK // not sure about this mapping yet, does it make sense to query ref components? diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java index 68f32bf115f..e409993c199 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportDataMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportDataType; @@ -22,11 +23,13 @@ public class QReportDataMapping public static final String DEFAULT_ALIAS_NAME = "repout"; - public static final QReportDataMapping INSTANCE = new QReportDataMapping(); + public static QReportDataMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QReportDataMapping(repositoryContext); + } - private QReportDataMapping() { + private QReportDataMapping(@NotNull SqaleRepoContext repositoryContext) { super(QReportData.TABLE_NAME, DEFAULT_ALIAS_NAME, - ReportDataType.class, QReportData.class); + ReportDataType.class, QReportData.class, repositoryContext); addItemMapping(F_REPORT_REF, refMapper( q -> q.reportRefTargetOid, diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java index c07dd68b7a7..151312f9b71 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/report/QReportMapping.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.JasperReportEngineConfigurationType; @@ -21,11 +22,13 @@ public class QReportMapping public static final String DEFAULT_ALIAS_NAME = "rep"; - public static final QReportMapping INSTANCE = new QReportMapping(); + public static QReportMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QReportMapping(repositoryContext); + } - private QReportMapping() { + private QReportMapping(@NotNull SqaleRepoContext repositoryContext) { super(QReport.TABLE_NAME, DEFAULT_ALIAS_NAME, - ReportType.class, QReport.class); + ReportType.class, QReport.class, repositoryContext); addNestedMapping(ReportType.F_JASPER, JasperReportEngineConfigurationType.class) .addItemMapping(JasperReportEngineConfigurationType.F_ORIENTATION, diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java index 9f8964fab34..289871fadc1 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/resource/QResourceMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; @@ -24,16 +25,20 @@ public class QResourceMapping extends QObjectMapping q.businessAdministrativeState)) .addRefMapping(ResourceBusinessConfigurationType.F_APPROVER_REF, - QObjectReferenceMapping.INSTANCE_RESOURCE_BUSINESS_CONFIGURATION_APPROVER); + QObjectReferenceMapping.initForResourceBusinessConfigurationApprover( + repositoryContext)); addNestedMapping(F_OPERATIONAL_STATE, OperationalStateType.class) .addItemMapping(OperationalStateType.F_LAST_AVAILABILITY_STATUS, @@ -87,7 +92,7 @@ public void storeRelatedEntities(@NotNull MResource row, ResourceBusinessConfigurationType business = schemaObject.getBusiness(); if (business != null) { storeRefs(row, business.getApproverRef(), - QObjectReferenceMapping.INSTANCE_RESOURCE_BUSINESS_CONFIGURATION_APPROVER, + QObjectReferenceMapping.getForResourceBusinessConfigurationApprover(), jdbcSession); } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java index c1f69a05847..84a74a0d7fc 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QAbstractRoleMapping.java @@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentMapping; import com.evolveum.midpoint.repo.sqale.qmodel.focus.QFocusMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; @@ -32,17 +33,18 @@ public class QAbstractRoleMapping< public static final String DEFAULT_ALIAS_NAME = "ar"; - public static final - QAbstractRoleMapping, MAbstractRole> INSTANCE = - new QAbstractRoleMapping<>(QAbstractRole.TABLE_NAME, DEFAULT_ALIAS_NAME, - AbstractRoleType.class, QAbstractRole.CLASS); + public static QAbstractRoleMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QAbstractRoleMapping<>(QAbstractRole.TABLE_NAME, DEFAULT_ALIAS_NAME, + AbstractRoleType.class, QAbstractRole.CLASS, repositoryContext); + } protected QAbstractRoleMapping( @NotNull String tableName, @NotNull String defaultAliasName, @NotNull Class schemaType, - @NotNull Class queryType) { - super(tableName, defaultAliasName, schemaType, queryType); + @NotNull Class queryType, + @NotNull SqaleRepoContext repositoryContext) { + super(tableName, defaultAliasName, schemaType, queryType, repositoryContext); addNestedMapping(F_AUTOASSIGN, AutoassignSpecificationType.class) .addItemMapping(AutoassignSpecificationType.F_ENABLED, @@ -53,17 +55,11 @@ protected QAbstractRoleMapping( addItemMapping(F_REQUESTABLE, booleanMapper(q -> q.requestable)); addItemMapping(F_RISK_LEVEL, stringMapper(q -> q.riskLevel)); - addContainerTableMapping(F_INDUCEMENT, inducementMapping(), + addContainerTableMapping(F_INDUCEMENT, + QAssignmentMapping.initInducement(repositoryContext), joinOn((o, a) -> o.oid.eq(a.ownerOid))); } - /** Fixes rigid parametric types of static mapping instance to this instance. */ - @NotNull - public QAssignmentMapping inducementMapping() { - //noinspection unchecked - return (QAssignmentMapping) QAssignmentMapping.INSTANCE_INDUCEMENT; - } - @Override protected Q newAliasInstance(String alias) { //noinspection unchecked @@ -94,7 +90,7 @@ public void storeRelatedEntities( List inducement = schemaObject.getInducement(); if (!inducement.isEmpty()) { inducement.forEach(assignment -> - inducementMapping().insert(assignment, row, jdbcSession)); + QAssignmentMapping.getInducement().insert(assignment, row, jdbcSession)); } } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QArchetypeMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QArchetypeMapping.java index 55788f874b6..54afcb991b8 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QArchetypeMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QArchetypeMapping.java @@ -6,6 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.role; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.xml.ns._public.common.common_3.ArchetypeType; /** @@ -16,11 +19,13 @@ public class QArchetypeMapping public static final String DEFAULT_ALIAS_NAME = "arch"; - public static final QArchetypeMapping INSTANCE = new QArchetypeMapping(); + public static QArchetypeMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QArchetypeMapping(repositoryContext); + } - private QArchetypeMapping() { + private QArchetypeMapping(@NotNull SqaleRepoContext repositoryContext) { super(QArchetype.TABLE_NAME, DEFAULT_ALIAS_NAME, - ArchetypeType.class, QArchetype.class); + ArchetypeType.class, QArchetype.class, repositoryContext); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QRoleMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QRoleMapping.java index bf33d135430..ae9fdfd89cb 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QRoleMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QRoleMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; @@ -21,11 +22,13 @@ public class QRoleMapping public static final String DEFAULT_ALIAS_NAME = "r"; - public static final QRoleMapping INSTANCE = new QRoleMapping(); + public static QRoleMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QRoleMapping(repositoryContext); + } - private QRoleMapping() { + private QRoleMapping(@NotNull SqaleRepoContext repositoryContext) { super(QRole.TABLE_NAME, DEFAULT_ALIAS_NAME, - RoleType.class, QRole.class); + RoleType.class, QRole.class, repositoryContext); addItemMapping(F_ROLE_TYPE, stringMapper(q -> q.roleType)); } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QServiceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QServiceMapping.java index 3f0c2920588..8b7b773a864 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QServiceMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/role/QServiceMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.xml.ns._public.common.common_3.ServiceType; @@ -21,11 +22,13 @@ public class QServiceMapping public static final String DEFAULT_ALIAS_NAME = "svc"; - public static final QServiceMapping INSTANCE = new QServiceMapping(); + public static QServiceMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QServiceMapping(repositoryContext); + } - private QServiceMapping() { + private QServiceMapping(@NotNull SqaleRepoContext repositoryContext) { super(QService.TABLE_NAME, DEFAULT_ALIAS_NAME, - ServiceType.class, QService.class); + ServiceType.class, QService.class, repositoryContext); addItemMapping(F_DISPLAY_ORDER, integerMapper(q -> q.displayOrder)); } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java index c68a2a35293..f6f655e5f5e 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/shadow/QShadowMapping.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.util.MiscUtil; @@ -23,10 +24,13 @@ public class QShadowMapping public static final String DEFAULT_ALIAS_NAME = "sh"; - public static final QShadowMapping INSTANCE = new QShadowMapping(); + public static QShadowMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QShadowMapping(repositoryContext); + } - private QShadowMapping() { - super(QShadow.TABLE_NAME, DEFAULT_ALIAS_NAME, ShadowType.class, QShadow.class); + private QShadowMapping(@NotNull SqaleRepoContext repositoryContext) { + super(QShadow.TABLE_NAME, DEFAULT_ALIAS_NAME, + ShadowType.class, QShadow.class, repositoryContext); addItemMapping(ShadowType.F_OBJECT_CLASS, uriMapper(q -> q.objectClassId)); addItemMapping(F_RESOURCE_REF, refMapper( diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSecurityPolicyMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSecurityPolicyMapping.java index 7cfeff53eb6..af1e42c0853 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSecurityPolicyMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSecurityPolicyMapping.java @@ -6,6 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.system; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityPolicyType; @@ -18,11 +21,13 @@ public class QSecurityPolicyMapping public static final String DEFAULT_ALIAS_NAME = "sp"; - public static final QSecurityPolicyMapping INSTANCE = new QSecurityPolicyMapping(); + public static QSecurityPolicyMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QSecurityPolicyMapping(repositoryContext); + } - private QSecurityPolicyMapping() { + private QSecurityPolicyMapping(@NotNull SqaleRepoContext repositoryContext) { super(QSecurityPolicy.TABLE_NAME, DEFAULT_ALIAS_NAME, - SecurityPolicyType.class, QSecurityPolicy.class); + SecurityPolicyType.class, QSecurityPolicy.class, repositoryContext); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSystemConfigurationMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSystemConfigurationMapping.java index 1ebaa23eb9a..e54d99c287e 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSystemConfigurationMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QSystemConfigurationMapping.java @@ -6,6 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.system; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; @@ -18,11 +21,13 @@ public class QSystemConfigurationMapping public static final String DEFAULT_ALIAS_NAME = "sc"; - public static final QSystemConfigurationMapping INSTANCE = new QSystemConfigurationMapping(); + public static QSystemConfigurationMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QSystemConfigurationMapping(repositoryContext); + } - private QSystemConfigurationMapping() { + private QSystemConfigurationMapping(@NotNull SqaleRepoContext repositoryContext) { super(QSystemConfiguration.TABLE_NAME, DEFAULT_ALIAS_NAME, - SystemConfigurationType.class, QSystemConfiguration.class); + SystemConfigurationType.class, QSystemConfiguration.class, repositoryContext); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QValuePolicyMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QValuePolicyMapping.java index 0fda2aeb90e..94d75b731ae 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QValuePolicyMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/system/QValuePolicyMapping.java @@ -6,6 +6,9 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.system; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.xml.ns._public.common.common_3.ValuePolicyType; @@ -18,11 +21,13 @@ public class QValuePolicyMapping public static final String DEFAULT_ALIAS_NAME = "vp"; - public static final QValuePolicyMapping INSTANCE = new QValuePolicyMapping(); + public static QValuePolicyMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QValuePolicyMapping(repositoryContext); + } - private QValuePolicyMapping() { + private QValuePolicyMapping(@NotNull SqaleRepoContext repositoryContext) { super(QValuePolicy.TABLE_NAME, DEFAULT_ALIAS_NAME, - ValuePolicyType.class, QValuePolicy.class); + ValuePolicyType.class, QValuePolicy.class, repositoryContext); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java index 16bf53d48e1..acd439e3ff8 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/task/QTaskMapping.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.NotNull; +import com.evolveum.midpoint.repo.sqale.SqaleRepoContext; import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping; import com.evolveum.midpoint.repo.sqlbase.JdbcSession; import com.evolveum.midpoint.util.MiscUtil; @@ -21,11 +22,13 @@ public class QTaskMapping public static final String DEFAULT_ALIAS_NAME = "t"; - public static final QTaskMapping INSTANCE = new QTaskMapping(); + public static QTaskMapping init(@NotNull SqaleRepoContext repositoryContext) { + return new QTaskMapping(repositoryContext); + } - private QTaskMapping() { + private QTaskMapping(@NotNull SqaleRepoContext repositoryContext) { super(QTask.TABLE_NAME, DEFAULT_ALIAS_NAME, - TaskType.class, QTask.class); + TaskType.class, QTask.class, repositoryContext); addItemMapping(TaskType.F_TASK_IDENTIFIER, stringMapper(q -> q.taskIdentifier)); addItemMapping(TaskType.F_BINDING, enumMapper(q -> q.binding)); diff --git a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java index fe9751bbce5..b4e51abf1cf 100644 --- a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java +++ b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java @@ -293,7 +293,7 @@ public void test205AddObjectWithMultivalueRefs() assertThat(userRow.containerIdSeq).isEqualTo(1); // cid sequence is in initial state UUID userOid = UUID.fromString(user.getOid()); - QObjectReference or = QObjectReferenceMapping.INSTANCE_PROJECTION.defaultAlias(); + QObjectReference or = QObjectReferenceMapping.getForProjection().defaultAlias(); List projectionRefs = select(or, or.ownerOid.eq(userOid)); assertThat(projectionRefs).hasSize(2) .allMatch(rRow -> rRow.referenceType == MReferenceType.PROJECTION) @@ -335,7 +335,7 @@ public void test206AddObjectWithMultivalueRefsOnAssignment() assertThat(userRow.oid).isNotNull(); QAssignmentReference ar = - QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_CREATE_APPROVER.defaultAlias(); + QAssignmentReferenceMapping.getForAssignmentCreateApprover().defaultAlias(); List projectionRefs = select(ar, ar.ownerOid.eq(userRow.oid)); assertThat(projectionRefs).hasSize(2) .allMatch(rRow -> rRow.referenceType == MReferenceType.ASSIGNMENT_CREATE_APPROVER) @@ -593,7 +593,7 @@ public void test803ContainerAssignment() throws Exception { then("it is stored and rows to child tables are inserted"); assertThatOperationResult(result).isSuccess(); - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); List aRows = select(a, a.ownerOid.eq(UUID.fromString(object.getOid()))); assertThat(aRows).hasSize(2) .allMatch(ar -> ar.orderValue != null); @@ -735,7 +735,7 @@ public void test810ResourceAndItsBusinessApproverReferences() throws Exception { assertCachedUri(row.connectorRefRelationId, connectorRelation); QObjectReference ref = QObjectReferenceMapping - .INSTANCE_RESOURCE_BUSINESS_CONFIGURATION_APPROVER.defaultAlias(); + .getForResourceBusinessConfigurationApprover().defaultAlias(); List refs = select(ref, ref.ownerOid.eq(row.oid)); assertThat(refs).hasSize(2); @@ -1014,7 +1014,7 @@ public void test821ArchetypeAndInducement() throws Exception { assertThat(row.requestable).isFalse(); assertThat(row.riskLevel).isEqualTo("extremely-high"); - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); assertThat(select(a, a.ownerOid.eq(archetypeOid))).hasSize(2) .anyMatch(ar -> ar.orderValue.equals(2)) .anyMatch(ar -> ar.orderValue.equals(3)) diff --git a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoModifyObjectTest.java b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoModifyObjectTest.java index 7253b01ba32..1674aadb182 100644 --- a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoModifyObjectTest.java +++ b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoModifyObjectTest.java @@ -859,7 +859,7 @@ public void test160AddingProjectionRefInsertsRowsToTable() assertThat(row.version).isEqualTo(originalRow.version + 1); and("externalized refs are inserted to the dedicated table"); - QObjectReference r = QObjectReferenceMapping.INSTANCE_PROJECTION.defaultAlias(); + QObjectReference r = QObjectReferenceMapping.getForProjection().defaultAlias(); UUID ownerOid = UUID.fromString(user1Oid); List refs = select(r, r.ownerOid.eq(ownerOid)); assertThat(refs).hasSize(1) @@ -903,7 +903,7 @@ public void test161AddingMoreProjectionRefsInsertsRowsToTable() assertThat(row.version).isEqualTo(originalRow.version + 1); and("externalized refs are inserted to the dedicated table"); - QObjectReference r = QObjectReferenceMapping.INSTANCE_PROJECTION.defaultAlias(); + QObjectReference r = QObjectReferenceMapping.getForProjection().defaultAlias(); List refs = select(r, r.ownerOid.eq(UUID.fromString(user1Oid))); assertThat(refs).hasSize(3) .anyMatch(refRowMatcher(refTargetOid, refRelation1)) @@ -946,7 +946,7 @@ public void test162ReplacingProjectionRefs() assertThat(row.version).isEqualTo(originalRow.version + 1); and("externalized refs are inserted to the dedicated table"); - QObjectReference r = QObjectReferenceMapping.INSTANCE_PROJECTION.defaultAlias(); + QObjectReference r = QObjectReferenceMapping.getForProjection().defaultAlias(); List refs = select(r, r.ownerOid.eq(UUID.fromString(user1Oid))); assertThat(refs).hasSize(2) // new added, previous three or so are gone .anyMatch(refRowMatcher(refTargetOid, refRelation1)) @@ -1025,7 +1025,7 @@ public void test163ReplacingProjectionRefs() assertThat(row.version).isEqualTo(originalRow.version + 1); and("externalized refs are inserted and deleted accordingly"); - QObjectReference r = QObjectReferenceMapping.INSTANCE_PROJECTION.defaultAlias(); + QObjectReference r = QObjectReferenceMapping.getForProjection().defaultAlias(); List refs = select(r, r.ownerOid.eq(UUID.fromString(user1Oid))); assertThat(refs).hasSize(6) .anyMatch(refRowMatcher(refTargetOid1, refRelation2)) @@ -1065,7 +1065,7 @@ public void test164DeletingAllProjectionRefsUsingReplace() assertThat(row.version).isEqualTo(originalRow.version + 1); and("externalized refs are inserted and deleted accordingly"); - QObjectReference r = QObjectReferenceMapping.INSTANCE_PROJECTION.defaultAlias(); + QObjectReference r = QObjectReferenceMapping.getForProjection().defaultAlias(); assertThat(count(r, r.ownerOid.eq(UUID.fromString(user1Oid)))).isZero(); } @@ -1107,7 +1107,7 @@ public void test170AddingCreateApproverRefsUnderMetadata() assertThat(row.version).isEqualTo(originalRow.version + 1); and("externalized refs are inserted to the dedicated table"); - QObjectReference r = QObjectReferenceMapping.INSTANCE_OBJECT_CREATE_APPROVER.defaultAlias(); + QObjectReference r = QObjectReferenceMapping.getForObjectCreateApprover().defaultAlias(); UUID ownerOid = UUID.fromString(user1Oid); List refs = select(r, r.ownerOid.eq(ownerOid)); assertThat(refs).hasSize(2) @@ -1143,9 +1143,9 @@ public void test171DeletingMetadataContainerRemovesContainedRefs() MUser row = selectObjectByOid(QUser.class, user1Oid); assertThat(row.version).isEqualTo(originalRow.version + 1); - QObjectReference r = QObjectReferenceMapping.INSTANCE_OBJECT_CREATE_APPROVER.defaultAlias(); + QObjectReference r = QObjectReferenceMapping.getForObjectCreateApprover().defaultAlias(); assertThat(count(r, r.ownerOid.eq(UUID.fromString(user1Oid)))).isZero(); - r = QObjectReferenceMapping.INSTANCE_OBJECT_MODIFY_APPROVER.defaultAlias(); + r = QObjectReferenceMapping.getForObjectModifyApprover().defaultAlias(); assertThat(count(r, r.ownerOid.eq(UUID.fromString(user1Oid)))).isZero(); } // endregion @@ -1661,7 +1661,7 @@ public void test300AddAssignmentStoresItAndGeneratesMissingId() MUser row = selectObjectByOid(QUser.class, user1Oid); assertThat(row.version).isEqualTo(originalRow.version + 1); - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); MAssignment aRow = selectOne(a, a.ownerOid.eq(UUID.fromString(user1Oid))); assertThat(aRow.cid).isEqualTo(originalRow.containerIdSeq); assertThat(aRow.containerType).isEqualTo(MContainerType.ASSIGNMENT); @@ -1676,7 +1676,7 @@ public void test301ReplaceItemUnderMultiValueAssignment() OperationResult result = createOperationResult(); given("delta replacing single-value item inside assignment for user 1"); - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); MAssignment origAssignmentRow = selectOne(a, a.ownerOid.eq(UUID.fromString(user1Oid))); assertThat(origAssignmentRow.orderValue).isNull(); // wasn't previously set ObjectDelta delta = prismContext.deltaFor(UserType.class) @@ -1755,7 +1755,7 @@ public void test302AddingMoreAssignmentsIncludingNestedContainersAndRefs() assertThat(row.version).isEqualTo(originalRow.version + 1); assertThat(row.containerIdSeq).isEqualTo(originalRow.containerIdSeq + 2); - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); List aRows = select(a, a.ownerOid.eq(UUID.fromString(user1Oid))); assertThat(aRows).hasSize(3) .anyMatch(aRow -> aRow.cid < originalRow.containerIdSeq) // previous one @@ -1767,7 +1767,7 @@ && cachedUriById(aRow.createChannelId).equals("create-channel")) && aRow.resourceRefTargetOid.equals(resourceOid)); QAssignmentReference ar = - QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_CREATE_APPROVER.defaultAlias(); + QAssignmentReferenceMapping.getForAssignmentCreateApprover().defaultAlias(); List refRows = select(ar, ar.ownerOid.eq(UUID.fromString(user1Oid)) .and(ar.assignmentCid.eq(row.containerIdSeq - 2))); assertThat(refRows).hasSize(2) @@ -1781,7 +1781,7 @@ public void test303ModificationsOnOneAssignmentDoesNotAffectOthers() MUser originalRow = selectObjectByOid(QUser.class, user1Oid); given("delta changing item inside single assignments for user 1"); - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); long assOrder49Cid = selectOne(a, a.ownerOid.eq(UUID.fromString(user1Oid)), a.orderValue.eq(49)).cid; ObjectDelta delta = prismContext.deltaFor(UserType.class) @@ -1825,7 +1825,7 @@ public void test304MultipleModificationsOfExistingAssignment() MUser originalRow = selectObjectByOid(QUser.class, user1Oid); given("delta changing multiple assignments for user 1"); - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); long assOrder48Cid = selectOne(a, a.ownerOid.eq(UUID.fromString(user1Oid)), a.orderValue.eq(48)).cid; long assOrder50Cid = selectOne(a, @@ -1876,7 +1876,7 @@ public void test304MultipleModificationsOfExistingAssignment() // Approver references were removed from the only assignment that had them. QAssignmentReference ar = - QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_CREATE_APPROVER.defaultAlias(); + QAssignmentReferenceMapping.getForAssignmentCreateApprover().defaultAlias(); assertThat(count(ar, ar.ownerOid.eq(UUID.fromString(user1Oid)))).isZero(); } @@ -1912,7 +1912,7 @@ public void test305DeleteAssignmentByContent() MUser row = selectObjectByOid(QUser.class, user1Oid); assertThat(row.version).isEqualTo(originalRow.version + 1); - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); List aRows = select(a, a.ownerOid.eq(UUID.fromString(user1Oid))); assertThat(aRows).hasSize(2) .anyMatch(aRow -> aRow.orderValue.equals(47)) @@ -1952,7 +1952,7 @@ public void test310AddingAssignmentWithNewPrefilledCid() assertThat(row.version).isEqualTo(originalRow.version + 1); assertThat(row.containerIdSeq).isEqualTo(originalRow.containerIdSeq + 1); - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); List aRows = select(a, a.ownerOid.eq(UUID.fromString(user1Oid))); assertThat(aRows).hasSize(3) .anyMatch(aRow -> aRow.cid.equals(originalRow.containerIdSeq) @@ -1991,7 +1991,7 @@ public void test311DeleteAssignmentByCid() assertThat(row.version).isEqualTo(originalRow.version + 1); assertThat(row.containerIdSeq).isEqualTo(originalRow.containerIdSeq); // no need for change - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); List aRows = select(a, a.ownerOid.eq(UUID.fromString(user1Oid))); assertThat(aRows).hasSize(2) .noneMatch(aRow -> aRow.cid.equals(originalRow.containerIdSeq - 1)); @@ -2031,7 +2031,7 @@ public void test312AddingAssignmentWithUsedBytFreeCid() assertThat(row.version).isEqualTo(originalRow.version + 1); assertThat(row.containerIdSeq).isEqualTo(originalRow.containerIdSeq); // no change - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); List aRows = select(a, a.ownerOid.eq(UUID.fromString(user1Oid))); assertThat(aRows).hasSize(3) .anyMatch(aRow -> aRow.cid.equals(originalRow.containerIdSeq - 1) @@ -2069,7 +2069,7 @@ public void test319DeleteAllAssignments() MUser row = selectObjectByOid(QUser.class, user1Oid); assertThat(row.version).isEqualTo(originalRow.version + 1); - QAssignment a = QAssignmentMapping.INSTANCE.defaultAlias(); + QAssignment a = QAssignmentMapping.getAssignment().defaultAlias(); assertThat(select(a, a.ownerOid.eq(UUID.fromString(user1Oid)))).isEmpty(); } // endregion diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java index bcf7e09661c..be10e3dedee 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditDeltaMapping.java @@ -8,6 +8,8 @@ import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditItem.TABLE_NAME; +import java.util.Objects; + import com.querydsl.sql.SQLServerTemplates; import com.querydsl.sql.SQLTemplates; import org.jetbrains.annotations.NotNull; @@ -39,7 +41,7 @@ public static QAuditDeltaMapping init(@NotNull SqlRepoContext repositoryContext) } public static QAuditDeltaMapping get() { - return instance; + return Objects.requireNonNull(instance); } private QAuditDeltaMapping(@NotNull SqlRepoContext repositoryContext) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java index 6b5855da59c..25c0d239264 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditEventRecordMapping.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Map; +import java.util.Objects; import javax.xml.namespace.QName; import com.querydsl.core.Tuple; @@ -57,7 +58,7 @@ public static QAuditEventRecordMapping init(@NotNull SqlRepoContext repositoryCo } public static QAuditEventRecordMapping get() { - return instance; + return Objects.requireNonNull(instance); } private QAuditEventRecordMapping(@NotNull SqlRepoContext repositoryContext) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java index 17a28f00fe1..8e272ef8e16 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditItemMapping.java @@ -8,6 +8,8 @@ import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditItem.TABLE_NAME; +import java.util.Objects; + import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.repo.sql.audit.beans.MAuditItem; @@ -31,7 +33,7 @@ public static QAuditItemMapping init(@NotNull SqlRepoContext repositoryContext) } public static QAuditItemMapping get() { - return instance; + return Objects.requireNonNull(instance); } private QAuditItemMapping(@NotNull SqlRepoContext repositoryContext) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java index 86e52f2bc14..974a315f1cf 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditPropertyValueMapping.java @@ -8,6 +8,8 @@ import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditPropertyValue.TABLE_NAME; +import java.util.Objects; + import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.repo.sql.audit.beans.MAuditPropertyValue; @@ -31,7 +33,7 @@ public static QAuditPropertyValueMapping init(@NotNull SqlRepoContext repository } public static QAuditPropertyValueMapping get() { - return instance; + return Objects.requireNonNull(instance); } private QAuditPropertyValueMapping(@NotNull SqlRepoContext repositoryContext) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java index bc3e5ec0891..5a0d50035e2 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditRefValueMapping.java @@ -8,6 +8,8 @@ import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditItem.TABLE_NAME; +import java.util.Objects; + import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.repo.sql.audit.beans.MAuditRefValue; @@ -31,7 +33,7 @@ public static QAuditRefValueMapping init(@NotNull SqlRepoContext repositoryConte } public static QAuditRefValueMapping get() { - return instance; + return Objects.requireNonNull(instance); } private QAuditRefValueMapping(@NotNull SqlRepoContext repositoryContext) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java index c72605edbc5..dc6f0faf1a1 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/audit/mapping/QAuditResourceMapping.java @@ -8,6 +8,8 @@ import static com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditItem.TABLE_NAME; +import java.util.Objects; + import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.repo.sql.audit.beans.MAuditResource; @@ -30,7 +32,7 @@ public static QAuditResourceMapping init(@NotNull SqlRepoContext repositoryConte } public static QAuditResourceMapping get() { - return instance; + return Objects.requireNonNull(instance); } private QAuditResourceMapping(@NotNull SqlRepoContext repositoryContext) { From f80e9e94d5a9606dca41d45ca27850da91381275 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Mon, 3 May 2021 18:01:46 +0200 Subject: [PATCH 16/33] repo-sqlbase: MReferenceType is now pure enum, no ties to other classes --- .../repo/sqale/qmodel/ref/MReferenceType.java | 92 +++---------------- 1 file changed, 12 insertions(+), 80 deletions(-) diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/MReferenceType.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/MReferenceType.java index e436641c746..4baa405a29a 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/MReferenceType.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ref/MReferenceType.java @@ -6,95 +6,27 @@ */ package com.evolveum.midpoint.repo.sqale.qmodel.ref; -import java.util.Objects; -import javax.xml.namespace.QName; - -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.util.QNameUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; - /** * Enumeration of various types of reference entities (subtypes of {@link QReference}). - * Each value contains information about concrete Q-type (implying the concrete sub-table) - * and what is mapped to that kind of reference (reference owner + item that stores it). - * - * Implementation notes: * * * Order of values is irrelevant. * * Constant names must match the custom enum type ReferenceType in the database schema. - * - * This class has a bit of bad gravity, as it depends on various schema types. - * TODO: this can perhaps be a job of QObjectReferenceMapping and other ref mappings... */ public enum MReferenceType { // OBJECT REFERENCES - - ARCHETYPE(AssignmentHolderType.class, AssignmentHolderType.F_ARCHETYPE_REF), - - DELEGATED(AssignmentHolderType.class, AssignmentHolderType.F_DELEGATED_REF), - - INCLUDE(ObjectTemplateType.class, ObjectTemplateType.F_INCLUDE_REF), - - PROJECTION(FocusType.class, FocusType.F_LINK_REF), - - OBJECT_CREATE_APPROVER(ObjectType.class, MetadataType.F_CREATE_APPROVER_REF), - - OBJECT_MODIFY_APPROVER(ObjectType.class, MetadataType.F_MODIFY_APPROVER_REF), - - OBJECT_PARENT_ORG(ObjectType.class, ObjectType.F_PARENT_ORG_REF), - - PERSONA(FocusType.class, FocusType.F_PERSONA_REF), - - RESOURCE_BUSINESS_CONFIGURATION_APPROVER( - ResourceType.class, ResourceBusinessConfigurationType.F_APPROVER_REF), - - ROLE_MEMBERSHIP(AssignmentHolderType.class, AssignmentHolderType.F_ROLE_MEMBERSHIP_REF), + ARCHETYPE, + DELEGATED, + INCLUDE, + PROJECTION, + OBJECT_CREATE_APPROVER, + OBJECT_MODIFY_APPROVER, + OBJECT_PARENT_ORG, + PERSONA, + RESOURCE_BUSINESS_CONFIGURATION_APPROVER, + ROLE_MEMBERSHIP, // OTHER REFERENCES - - ASSIGNMENT_CREATE_APPROVER(AssignmentType.class, MetadataType.F_CREATE_APPROVER_REF), - - ASSIGNMENT_MODIFY_APPROVER(AssignmentType.class, MetadataType.F_MODIFY_APPROVER_REF) - - // TODO acc.cert.wi refs - // TODO case.wi refs - ; - - private final Class schemaType; - private final QName itemName; - - MReferenceType( - @NotNull Class schemaType, - @NotNull QName itemName) { - this.schemaType = schemaType; - this.itemName = itemName; - } - - public Class schemaType() { - return schemaType; - } - - public QName itemName() { - return itemName; - } - - // TODO: in old repo it's used by ObjectReferenceMapper.map, will we need it or will Q*Mapping definitions take care of it? - public static MReferenceType getOwnerByQName( - Class typeClass, QName itemName) { - Objects.requireNonNull(typeClass, "Schema type class must not be null"); - Objects.requireNonNull(itemName, "QName must not be null"); - - for (MReferenceType referenceType : values()) { - if (QNameUtil.match(itemName, referenceType.itemName) - && referenceType.schemaType.isAssignableFrom(typeClass)) { - return referenceType; - } - } - - throw new IllegalArgumentException("Can't find reference type for item '" + itemName - + "' in schema type " + typeClass.getName()); - } + ASSIGNMENT_CREATE_APPROVER, + ASSIGNMENT_MODIFY_APPROVER; } From e3759e0740ef0c06b06f66e45dbcad194c108a34 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Mon, 3 May 2021 18:22:33 +0200 Subject: [PATCH 17/33] repo-sqlbase SQL schema: removed /*VARCHAR...*/ comments --- repo/repo-sqale/sql/pgnew-repo.sql | 214 ++++++++++++++--------------- 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/repo/repo-sqale/sql/pgnew-repo.sql b/repo/repo-sqale/sql/pgnew-repo.sql index 8523c04f5f8..07f468f6c68 100644 --- a/repo/repo-sqale/sql/pgnew-repo.sql +++ b/repo/repo-sqale/sql/pgnew-repo.sql @@ -187,7 +187,7 @@ $$; -- URI can be anything, for QNames the format is based on QNameUtil ("prefix-url#localPart"). CREATE TABLE m_uri ( id SERIAL NOT NULL PRIMARY KEY, - uri TEXT/*VARCHAR(255)*/ NOT NULL UNIQUE + uri TEXT NOT NULL UNIQUE ); -- There can be more constants pre-filled, but that adds overhead, let the first-start do it. @@ -215,13 +215,13 @@ CREATE TABLE m_object ( oid UUID NOT NULL, -- objectType will be overridden with GENERATED value in concrete table objectType ObjectType NOT NULL, - name_orig TEXT/*VARCHAR(255)*/ NOT NULL, - name_norm TEXT/*VARCHAR(255)*/ NOT NULL, + name_orig TEXT NOT NULL, + name_norm TEXT NOT NULL, fullObject BYTEA, tenantRef_targetOid UUID, tenantRef_targetType ObjectType, tenantRef_relation_id INTEGER REFERENCES m_uri(id), - lifecycleState TEXT/*VARCHAR(255)*/, -- TODO what is this? how many distinct values? + lifecycleState TEXT, -- TODO what is this? how many distinct values? cid_seq BIGINT NOT NULL DEFAULT 1, -- sequence for container id, next free cid version INTEGER NOT NULL DEFAULT 1, -- complex DB columns, add indexes as needed per concrete table, e.g. see m_user @@ -366,15 +366,15 @@ CREATE INDEX m_ref_role_member_targetOid_relation_id_idx CREATE TABLE m_focus ( -- will be overridden with GENERATED value in concrete table objectType ObjectType NOT NULL, - costCenter TEXT/*VARCHAR(255)*/, - emailAddress TEXT/*VARCHAR(255)*/, + costCenter TEXT, + emailAddress TEXT, photo BYTEA, -- will be TOAST-ed if necessary - locale TEXT/*VARCHAR(255)*/, - locality_orig TEXT/*VARCHAR(255)*/, - locality_norm TEXT/*VARCHAR(255)*/, - preferredLanguage TEXT/*VARCHAR(255)*/, - telephoneNumber TEXT/*VARCHAR(255)*/, - timezone TEXT/*VARCHAR(255)*/, + locale TEXT, + locality_orig TEXT, + locality_norm TEXT, + preferredLanguage TEXT, + telephoneNumber TEXT, + timezone TEXT, -- credential/password/metadata passwordCreateTimestamp TIMESTAMPTZ, passwordModifyTimestamp TIMESTAMPTZ, @@ -383,7 +383,7 @@ CREATE TABLE m_focus ( effectiveStatus ActivationStatusType, enableTimestamp TIMESTAMPTZ, disableTimestamp TIMESTAMPTZ, - disableReason TEXT/*VARCHAR(255)*/, + disableReason TEXT, validityStatus TimeIntervalStatusType, validFrom TIMESTAMPTZ, validTo TIMESTAMPTZ, @@ -445,23 +445,23 @@ ALTER TABLE m_generic_object ADD CONSTRAINT m_generic_object_name_norm_key UNIQU CREATE TABLE m_user ( oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid), objectType ObjectType GENERATED ALWAYS AS ('USER') STORED, - additionalName_orig TEXT/*VARCHAR(255)*/, - additionalName_norm TEXT/*VARCHAR(255)*/, - employeeNumber TEXT/*VARCHAR(255)*/, - familyName_orig TEXT/*VARCHAR(255)*/, - familyName_norm TEXT/*VARCHAR(255)*/, - fullName_orig TEXT/*VARCHAR(255)*/, - fullName_norm TEXT/*VARCHAR(255)*/, - givenName_orig TEXT/*VARCHAR(255)*/, - givenName_norm TEXT/*VARCHAR(255)*/, - honorificPrefix_orig TEXT/*VARCHAR(255)*/, - honorificPrefix_norm TEXT/*VARCHAR(255)*/, - honorificSuffix_orig TEXT/*VARCHAR(255)*/, - honorificSuffix_norm TEXT/*VARCHAR(255)*/, - nickName_orig TEXT/*VARCHAR(255)*/, - nickName_norm TEXT/*VARCHAR(255)*/, - title_orig TEXT/*VARCHAR(255)*/, - title_norm TEXT/*VARCHAR(255)*/ + additionalName_orig TEXT, + additionalName_norm TEXT, + employeeNumber TEXT, + familyName_orig TEXT, + familyName_norm TEXT, + fullName_orig TEXT, + fullName_norm TEXT, + givenName_orig TEXT, + givenName_norm TEXT, + honorificPrefix_orig TEXT, + honorificPrefix_norm TEXT, + honorificSuffix_orig TEXT, + honorificSuffix_norm TEXT, + nickName_orig TEXT, + nickName_norm TEXT, + title_orig TEXT, + title_norm TEXT ) INHERITS (m_focus); @@ -484,13 +484,13 @@ CREATE INDEX m_user_employeeNumber_idx ON m_user (employeeNumber); /* TODO JSON of polystrings? CREATE TABLE m_user_organization ( user_oid UUID NOT NULL, - norm TEXT/*VARCHAR(255)*/, - orig TEXT/*VARCHAR(255)*/ + norm TEXT, + orig TEXT ); CREATE TABLE m_user_organizational_unit ( user_oid UUID NOT NULL, - norm TEXT/*VARCHAR(255)*/, - orig TEXT/*VARCHAR(255)*/ + norm TEXT, + orig TEXT ); */ -- endregion @@ -501,11 +501,11 @@ CREATE TABLE m_abstract_role ( -- will be overridden with GENERATED value in concrete table objectType ObjectType NOT NULL, autoAssignEnabled BOOLEAN, - displayName_orig TEXT/*VARCHAR(255)*/, - displayName_norm TEXT/*VARCHAR(255)*/, - identifier TEXT/*VARCHAR(255)*/, + displayName_orig TEXT, + displayName_norm TEXT, + identifier TEXT, requestable BOOLEAN, - riskLevel TEXT/*VARCHAR(255)*/, + riskLevel TEXT, CHECK (FALSE) NO INHERIT ) @@ -515,7 +515,7 @@ CREATE TABLE m_abstract_role ( CREATE TABLE m_role ( oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid), objectType ObjectType GENERATED ALWAYS AS ('ROLE') STORED, - roleType TEXT/*VARCHAR(255)*/ + roleType TEXT ) INHERITS (m_abstract_role); @@ -627,7 +627,7 @@ CREATE TABLE m_access_cert_case ( containerType ContainerType GENERATED ALWAYS AS ('ACCESS_CERTIFICATION_CASE') STORED, administrativeStatus INTEGER, archiveTimestamp TIMESTAMPTZ, - disableReason TEXT/*VARCHAR(255)*/, + disableReason TEXT, disableTimestamp TIMESTAMPTZ, effectiveStatus INTEGER, enableTimestamp TIMESTAMPTZ, @@ -635,7 +635,7 @@ CREATE TABLE m_access_cert_case ( validTo TIMESTAMPTZ, validityChangeTimestamp TIMESTAMPTZ, validityStatus INTEGER, - currentStageOutcome TEXT/*VARCHAR(255)*/, + currentStageOutcome TEXT, fullObject BYTEA, iteration INTEGER NOT NULL, objectRef_targetOid UUID, @@ -644,7 +644,7 @@ CREATE TABLE m_access_cert_case ( orgRef_targetOid UUID, orgRef_targetType ObjectType, orgRef_relation_id INTEGER REFERENCES m_uri(id), - outcome TEXT/*VARCHAR(255)*/, + outcome TEXT, remediedTimestamp TIMESTAMPTZ, reviewDeadline TIMESTAMPTZ, reviewRequestedTimestamp TIMESTAMPTZ, @@ -666,7 +666,7 @@ CREATE TABLE m_access_cert_wi ( containerType ContainerType GENERATED ALWAYS AS ('ACCESS_CERTIFICATION_WORK_ITEM') STORED, closeTimestamp TIMESTAMPTZ, iteration INTEGER NOT NULL, - outcome TEXT/*VARCHAR(255)*/, + outcome TEXT, outputChangeTimestamp TIMESTAMPTZ, performerRef_targetOid UUID, performerRef_targetType ObjectType, @@ -758,14 +758,14 @@ CREATE TABLE m_shadow ( resourceRef_targetOid UUID, resourceRef_targetType ObjectType, resourceRef_relation_id INTEGER REFERENCES m_uri(id), - intent TEXT/*VARCHAR(255)*/, + intent TEXT, kind ShadowKindType, attemptNumber INTEGER, -- TODO how is this mapped? dead BOOLEAN, exist BOOLEAN, fullSynchronizationTimestamp TIMESTAMPTZ, pendingOperationCount INTEGER, - primaryIdentifierValue TEXT/*VARCHAR(255)*/, + primaryIdentifierValue TEXT, -- status INTEGER, TODO how is this mapped? See RUtil.copyResultFromJAXB called from RTask and OperationResultMapper synchronizationSituation SynchronizationSituationType, synchronizationTimestamp TIMESTAMPTZ @@ -804,7 +804,7 @@ ALTER TABLE m_shadow ADD CONSTRAINT iPrimaryIdentifierValueWithOC CREATE TABLE m_node ( oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid), objectType ObjectType GENERATED ALWAYS AS ('NODE') STORED, - nodeIdentifier TEXT/*VARCHAR(255)*/ + nodeIdentifier TEXT ) INHERITS (m_object); @@ -963,10 +963,10 @@ ALTER TABLE m_lookup_table ADD CONSTRAINT m_lookup_table_name_norm_key UNIQUE (n CREATE TABLE m_lookup_table_row ( owner_oid UUID NOT NULL REFERENCES m_lookup_table(oid) ON DELETE CASCADE, containerType ContainerType GENERATED ALWAYS AS ('LOOKUP_TABLE_ROW') STORED, - key TEXT/*VARCHAR(255)*/, - value TEXT/*VARCHAR(255)*/, - label_orig TEXT/*VARCHAR(255)*/, - label_norm TEXT/*VARCHAR(255)*/, + key TEXT, + value TEXT, + label_orig TEXT, + label_norm TEXT, lastChangeTimestamp TIMESTAMPTZ, PRIMARY KEY (owner_oid, cid) @@ -980,9 +980,9 @@ ALTER TABLE m_lookup_table_row CREATE TABLE m_connector ( oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid), objectType ObjectType GENERATED ALWAYS AS ('CONNECTOR') STORED, - connectorBundle TEXT/*VARCHAR(255)*/, -- typically a package name - connectorType TEXT/*VARCHAR(255)*/, -- typically a class name - connectorVersion TEXT/*VARCHAR(255)*/, + connectorBundle TEXT, -- typically a package name + connectorType TEXT, -- typically a class name + connectorVersion TEXT, framework_id INTEGER REFERENCES m_uri(id), connectorHostRef_targetOid UUID, connectorHostRef_targetType ObjectType, @@ -1004,7 +1004,7 @@ ALTER TABLE m_connector ADD CONSTRAINT m_connector_name_norm_key UNIQUE (name_no -- TODO array/json in m_connector table -- CREATE TABLE m_connector_target_system ( -- connector_oid UUID NOT NULL, --- targetSystemType TEXT/*VARCHAR(255)*/ +-- targetSystemType TEXT -- ); -- ALTER TABLE m_connector_target_system -- ADD CONSTRAINT fk_connector_target_system FOREIGN KEY (connector_oid) REFERENCES m_connector; @@ -1013,8 +1013,8 @@ ALTER TABLE m_connector ADD CONSTRAINT m_connector_name_norm_key UNIQUE (name_no CREATE TABLE m_connector_host ( oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid), objectType ObjectType GENERATED ALWAYS AS ('CONNECTOR_HOST') STORED, - hostname TEXT/*VARCHAR(255)*/, - port TEXT/*VARCHAR(32)*/ + hostname TEXT, + port TEXT ) INHERITS (m_object); @@ -1032,23 +1032,23 @@ ALTER TABLE m_connector_host ADD CONSTRAINT m_connector_host_name_norm_key UNIQU CREATE TABLE m_task ( oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid), objectType ObjectType GENERATED ALWAYS AS ('TASK') STORED, - taskIdentifier TEXT/*VARCHAR(255)*/, + taskIdentifier TEXT, binding TaskBindingType, - category TEXT/*VARCHAR(255)*/, + category TEXT, completionTimestamp TIMESTAMPTZ, executionStatus TaskExecutionStateType, fullResult BYTEA, handlerUri_id INTEGER REFERENCES m_uri(id), lastRunStartTimestamp TIMESTAMPTZ, lastRunFinishTimestamp TIMESTAMPTZ, - node TEXT/*VARCHAR(255)*/, -- node_id only for information purposes + node TEXT, -- node_id only for information purposes objectRef_targetOid UUID, objectRef_targetType ObjectType, objectRef_relation_id INTEGER REFERENCES m_uri(id), ownerRef_targetOid UUID, ownerRef_targetType ObjectType, ownerRef_relation_id INTEGER REFERENCES m_uri(id), - parent TEXT/*VARCHAR(255)*/, -- value of taskIdentifier + parent TEXT, -- value of taskIdentifier recurrence TaskRecurrenceType, resultStatus OperationResultStatusType, threadStopAction ThreadStopActionType, @@ -1075,7 +1075,7 @@ CREATE INDEX m_task_dependentTaskIdentifiers_idx ON m_task USING GIN(dependentTa CREATE TABLE m_case ( oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid), objectType ObjectType GENERATED ALWAYS AS ('CASE') STORED, - state TEXT/*VARCHAR(255)*/, + state TEXT, closeTimestamp TIMESTAMPTZ, objectRef_targetOid UUID, objectRef_targetType ObjectType, @@ -1210,7 +1210,7 @@ CREATE TABLE m_assignment ( -- this is different from other containers, this is not generated, app must provide it containerType ContainerType NOT NULL CHECK (containerType IN ('ASSIGNMENT', 'INDUCEMENT')), owner_type ObjectType NOT NULL, - lifecycleState TEXT/*VARCHAR(255)*/, + lifecycleState TEXT, orderValue INTEGER, orgRef_targetOid UUID, orgRef_targetType ObjectType, @@ -1223,7 +1223,7 @@ CREATE TABLE m_assignment ( tenantRef_relation_id INTEGER REFERENCES m_uri(id), -- TODO what is this? see RAssignment.getExtension (both extId/Oid) extId INTEGER, - extOid TEXT/*VARCHAR(36)*/, -- is this UUID too? + extOid TEXT, -- is this UUID too? policySituations INTEGER[], -- soft-references m_uri, add index per table ext JSONB, -- construction @@ -1235,7 +1235,7 @@ CREATE TABLE m_assignment ( effectiveStatus ActivationStatusType, enableTimestamp TIMESTAMPTZ, disableTimestamp TIMESTAMPTZ, - disableReason TEXT/*VARCHAR(255)*/, + disableReason TEXT, validityStatus TimeIntervalStatusType, validFrom TIMESTAMPTZ, validTo TIMESTAMPTZ, @@ -1347,10 +1347,10 @@ CREATE INDEX m_operation_execution_timestampValue_idx ON m_operation_execution ( CREATE TABLE m_ext_item ( id SERIAL NOT NULL, kind INTEGER, -- see RItemKind, is this necessary? does it contain cardinality? - name TEXT/*VARCHAR(157)*/, -- no path for nested props needed? - type TEXT/*VARCHAR(32)*/, -- data type TODO enum? - storageType TEXT/*VARCHAR(32)*/ NOT NULL default 'EXT_JSON', -- type of storage (JSON, column, table separate/common, etc.) - storageInfo TEXT/*VARCHAR(32)*/, -- optional storage detail, name of column or table if necessary + name TEXT, -- no path for nested props needed? + type TEXT, -- data type TODO enum? + storageType TEXT NOT NULL default 'EXT_JSON', -- type of storage (JSON, column, table separate/common, etc.) + storageInfo TEXT, -- optional storage detail, name of column or table if necessary PRIMARY KEY (id) ); @@ -1379,8 +1379,8 @@ CREATE TABLE m_object_ext_long ( CREATE TABLE m_object_ext_poly ( owner_oid UUID NOT NULL REFERENCES m_object_oid(oid), ext_item_id VARCHAR(32) NOT NULL, - orig TEXT/*VARCHAR(255)*/ NOT NULL, - norm TEXT/*VARCHAR(255)*/, + orig TEXT NOT NULL, + norm TEXT, PRIMARY KEY (owner_oid, ext_item_id, orig) ); CREATE TABLE m_object_ext_reference ( @@ -1394,7 +1394,7 @@ CREATE TABLE m_object_ext_reference ( CREATE TABLE m_object_ext_string ( owner_oid UUID NOT NULL REFERENCES m_object_oid(oid), ext_item_id VARCHAR(32) NOT NULL, - value TEXT/*VARCHAR(255)*/ NOT NULL, + value TEXT NOT NULL, PRIMARY KEY (owner_oid, ext_item_id, value) ); @@ -1430,8 +1430,8 @@ CREATE TABLE m_assignment_ext_poly ( item_id INTEGER NOT NULL, anyContainer_owner_id INTEGER NOT NULL, anyContainer_owner_owner_oid UUID NOT NULL, - orig TEXT/*VARCHAR(255)*/ NOT NULL, - norm TEXT/*VARCHAR(255)*/, + orig TEXT NOT NULL, + norm TEXT, PRIMARY KEY (anyContainer_owner_owner_oid, anyContainer_owner_id, item_id, orig) ); CREATE TABLE m_assignment_ext_reference ( @@ -1447,7 +1447,7 @@ CREATE TABLE m_assignment_ext_string ( item_id INTEGER NOT NULL, anyContainer_owner_id INTEGER NOT NULL, anyContainer_owner_owner_oid UUID NOT NULL, - stringValue TEXT/*VARCHAR(255)*/ NOT NULL, + stringValue TEXT NOT NULL, PRIMARY KEY (anyContainer_owner_owner_oid, anyContainer_owner_id, item_id, stringValue) ); CREATE TABLE m_assignment_extension ( @@ -1465,42 +1465,42 @@ CREATE TABLE m_audit_delta ( deltaOid UUID, deltaType INTEGER, fullResult BYTEA, - objectName_norm TEXT/*VARCHAR(255)*/, - objectName_orig TEXT/*VARCHAR(255)*/, - resourceName_norm TEXT/*VARCHAR(255)*/, - resourceName_orig TEXT/*VARCHAR(255)*/, + objectName_norm TEXT, + objectName_orig TEXT, + resourceName_norm TEXT, + resourceName_orig TEXT, resourceOid UUID, status INTEGER, PRIMARY KEY (record_id, checksum) ); CREATE TABLE m_audit_event ( id BIGSERIAL NOT NULL, - attorneyName TEXT/*VARCHAR(255)*/, + attorneyName TEXT, attorneyOid UUID, - channel TEXT/*VARCHAR(255)*/, - eventIdentifier TEXT/*VARCHAR(255)*/, + channel TEXT, + eventIdentifier TEXT, eventStage INTEGER, eventType INTEGER, - hostIdentifier TEXT/*VARCHAR(255)*/, - initiatorName TEXT/*VARCHAR(255)*/, + hostIdentifier TEXT, + initiatorName TEXT, initiatorOid UUID, initiatorType INTEGER, message VARCHAR(1024), - nodeIdentifier TEXT/*VARCHAR(255)*/, + nodeIdentifier TEXT, outcome INTEGER, - parameter TEXT/*VARCHAR(255)*/, - remoteHostAddress TEXT/*VARCHAR(255)*/, - requestIdentifier TEXT/*VARCHAR(255)*/, - result TEXT/*VARCHAR(255)*/, - sessionIdentifier TEXT/*VARCHAR(255)*/, - targetName TEXT/*VARCHAR(255)*/, + parameter TEXT, + remoteHostAddress TEXT, + requestIdentifier TEXT, + result TEXT, + sessionIdentifier TEXT, + targetName TEXT, targetOid UUID, - targetOwnerName TEXT/*VARCHAR(255)*/, + targetOwnerName TEXT, targetOwnerOid UUID, targetOwnerType INTEGER, targetType INTEGER, - taskIdentifier TEXT/*VARCHAR(255)*/, - taskOID TEXT/*VARCHAR(255)*/, + taskIdentifier TEXT, + taskOID TEXT, timestampValue TIMESTAMPTZ, PRIMARY KEY (id) ); @@ -1511,23 +1511,23 @@ CREATE TABLE m_audit_item ( ); CREATE TABLE m_audit_prop_value ( id BIGSERIAL NOT NULL, - name TEXT/*VARCHAR(255)*/, + name TEXT, record_id BIGINT, value VARCHAR(1024), PRIMARY KEY (id) ); CREATE TABLE m_audit_ref_value ( id BIGSERIAL NOT NULL, - name TEXT/*VARCHAR(255)*/, + name TEXT, oid UUID, record_id BIGINT, - targetName_norm TEXT/*VARCHAR(255)*/, - targetName_orig TEXT/*VARCHAR(255)*/, - type TEXT/*VARCHAR(255)*/, + targetName_norm TEXT, + targetName_orig TEXT, + type TEXT, PRIMARY KEY (id) ); CREATE TABLE m_audit_resource ( - resourceOid TEXT/*VARCHAR(255)*/ NOT NULL, + resourceOid TEXT NOT NULL, record_id BIGINT NOT NULL, PRIMARY KEY (record_id, resourceOid) ); @@ -1540,7 +1540,7 @@ CREATE TABLE m_case_wi ( originalAssigneeRef_relation VARCHAR(157), originalAssigneeRef_targetOid UUID, originalAssigneeRef_targetType INTEGER, - outcome TEXT/*VARCHAR(255)*/, + outcome TEXT, performerRef_relation VARCHAR(157), performerRef_targetOid UUID, performerRef_targetType INTEGER, @@ -1588,8 +1588,8 @@ CREATE TABLE m_object_ext_poly ( item_id INTEGER NOT NULL, owner_oid UUID NOT NULL, ownerType INTEGER NOT NULL, - orig TEXT/*VARCHAR(255)*/ NOT NULL, - norm TEXT/*VARCHAR(255)*/, + orig TEXT NOT NULL, + norm TEXT, PRIMARY KEY (owner_oid, ownerType, item_id, orig) ); CREATE TABLE m_object_ext_reference ( @@ -1605,7 +1605,7 @@ CREATE TABLE m_object_ext_string ( item_id INTEGER NOT NULL, owner_oid UUID NOT NULL, ownerType INTEGER NOT NULL, - stringValue TEXT/*VARCHAR(255)*/ NOT NULL, + stringValue TEXT NOT NULL, PRIMARY KEY (owner_oid, ownerType, item_id, stringValue) ); CREATE TABLE m_org_closure ( @@ -1617,8 +1617,8 @@ CREATE TABLE m_org_closure ( CREATE TABLE m_org ( displayOrder INTEGER, - name_norm TEXT/*VARCHAR(255)*/, - name_orig TEXT/*VARCHAR(255)*/, + name_norm TEXT, + name_orig TEXT, tenant BOOLEAN, oid UUID NOT NULL, PRIMARY KEY (oid) @@ -2014,8 +2014,8 @@ create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP); -- region Schema versioning and upgrading CREATE TABLE m_global_metadata ( - name TEXT/*VARCHAR(255)*/ PRIMARY KEY, - value TEXT/*VARCHAR(255)*/ + name TEXT PRIMARY KEY, + value TEXT ); /* From d801958af40fdc64813abec640d0a9d141e8537b Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 3 May 2021 19:19:33 +0200 Subject: [PATCH 18/33] Add dynamic extension schema generation Plus some minor improvements in the system-level performance test. --- .../story/sysperf/ExtensionSchemaVariant.java | 52 - ...guration.java => ImportConfiguration.java} | 8 +- .../story/sysperf/PopulationVariant.java | 52 - .../story/sysperf/ProgressOutputFile.java | 4 +- .../sysperf/RecomputationConfiguration.java | 6 +- ....java => ReconciliationConfiguration.java} | 10 +- .../story/sysperf/SchemaConfiguration.java | 138 + .../story/sysperf/SummaryOutputFile.java | 6 +- .../story/sysperf/TestSystemPerformance.java | 55 +- .../schema-basic/user-extension-basic.xsd | 795 -- .../user-extension-big-global.xsd | 7106 ----------------- .../schema-big/user-extension-big.xsd | 7105 ---------------- .../schema-indexed/user-extension-indexed.xsd | 795 -- .../test/resources/system-perf/schema.vm.xsd | 41 + ...mpute.vm.xml => task-recomputation.vm.xml} | 2 +- 15 files changed, 229 insertions(+), 15946 deletions(-) delete mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java rename testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/{ImportsConfiguration.java => ImportConfiguration.java} (93%) delete mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java rename testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/{ReconciliationsConfiguration.java => ReconciliationConfiguration.java} (91%) create mode 100644 testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SchemaConfiguration.java delete mode 100644 testing/story/src/test/resources/system-perf/schema-basic/user-extension-basic.xsd delete mode 100644 testing/story/src/test/resources/system-perf/schema-big-global/user-extension-big-global.xsd delete mode 100644 testing/story/src/test/resources/system-perf/schema-big/user-extension-big.xsd delete mode 100644 testing/story/src/test/resources/system-perf/schema-indexed/user-extension-indexed.xsd create mode 100644 testing/story/src/test/resources/system-perf/schema.vm.xsd rename testing/story/src/test/resources/system-perf/{task-recompute.vm.xml => task-recomputation.vm.xml} (97%) diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java deleted file mode 100644 index fc2b6a2a5ad..00000000000 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ExtensionSchemaVariant.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ - -package com.evolveum.midpoint.testing.story.sysperf; - -enum ExtensionSchemaVariant { - - BASIC("basic"), - INDEXED("indexed"), - BIG("big"), // don't use: does not make any difference - BIG_GLOBAL("big-global") // don't use: does not make any difference - ; - - private static final String PROP_EXTENSION_SCHEMA = "schema"; - - private final String name; - - ExtensionSchemaVariant(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public String getExtensionSchemaDir() { - return "./src/test/resources/system-perf/schema-" + name; - } - - public static ExtensionSchemaVariant setup() { - String configuredSchemaVariant = System.getProperty(PROP_EXTENSION_SCHEMA, BASIC.name); - ExtensionSchemaVariant schemaVariant = fromName(configuredSchemaVariant); - System.out.println("Extension schema variant: " + schemaVariant); - String extensionSchemaDir = schemaVariant.getExtensionSchemaDir(); - System.out.println("Extension schema directory: " + extensionSchemaDir); - System.setProperty("midpoint.global.extensionDir", extensionSchemaDir); - return schemaVariant; - } - - private static ExtensionSchemaVariant fromName(String name) { - for (ExtensionSchemaVariant value : values()) { - if (value.name.equals(name)) { - return value; - } - } - throw new IllegalArgumentException("Unknown extension schema variant: " + name); - } -} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ImportsConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ImportConfiguration.java similarity index 93% rename from testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ImportsConfiguration.java rename to testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ImportConfiguration.java index 8e7077543ab..0e655deaf3a 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ImportsConfiguration.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ImportConfiguration.java @@ -20,7 +20,7 @@ import com.evolveum.midpoint.test.TestResource; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; -class ImportsConfiguration { +class ImportConfiguration { private static final String PROP = "import"; private static final String PROP_THREADS = PROP + ".threads"; @@ -33,7 +33,7 @@ class ImportsConfiguration { private final List> generatedTasks; - private ImportsConfiguration() { + private ImportConfiguration() { threads = Integer.parseInt(System.getProperty(PROP_THREADS, "0")); noOpRuns = Integer.parseInt(System.getProperty(PROP_NO_OP_RUNS, "1")); @@ -60,8 +60,8 @@ public String toString() { '}'; } - public static ImportsConfiguration setup() { - ImportsConfiguration configuration = new ImportsConfiguration(); + public static ImportConfiguration setup() { + ImportConfiguration configuration = new ImportConfiguration(); System.out.println("Import: " + configuration); return configuration; } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java deleted file mode 100644 index 8e18fe1655a..00000000000 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/PopulationVariant.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2010-2021 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ - -package com.evolveum.midpoint.testing.story.sysperf; - -enum PopulationVariant { - - P10("10", 10), - P100("100", 100), - P1K("1k", 1000), - P10K("10k", 10000), - P100K("100k", 100_000), - P1M("1m", 1_000_000); - - private static final String PROP_POPULATION = "population"; - - private final String name; - private final int accounts; - - PopulationVariant(String name, int accounts) { - this.name = name; - this.accounts = accounts; - } - - public String getName() { - return name; - } - - public int getAccounts() { - return accounts; - } - - public static PopulationVariant setup() { - String configuredName = System.getProperty(PROP_POPULATION, P10.name); - PopulationVariant variant = fromName(configuredName); - System.out.println("Population variant: " + variant); - return variant; - } - - private static PopulationVariant fromName(String name) { - for (PopulationVariant value : values()) { - if (value.name.equals(name)) { - return value; - } - } - throw new IllegalArgumentException("Unknown population variant: " + name); - } -} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java index 5fef0efa789..03fe38a50e7 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java @@ -20,13 +20,13 @@ class ProgressOutputFile { writer.println("test;time;progress"); } - void recordProgress(String testName, Task task) { + void recordProgress(String label, Task task) { long start = task.getLastRunStartTimestamp(); Long lastFinish = task.getLastRunFinishTimestamp(); long thisFinish = lastFinish != null && lastFinish > start ? lastFinish : System.currentTimeMillis(); long running = thisFinish - start; long progress = task.getProgress(); - writer.println(testName + ";" + running + ";" + progress); + writer.println(label + task.getName() + ";" + running + ";" + progress); writer.flush(); } } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RecomputationConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RecomputationConfiguration.java index 84bcee099ea..08aa4d63310 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RecomputationConfiguration.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RecomputationConfiguration.java @@ -18,10 +18,10 @@ class RecomputationConfiguration { - private static final String PROP = "recompute"; + private static final String PROP = "recomputation"; private static final String PROP_THREADS = PROP + ".threads"; - private static final File TASK_TEMPLATE_FILE = new File(TEST_DIR, "task-recompute.vm.xml"); + private static final File TASK_TEMPLATE_FILE = new File(TEST_DIR, "task-recomputation.vm.xml"); private static final String RECOMPUTE_TASK_OID = "f5920848-6c8f-4eda-ae26-2b961d6dae1b"; @@ -44,7 +44,7 @@ TestResource getGeneratedTask() { @Override public String toString() { - return "RecomputeConfiguration{" + + return "RecomputationConfiguration{" + "threads=" + threads + '}'; } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ReconciliationsConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ReconciliationConfiguration.java similarity index 91% rename from testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ReconciliationsConfiguration.java rename to testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ReconciliationConfiguration.java index a6db7659ce5..4bb27dbf3d7 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ReconciliationsConfiguration.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ReconciliationConfiguration.java @@ -20,7 +20,7 @@ import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TARGET_DIR; import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TEST_DIR; -class ReconciliationsConfiguration { +class ReconciliationConfiguration { private static final String PROP = "reconciliation"; private static final String PROP_THREADS = PROP + ".threads"; @@ -33,7 +33,7 @@ class ReconciliationsConfiguration { private final List> generatedTasks; - private ReconciliationsConfiguration() { + private ReconciliationConfiguration() { threads = Integer.parseInt(System.getProperty(PROP_THREADS, "0")); runs = Integer.parseInt(System.getProperty(PROP_RUNS, "1")); @@ -54,14 +54,14 @@ List> getGeneratedTasks() { @Override public String toString() { - return "ReconciliationsConfiguration{" + + return "ReconciliationConfiguration{" + "threads=" + threads + ", runs=" + runs + '}'; } - public static ReconciliationsConfiguration setup() { - ReconciliationsConfiguration configuration = new ReconciliationsConfiguration(); + public static ReconciliationConfiguration setup() { + ReconciliationConfiguration configuration = new ReconciliationConfiguration(); System.out.println("Import: " + configuration); return configuration; } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SchemaConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SchemaConfiguration.java new file mode 100644 index 00000000000..b9f6fcbdaf7 --- /dev/null +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SchemaConfiguration.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.testing.story.sysperf; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static com.evolveum.midpoint.test.util.MidPointTestConstants.TARGET_DIR_PATH; +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TEST_DIR; + +class SchemaConfiguration { + + private static final String PROP = "schema"; + private static final String PROP_SINGLE_VALUED_PROPERTIES = PROP + ".single-valued-properties"; + private static final String PROP_MULTI_VALUED_PROPERTIES = PROP + ".multi-valued-properties"; + private static final String PROP_INDEXED_PERCENTAGE = PROP + ".indexed-percentage"; + + private static final File SCHEMA_TEMPLATE_FILE = new File(TEST_DIR, "schema.vm.xsd"); + + private static final String GENERATED_SCHEMA_DIR_PATH = TARGET_DIR_PATH + "/schema"; + private static final File GENERATED_SCHEMA_DIR = new File(GENERATED_SCHEMA_DIR_PATH); + private static final File GENERATED_SCHEMA_FILE = new File(GENERATED_SCHEMA_DIR, "schema.xsd"); + + private static final String P_SINGLE_PATTERN = "p-single-%04d"; + private static final String P_MULTI_PATTERN = "p-multi-%04d"; + + private final int singleValuedProperties; + private final int multiValuedProperties; + private final int indexedPercentage; + + private SchemaConfiguration() { + this.singleValuedProperties = Integer.parseInt(System.getProperty(PROP_SINGLE_VALUED_PROPERTIES, "100")); + this.multiValuedProperties = Integer.parseInt(System.getProperty(PROP_MULTI_VALUED_PROPERTIES, "10")); + this.indexedPercentage = Integer.parseInt(System.getProperty(PROP_INDEXED_PERCENTAGE, "0")); + + generateSchemaFile(); + } + + int getSingleValuedProperties() { + return singleValuedProperties; + } + + int getMultiValuedProperties() { + return multiValuedProperties; + } + + int getIndexedPercentage() { + return indexedPercentage; + } + + @Override + public String toString() { + return "SchemaConfiguration{" + + "singleValuedProperties=" + singleValuedProperties + + ", multiValuedProperties=" + multiValuedProperties + + ", indexedPercentage=" + indexedPercentage + + '}'; + } + + public static SchemaConfiguration setup() { + System.setProperty("midpoint.global.extensionDir", GENERATED_SCHEMA_DIR_PATH); + + SchemaConfiguration configuration = new SchemaConfiguration(); + System.out.println("Schema: " + configuration); + return configuration; + } + + private void generateSchemaFile() { + + List itemDefList = new ArrayList<>(); + IndexedSelector indexedSelector = new IndexedSelector(); + for (int i = 0; i < singleValuedProperties; i++) { + String name = String.format(P_SINGLE_PATTERN, i); + boolean indexed = indexedSelector.getNext(); + itemDefList.add(new ItemDef(name, "1", indexed)); + } + indexedSelector.reset(); + for (int i = 0; i < multiValuedProperties; i++) { + String name = String.format(P_MULTI_PATTERN, i); + boolean indexed = indexedSelector.getNext(); + itemDefList.add(new ItemDef(name, "unbounded", indexed)); + } + + //noinspection ResultOfMethodCallIgnored + GENERATED_SCHEMA_DIR.mkdirs(); + + VelocityGenerator.generate(SCHEMA_TEMPLATE_FILE, GENERATED_SCHEMA_FILE, + Map.of("itemList", itemDefList)); + } + + public static class ItemDef { + private final String name; + private final String maxOccurs; + private final boolean indexed; + + private ItemDef(String name, String maxOccurs, boolean indexed) { + this.name = name; + this.maxOccurs = maxOccurs; + this.indexed = indexed; + } + + public String getName() { + return name; + } + + public String getMaxOccurs() { + return maxOccurs; + } + + public boolean isIndexed() { + return indexed; + } + } + + private class IndexedSelector { + private int counter; + private boolean getNext() { + counter += indexedPercentage; + if (counter >= 100) { + counter -= 100; + return true; + } else { + return false; + } + } + + public void reset() { + counter = 0; + } + } +} diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java index 4eff8fa544b..3c6c0f3652f 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java @@ -19,12 +19,12 @@ class SummaryOutputFile { void logStart() { writer.println("Started: " + new Date(START) + " (" + START + ")"); - writer.printf("Extension schema variant: %s\n", EXTENSION_SCHEMA_VARIANT); + writer.printf("Schema: %s\n", SCHEMA_CONFIGURATION); writer.printf("Sources: %s\n", SOURCES_CONFIGURATION); writer.printf("Targets: %s\n", TARGETS_CONFIGURATION); writer.printf("Roles: %s\n", ROLES_CONFIGURATION); - writer.printf("Imports: %s\n", IMPORTS_CONFIGURATION); - writer.printf("Reconciliations: %s\n", RECONCILIATIONS_CONFIGURATION); + writer.printf("Import: %s\n", IMPORTS_CONFIGURATION); + writer.printf("Reconciliation: %s\n", RECONCILIATIONS_CONFIGURATION); writer.printf("Recomputation: %s\n", RECOMPUTATION_CONFIGURATION); writer.printf("Progress file: %s\n\n", ProgressOutputFile.FILE); writer.flush(); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java index 7286a2b7855..ca55eada558 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java @@ -62,12 +62,12 @@ public class TestSystemPerformance extends AbstractStoryTest implements Performa private static final File SYSTEM_CONFIGURATION_FILE = new File(TEST_DIR, "system-configuration.xml"); - static final ExtensionSchemaVariant EXTENSION_SCHEMA_VARIANT; + static final SchemaConfiguration SCHEMA_CONFIGURATION; static final SourcesConfiguration SOURCES_CONFIGURATION; static final TargetsConfiguration TARGETS_CONFIGURATION; static final RolesConfiguration ROLES_CONFIGURATION; - static final ImportsConfiguration IMPORTS_CONFIGURATION; - static final ReconciliationsConfiguration RECONCILIATIONS_CONFIGURATION; + static final ImportConfiguration IMPORTS_CONFIGURATION; + static final ReconciliationConfiguration RECONCILIATIONS_CONFIGURATION; static final RecomputationConfiguration RECOMPUTATION_CONFIGURATION; private static final OtherParameters OTHER_PARAMETERS; @@ -102,12 +102,12 @@ public class TestSystemPerformance extends AbstractStoryTest implements Performa private long lastProgress; static { - EXTENSION_SCHEMA_VARIANT = ExtensionSchemaVariant.setup(); + SCHEMA_CONFIGURATION = SchemaConfiguration.setup(); SOURCES_CONFIGURATION = SourcesConfiguration.setup(); TARGETS_CONFIGURATION = TargetsConfiguration.setup(); ROLES_CONFIGURATION = RolesConfiguration.setup(); - IMPORTS_CONFIGURATION = ImportsConfiguration.setup(); - RECONCILIATIONS_CONFIGURATION = ReconciliationsConfiguration.setup(); + IMPORTS_CONFIGURATION = ImportConfiguration.setup(); + RECONCILIATIONS_CONFIGURATION = ReconciliationConfiguration.setup(); RECOMPUTATION_CONFIGURATION = RecomputationConfiguration.setup(); OTHER_PARAMETERS = OtherParameters.setup(); @@ -172,13 +172,15 @@ protected void importSystemTasks(OperationResult initResult) { public void test000LogStart() { testMonitor().addReportSection(REPORT_SECTION_SUMMARY_NAME) - .withColumns("schema", + .withColumns("schemaSingleValuedProperties", "schemaMultiValuedProperties", "schemaIndexedPercentage", "sources", "accounts", "singleValuedInboundMappings", "multiValuedInboundMappings", "attributeValues", "targets", "singleValuedOutboundMappings", "multiValuedOutboundMappings", "importTaskThreads", "reconciliationTaskThreads", "recomputationTaskThreads") - .addRow(EXTENSION_SCHEMA_VARIANT.getName(), + .addRow(SCHEMA_CONFIGURATION.getSingleValuedProperties(), + SCHEMA_CONFIGURATION.getMultiValuedProperties(), + SCHEMA_CONFIGURATION.getIndexedPercentage(), SOURCES_CONFIGURATION.getNumberOfResources(), SOURCES_CONFIGURATION.getNumberOfAccounts(), @@ -198,12 +200,12 @@ public void test000LogStart() { .withColumns("task", "time", "timePerAccount"); logger.info("********** STARTED **********\n"); - logger.info("Extension schema: {}", EXTENSION_SCHEMA_VARIANT); + logger.info("Extension schema: {}", SCHEMA_CONFIGURATION); logger.info("Sources: {}", SOURCES_CONFIGURATION); logger.info("Targets: {}", TARGETS_CONFIGURATION); logger.info("Roles: {}", ROLES_CONFIGURATION); - logger.info("Imports: {}", IMPORTS_CONFIGURATION); - logger.info("Reconciliations: {}", RECONCILIATIONS_CONFIGURATION); + logger.info("Import: {}", IMPORTS_CONFIGURATION); + logger.info("Reconciliation: {}", RECONCILIATIONS_CONFIGURATION); logger.info("Recomputation: {}", RECOMPUTATION_CONFIGURATION); logger.info("Progress file: {}", ProgressOutputFile.FILE); @@ -226,6 +228,8 @@ public void test100Import() throws Exception { int usersBefore = repositoryService.countObjects(UserType.class, null, null, result); + String label = "initial-run-of-"; + for (int taskIndex = 0; taskIndex < TASK_IMPORT_LIST.size(); taskIndex++) { String importName = "import #" + taskIndex; @@ -236,7 +240,7 @@ public void test100Import() throws Exception { lastProgress = 0; addTask(taskImport, result); waitForTaskFinish(taskImport.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, - builder -> builder.taskConsumer(this::recordProgress)); + builder -> builder.taskConsumer(task1 -> recordProgress(label, task1))); then(importName); @@ -250,7 +254,7 @@ public void test100Import() throws Exception { .display() .getObject(); - logTaskFinish(taskAfter, "initial-run-of-"); + logTaskFinish(taskAfter, label); } String accountName = SourceInitializer.getAccountName(0); @@ -313,8 +317,11 @@ public void test110ImportAgain() throws Exception { int usersBefore = repositoryService.countObjects(UserType.class, null, null, result); for (int retry = 0; retry < IMPORTS_CONFIGURATION.getNoOpRuns(); retry++) { + + String label = String.format("no-op-run-%d-of-", retry + 1); + for (int taskIndex = 0; taskIndex < TASK_IMPORT_LIST.size(); taskIndex++) { - String importName = String.format("re-import #%d of resource #%d", retry, taskIndex); + String importName = String.format("re-import #%d of resource #%d", retry+1, taskIndex); when(importName); @@ -325,7 +332,7 @@ public void test110ImportAgain() throws Exception { Thread.sleep(500); waitForTaskFinish(taskImport.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, - builder -> builder.taskConsumer(this::recordProgress)); + builder -> builder.taskConsumer(task1 -> recordProgress(label, task1))); then(importName); @@ -336,7 +343,7 @@ public void test110ImportAgain() throws Exception { .display() .getObject(); - logTaskFinish(taskAfter, String.format("no-op-run-%d-of-", retry+1)); + logTaskFinish(taskAfter, label); } } } @@ -349,8 +356,10 @@ public void test120Reconciliation() throws Exception { OperationResult result = task.getResult(); for (int run = 0; run < RECONCILIATIONS_CONFIGURATION.getRuns(); run++) { + String label = String.format("run-%d-of-", run + 1); + for (int taskIndex = 0; taskIndex < TASK_RECONCILIATION_LIST.size(); taskIndex++) { - String importName = String.format("reconciliation #%d of resource #%d", run, taskIndex); + String importName = String.format("reconciliation #%d of resource #%d", run+1, taskIndex); when(importName); @@ -365,7 +374,7 @@ public void test120Reconciliation() throws Exception { } waitForTaskFinish(reconTask.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, - builder -> builder.taskConsumer(this::recordProgress)); + builder -> builder.taskConsumer(task1 -> recordProgress(label, task1))); then(importName); @@ -373,7 +382,7 @@ public void test120Reconciliation() throws Exception { .display() .getObject(); - logTaskFinish(taskAfter, String.format("recon-run-%d-of-", run+1)); + logTaskFinish(taskAfter, label); } } } @@ -390,7 +399,7 @@ public void test130RecomputeUsers() throws Exception { lastProgress = 0; addTask(TASK_RECOMPUTE, result); waitForTaskFinish(TASK_RECOMPUTE.oid, false, 0, OTHER_PARAMETERS.taskTimeout, false, 0, - builder -> builder.taskConsumer(this::recordProgress)); + builder -> builder.taskConsumer(task1 -> recordProgress("", task1))); then(); @@ -437,7 +446,7 @@ private void logTaskFinish(PrismObject taskAfter, String label) { .addRow(desc, executionTime, timePerAccount); } - private void recordProgress(Task task) { + private void recordProgress(String label, Task task) { Long start = task.getLastRunStartTimestamp(); long progress = task.getProgress(); @@ -446,13 +455,13 @@ private void recordProgress(Task task) { } lastProgress = progress; - progressOutputFile.recordProgress(getTestNameShort(), task); + progressOutputFile.recordProgress(label, task); OperationStatsType stats = task.getStoredOperationStatsOrClone(); logger.info("\n{}", TaskOperationStatsUtil.format(stats)); TaskPerformanceInformation performanceInformation = TaskPerformanceInformation.fromTaskTree( task.getRawTaskObjectClone().asObjectable()); - displayDumpable("performance", performanceInformation); + displayDumpable("performance: " + label + task.getName(), performanceInformation); } } diff --git a/testing/story/src/test/resources/system-perf/schema-basic/user-extension-basic.xsd b/testing/story/src/test/resources/system-perf/schema-basic/user-extension-basic.xsd deleted file mode 100644 index e7172421506..00000000000 --- a/testing/story/src/test/resources/system-perf/schema-basic/user-extension-basic.xsd +++ /dev/null @@ -1,795 +0,0 @@ - - - - - - - - - - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - diff --git a/testing/story/src/test/resources/system-perf/schema-big-global/user-extension-big-global.xsd b/testing/story/src/test/resources/system-perf/schema-big-global/user-extension-big-global.xsd deleted file mode 100644 index 3da4de2d541..00000000000 --- a/testing/story/src/test/resources/system-perf/schema-big-global/user-extension-big-global.xsd +++ /dev/null @@ -1,7106 +0,0 @@ - - - - - - - - - - false - unbounded - - - - - - - false - unbounded - - - - - - - false - unbounded - - - - - - - false - unbounded - - - - - - - false - unbounded - - - - - - - false - unbounded - - - - - - - false - unbounded - - - - - - - false - unbounded - - - - - - - false - unbounded - - - - - - - false - unbounded - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - diff --git a/testing/story/src/test/resources/system-perf/schema-big/user-extension-big.xsd b/testing/story/src/test/resources/system-perf/schema-big/user-extension-big.xsd deleted file mode 100644 index 67bdfd0634f..00000000000 --- a/testing/story/src/test/resources/system-perf/schema-big/user-extension-big.xsd +++ /dev/null @@ -1,7105 +0,0 @@ - - - - - - - - - - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - false - - - - - - - diff --git a/testing/story/src/test/resources/system-perf/schema-indexed/user-extension-indexed.xsd b/testing/story/src/test/resources/system-perf/schema-indexed/user-extension-indexed.xsd deleted file mode 100644 index a53535dee37..00000000000 --- a/testing/story/src/test/resources/system-perf/schema-indexed/user-extension-indexed.xsd +++ /dev/null @@ -1,795 +0,0 @@ - - - - - - - - - - - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - - true - - - - - - diff --git a/testing/story/src/test/resources/system-perf/schema.vm.xsd b/testing/story/src/test/resources/system-perf/schema.vm.xsd new file mode 100644 index 00000000000..e1814dc1738 --- /dev/null +++ b/testing/story/src/test/resources/system-perf/schema.vm.xsd @@ -0,0 +1,41 @@ + + + + + + + + + + + + + +#foreach($item in $itemList) + + + + $item.indexed + + + +#end + + + diff --git a/testing/story/src/test/resources/system-perf/task-recompute.vm.xml b/testing/story/src/test/resources/system-perf/task-recomputation.vm.xml similarity index 97% rename from testing/story/src/test/resources/system-perf/task-recompute.vm.xml rename to testing/story/src/test/resources/system-perf/task-recomputation.vm.xml index b2fd4fb1318..e40e73efc74 100644 --- a/testing/story/src/test/resources/system-perf/task-recompute.vm.xml +++ b/testing/story/src/test/resources/system-perf/task-recomputation.vm.xml @@ -16,7 +16,7 @@ Parameters: xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"> - task-recompute + task-recomputation UserType From 296daf6535d61ffaae27ea7485cf025d3abbb70b Mon Sep 17 00:00:00 2001 From: Tony Tkacik Date: Mon, 3 May 2021 19:32:19 +0200 Subject: [PATCH 19/33] MID-7030: Fixed thread safety in AbstractLazy Signed-off-by: Tony Tkacik --- .../java/com/evolveum/axiom/concepts/AbstractLazy.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/infra/axiom/src/main/java/com/evolveum/axiom/concepts/AbstractLazy.java b/infra/axiom/src/main/java/com/evolveum/axiom/concepts/AbstractLazy.java index f901fdac12b..bd852ee2fce 100644 --- a/infra/axiom/src/main/java/com/evolveum/axiom/concepts/AbstractLazy.java +++ b/infra/axiom/src/main/java/com/evolveum/axiom/concepts/AbstractLazy.java @@ -8,20 +8,21 @@ public abstract class AbstractLazy { - private Object value; + private volatile Object value; AbstractLazy(Object supplier) { value = supplier; } T unwrap() { - if (value instanceof Lazy.Supplier) { + Object val = this.value; + if (val instanceof Lazy.Supplier) { //noinspection unchecked - value = ((Lazy.Supplier) value).get(); + this.value = ((Lazy.Supplier) val).get(); return unwrap(); } //noinspection unchecked - return (T) value; + return (T) val; } @Override From 1296796342212432d7a8341daf50cdd65feb1d58 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 3 May 2021 20:13:33 +0200 Subject: [PATCH 20/33] Fix system perf test (when no targets) --- .../testing/story/sysperf/RolesConfiguration.java | 11 ++++++++--- .../testing/story/sysperf/TestSystemPerformance.java | 12 +++++++++--- .../test/resources/system-perf/role-technical.vm.xml | 6 ++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RolesConfiguration.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RolesConfiguration.java index 25e66572995..b758909f1ab 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RolesConfiguration.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/RolesConfiguration.java @@ -134,9 +134,14 @@ private List> generateTechnicalRoles() { private String createTechnicalRoleDefinition(int index, String oid) { String fileName = String.format("generated-technical-role-%04d.xml", index); - String resourceOid = TARGETS_CONFIGURATION.getGeneratedResources() - .get(index % TARGETS_CONFIGURATION.getNumberOfResources()) - .oid; + String resourceOid; + if (TARGETS_CONFIGURATION.getNumberOfResources() > 0) { + resourceOid = TARGETS_CONFIGURATION.getGeneratedResources() + .get(index % TARGETS_CONFIGURATION.getNumberOfResources()) + .oid; + } else { + resourceOid = ""; + } File generated = new File(TARGET_DIR, fileName); VelocityGenerator.generate(TECHNICAL_ROLE_TEMPLATE_FILE, generated, diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java index ca55eada558..1eed566efbc 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java @@ -273,9 +273,8 @@ public void test100Import() throws Exception { .collect(Collectors.toSet()); displayValue("Technical roles for " + accountName, technicalRoles); - assertUserAfterByUsername(accountName) + PrismObject user = assertUserAfterByUsername(accountName) .assertAssignments(roles.size() + 1) // 1. archetype - .assertRoleMemberhipRefs(roles.size() + technicalRoles.size() + 2) // 1. archetype, 2. role-targets .assertLinks(SOURCES_CONFIGURATION.getNumberOfResources() + TARGETS_CONFIGURATION.getNumberOfResources(), 0) .extension() .assertSize(SOURCES_CONFIGURATION.getSingleValuedMappings() + SOURCES_CONFIGURATION.getMultiValuedMappings()) @@ -285,7 +284,14 @@ public void test100Import() throws Exception { .property(ItemPath.create(getMultiValuedPropertyName(0))) .assertSize(SOURCES_CONFIGURATION.getAttributeValues() * SOURCES_CONFIGURATION.getNumberOfResources()) .end() - .end(); + .end() + .getObject(); + + if (TARGETS_CONFIGURATION.getNumberOfResources() > 0) { + assertThat(user.asObjectable().getRoleMembershipRef().size()) + .as("# of role membership refs") + .isEqualTo(roles.size() + technicalRoles.size() + 2); // 1. archetype, 2. role-targets) + } } private String getTechnicalRoleName(String membership) { diff --git a/testing/story/src/test/resources/system-perf/role-technical.vm.xml b/testing/story/src/test/resources/system-perf/role-technical.vm.xml index becfe4088b6..c9bbcf57ff9 100644 --- a/testing/story/src/test/resources/system-perf/role-technical.vm.xml +++ b/testing/story/src/test/resources/system-perf/role-technical.vm.xml @@ -15,6 +15,8 @@ Parameters: xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"> technical-$index + +#if($resourceOid != "") @@ -22,9 +24,11 @@ Parameters: group +#end g-$index +#if($resourceOid != "") @@ -56,4 +60,6 @@ Parameters: +#end + From 729d699ec466564b14a3f8eb407f5d25ed069398 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 3 May 2021 23:52:11 +0200 Subject: [PATCH 21/33] Make dummy objects thread safe This is an attempt to enable DummyGroup objects to participate in multi-threaded tests. --- .../icf/dummy/resource/DummyObject.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java index 30bd7b0704c..434e4184e3a 100644 --- a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java +++ b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java @@ -12,12 +12,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang.StringUtils; @@ -34,14 +34,14 @@ public abstract class DummyObject implements DebugDumpable { private String id; // private int internalId = -1; private String name; - private Map> attributes = new HashMap<>(); + private final Map> attributes = new ConcurrentHashMap<>(); private Boolean enabled = true; private Date validFrom = null; private Date validTo = null; private String lastModifier; protected DummyResource resource; - private final Set auxiliaryObjectClassNames = new HashSet<>(); + private final Set auxiliaryObjectClassNames = ConcurrentHashMap.newKeySet(); private BreakMode modifyBreakMode = null; @@ -160,7 +160,7 @@ public void replaceAttributeValues(String name, Collection values) throw delayOperation(); Set currentValues = attributes.get(name); if (currentValues == null) { - currentValues = new HashSet<>(); + currentValues = createNewSet(); attributes.put(name, currentValues); } else { currentValues.clear(); @@ -170,12 +170,16 @@ public void replaceAttributeValues(String name, Collection values) throw recordModify(name, null, null, values); } + private Set createNewSet() { + return ConcurrentHashMap.newKeySet(); + } + public void replaceAttributeValues(String name, Object... values) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { checkModifyBreak(); delayOperation(); Set currentValues = attributes.get(name); if (currentValues == null) { - currentValues = new HashSet<>(); + currentValues = createNewSet(); attributes.put(name, currentValues); } else { currentValues.clear(); @@ -200,7 +204,7 @@ public void addAttributeValues(String name, Collection valuesToAdd) throw delayOperation(); Set currentValues = attributes.get(name); if (currentValues == null) { - currentValues = new HashSet<>(); + currentValues = createNewSet(); attributes.put(name, currentValues); } for(T valueToAdd: valuesToAdd) { @@ -214,7 +218,7 @@ public void addAttributeValues(String name, String... valuesToAdd) throws Schema delayOperation(); Set currentValues = attributes.get(name); if (currentValues == null) { - currentValues = new HashSet<>(); + currentValues = createNewSet(); attributes.put(name, currentValues); } for (Object valueToAdd: valuesToAdd) { @@ -268,7 +272,7 @@ public void removeAttributeValues(String name, Collection values) throws delayOperation(); Set currentValues = attributes.get(name); if (currentValues == null) { - currentValues = new HashSet<>(); + currentValues = createNewSet(); attributes.put(name, currentValues); } From b47e62935714670c0a02d8e577d5bcb29bd4806a Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 4 May 2021 09:00:34 +0200 Subject: [PATCH 22/33] Fix null values handling in DummyObject (approx.) As the thread safety was ensured using ConcurrentHashMap (and corresponding Set implementation), the null values can no longer be stored in attributes. This is not a problem, as they do not belong there anyway. This commit filters out such values. Unfortunately, it does not do that 100% consistently, so there are places (like sync delta creation) where such values leak. --- .../icf/dummy/resource/DummyObject.java | 157 +++++++++--------- 1 file changed, 79 insertions(+), 78 deletions(-) diff --git a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java index 434e4184e3a..1f5f2d60ef8 100644 --- a/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java +++ b/icf-connectors/dummy-resource/src/main/java/com/evolveum/icf/dummy/resource/DummyObject.java @@ -8,15 +8,7 @@ import java.io.FileNotFoundException; import java.net.ConnectException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang.StringUtils; @@ -25,9 +17,12 @@ import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.PrettyPrinter; +import static java.util.Collections.*; + /** - * @author Radovan Semancik + * TODO Treat null attribute values more consistently. * + * @author Radovan Semancik */ public abstract class DummyObject implements DebugDumpable { @@ -80,33 +75,36 @@ public Boolean isEnabled() { return enabled; } - public void setEnabled(Boolean enabled) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + public void setEnabled(Boolean enabled) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { checkModifyBreak(); delayOperation(); this.enabled = enabled; - recordModify("_ENABLED", null, null, Arrays.asList(enabled)); + recordModify("_ENABLED", null, null, singletonList(enabled)); } public Date getValidFrom() { return validFrom; } - public void setValidFrom(Date validFrom) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + public void setValidFrom(Date validFrom) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { checkModifyBreak(); delayOperation(); this.validFrom = validFrom; - recordModify("_VALID_FROM", null, null, Arrays.asList(validFrom)); + recordModify("_VALID_FROM", null, null, singletonList(validFrom)); } public Date getValidTo() { return validTo; } - public void setValidTo(Date validTo) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + public void setValidTo(Date validTo) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { checkModifyBreak(); delayOperation(); this.validTo = validTo; - recordModify("_VALID_TO", null, null, Arrays.asList(validTo)); + recordModify("_VALID_TO", null, null, singletonList(validTo)); } public String getLastModifier() { @@ -130,8 +128,8 @@ public Set getAttributeNames() { } public Set getAttributeValues(String attrName, Class type) { - Set values = attributes.get(attrName); - return (Set)values; + //noinspection unchecked + return (Set) attributes.get(attrName); } public T getAttributeValue(String attrName, Class type) { @@ -139,8 +137,8 @@ public T getAttributeValue(String attrName, Class type) { if (values == null || values.isEmpty()) { return null; } - if (values.size()>1) { - throw new IllegalArgumentException("Attempt to fetch single value from a multi-valued attribute "+attrName); + if (values.size() > 1) { + throw new IllegalArgumentException("Attempt to fetch single value from a multi-valued attribute " + attrName); } return values.iterator().next(); } @@ -149,87 +147,95 @@ public String getAttributeValue(String attrName) { return getAttributeValue(attrName,String.class); } - public void replaceAttributeValue(String name, Object value) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { - Collection values = new ArrayList<>(1); - values.add(value); - replaceAttributeValues(name, values); + public void replaceAttributeValue(String name, Object value) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + replaceAttributeValues(name, createCollection(value)); } - public void replaceAttributeValues(String name, Collection values) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + private Set createCollection(Object value) { + return value != null ? singleton(value) : emptySet(); + } + + public void replaceAttributeValues(String name, Collection values) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { checkModifyBreak(); delayOperation(); - Set currentValues = attributes.get(name); - if (currentValues == null) { - currentValues = createNewSet(); - attributes.put(name, currentValues); - } else { - currentValues.clear(); - } - currentValues.addAll(values); + + Set currentValues = getOrCreateAttributeValueSet(name); + currentValues.clear(); + + addNonNullValues(currentValues, values); checkSchema(name, values, "replace"); recordModify(name, null, null, values); } - private Set createNewSet() { - return ConcurrentHashMap.newKeySet(); + private void addNonNullValues(Set currentValues, Collection values) { + for (Object value : values) { + if (value != null) { + currentValues.add(value); + } + } + } + + private Set getOrCreateAttributeValueSet(String name) { + return attributes.computeIfAbsent(name, k -> ConcurrentHashMap.newKeySet()); } - public void replaceAttributeValues(String name, Object... values) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + public void replaceAttributeValues(String name, Object... values) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { checkModifyBreak(); delayOperation(); - Set currentValues = attributes.get(name); - if (currentValues == null) { - currentValues = createNewSet(); - attributes.put(name, currentValues); - } else { - currentValues.clear(); - } + + Set currentValues = getOrCreateAttributeValueSet(name); + currentValues.clear(); + List valuesList = Arrays.asList(values); - currentValues.addAll(valuesList); + addNonNullValues(currentValues, valuesList); checkSchema(name, valuesList, "replace"); + + // Why isn't the same code in the "collection" version of this method (above)? + // Maybe to check null-attribute handling of UCF layer, see TestDummy.test129NullAttributeValue. if (valuesList.isEmpty()) { attributes.remove(name); } - recordModify(name, null, null, Arrays.asList(values)); + recordModify(name, null, null, valuesList); } - public void addAttributeValue(String name, Object value) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { - Collection values = new ArrayList<>(1); - values.add(value); - addAttributeValues(name, values); + public void addAttributeValue(String name, Object value) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + addAttributeValues(name, createCollection(value)); } - public void addAttributeValues(String name, Collection valuesToAdd) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + public void addAttributeValues(String name, Collection valuesToAdd) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { checkModifyBreak(); delayOperation(); - Set currentValues = attributes.get(name); - if (currentValues == null) { - currentValues = createNewSet(); - attributes.put(name, currentValues); - } - for(T valueToAdd: valuesToAdd) { + Set currentValues = getOrCreateAttributeValueSet(name); + for (T valueToAdd: valuesToAdd) { addAttributeValue(name, currentValues, valueToAdd); } recordModify(name, valuesToAdd, null, null); } - public void addAttributeValues(String name, String... valuesToAdd) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + public void addAttributeValues(String name, String... valuesToAdd) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { checkModifyBreak(); delayOperation(); - Set currentValues = attributes.get(name); - if (currentValues == null) { - currentValues = createNewSet(); - attributes.put(name, currentValues); - } + Set currentValues = getOrCreateAttributeValueSet(name); for (Object valueToAdd: valuesToAdd) { addAttributeValue(name, currentValues, valueToAdd); } recordModify(name, Arrays.asList(valuesToAdd), null, null); } - private void addAttributeValue(String attrName, Set currentValues, Object valueToAdd) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + private void addAttributeValue(String attrName, Set currentValues, Object valueToAdd) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { checkModifyBreak(); delayOperation(); + + if (valueToAdd == null) { + return; // Concurrent hash map does not allow null values. + } if (resource != null && !resource.isTolerateDuplicateValues()) { for (Object currentValue: currentValues) { if (currentValue.equals(valueToAdd)) { @@ -261,34 +267,29 @@ private void addAttributeValue(String attrName, Set currentValues, Objec currentValues.add(valueToAdd); } - public void removeAttributeValue(String name, Object value) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { - Collection values = new ArrayList<>(); - values.add(value); - removeAttributeValues(name, values); + public void removeAttributeValue(String name, Object value) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + removeAttributeValues(name, createCollection(value)); } - public void removeAttributeValues(String name, Collection values) throws SchemaViolationException, ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { + public void removeAttributeValues(String name, Collection values) + throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException, InterruptedException { checkModifyBreak(); delayOperation(); - Set currentValues = attributes.get(name); - if (currentValues == null) { - currentValues = createNewSet(); - attributes.put(name, currentValues); - } + Set currentValues = getOrCreateAttributeValueSet(name); - Set valuesToCheck = new HashSet<>(); - valuesToCheck.addAll(currentValues); + Set valuesToCheck = new HashSet<>(currentValues); valuesToCheck.removeAll(values); checkSchema(name, valuesToCheck, "remove"); Iterator iterator = currentValues.iterator(); boolean foundMember = false; - if (name.equals(DummyGroup.ATTR_MEMBERS_NAME) && !resource.isTolerateDuplicateValues()){ + if (name.equals(DummyGroup.ATTR_MEMBERS_NAME) && !resource.isTolerateDuplicateValues()) { checkIfExist(values, currentValues); } - while(iterator.hasNext()) { + while (iterator.hasNext()) { Object currentValue = iterator.next(); boolean found = false; for (Object value: values) { @@ -355,7 +356,7 @@ private void checkIfExist(Collection valuesToDelete, Set currentV } } - if (!found){ + if (!found) { throw new SchemaViolationException("no such member: " + valueToDelete + " in " + currentValues); } } From 2597d6949942c46f10650249372dc1d0d456f603 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Tue, 4 May 2021 10:24:22 +0200 Subject: [PATCH 23/33] POM.xml: added mvn example with remote debugger for IT tests --- pom.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 298af2c8cf3..1931e566461 100644 --- a/pom.xml +++ b/pom.xml @@ -54,9 +54,17 @@ mvn clean install -P -dist -DskipTests -DskipStoryTests=false See "extratest" profile in testing/pom.xml for all individual properties enabling extra tests. + Running a single IT test class from story tests with remote debugger: + mvn integration-test -DskipStoryTests=false -DredirectTestOutputToFile=false \ + -Dmaven.failsafe.debug="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" \ + -pl testing/story -Dit.test=TestSystemPerformance + Note the "maven.failsafe.debug", it is possible to use "maven.surefire.debug" (with -Dtest) too. + Change to "suspend=y" for the test to wait for the debugger (e.g. debugging the startup). + See: https://maven.apache.org/surefire/maven-surefire-plugin/examples/debugging.html + and https://maven.apache.org/surefire/maven-failsafe-plugin/examples/debugging.html + Running unit+IT tests of a selected module (-pl) with output to stdout: mvn clean install -DredirectTestOutputToFile=false -pl model/model-intest - --> From f4ca24a865fb492c35c35028ce4ae981c2493f09 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 4 May 2021 13:10:27 +0200 Subject: [PATCH 24/33] Improve TestSystemPerformance reporting Also, temporarily disabled some asserts. --- .../story/sysperf/OtherParameters.java | 56 ++++++++- .../story/sysperf/TestSystemPerformance.java | 106 +++++++++++++----- 2 files changed, 126 insertions(+), 36 deletions(-) diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/OtherParameters.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/OtherParameters.java index 820feafecf2..c2d45a37602 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/OtherParameters.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/OtherParameters.java @@ -1,18 +1,64 @@ package com.evolveum.midpoint.testing.story.sysperf; +import org.jetbrains.annotations.NotNull; + +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.*; + public class OtherParameters { + private static final String PROP_LABEL = "label"; private static final String PROP_TASK_TIMEOUT = "taskTimeout"; + final String label; final int taskTimeout; - private OtherParameters(int taskTimeout) { - this.taskTimeout = taskTimeout; + private OtherParameters() { + this.label = System.getProperty(PROP_LABEL, createDefaultLabel()); + this.taskTimeout = Integer.parseInt(System.getProperty(PROP_TASK_TIMEOUT, "1800000")); // 30 minutes + } + + private String createDefaultLabel() { + return SOURCES_CONFIGURATION.getNumberOfResources() + "s-" + + getSourceMappingsLabel() + "-" + + TARGETS_CONFIGURATION.getNumberOfResources() + "t-" + + getTargetMappingsLabel() + "-" + + getAssignmentsLabel() + ; + } + + @NotNull + private String getSourceMappingsLabel() { + int single = SOURCES_CONFIGURATION.getSingleValuedMappings(); + int multi = SOURCES_CONFIGURATION.getMultiValuedMappings(); + if (single == multi) { + return single + "m"; + } else { + return single + "sm-" + multi + "mm"; + } + } + + @NotNull + private String getTargetMappingsLabel() { + int single = TARGETS_CONFIGURATION.getSingleValuedMappings(); + int multi = TARGETS_CONFIGURATION.getMultiValuedMappings(); + if (single == multi) { + return single + "m"; + } else { + return single + "sm" + multi + "mm"; + } + } + + private String getAssignmentsLabel() { + int min = ROLES_CONFIGURATION.getNumberOfAssignmentsMin(); + int max = ROLES_CONFIGURATION.getNumberOfAssignmentsMax(); + if (min == max) { + return min + "a"; + } else { + return min + "-" + max + "a"; + } } static OtherParameters setup() { - return new OtherParameters( - Integer.parseInt(System.getProperty(PROP_TASK_TIMEOUT, "1800000")) // 30 minutes - ); + return new OtherParameters(); } } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java index 1eed566efbc..07d3650a772 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java @@ -7,6 +7,8 @@ package com.evolveum.midpoint.testing.story.sysperf; +import static com.evolveum.midpoint.util.MiscUtil.emptyIfNull; + import static org.assertj.core.api.Assertions.assertThat; import static com.evolveum.midpoint.test.util.MidPointTestConstants.TARGET_DIR_PATH; @@ -14,12 +16,15 @@ import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import org.apache.commons.collections4.ListUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; @@ -92,13 +97,18 @@ public class TestSystemPerformance extends AbstractStoryTest implements Performa private static final String REPORT_FILE_PREFIX = TARGET_DIR_PATH + "/" + START + "-report"; private static final String REPORT_SECTION_SUMMARY_NAME = "summary"; private static final String REPORT_SECTION_TASK_EXECUTION_NAME = "taskExecution"; + private static final String REPORT_SECTION_TASK_EXECUTION_DENORMALIZED_NAME = "taskExecutionDenormalized"; private TestReportSection taskExecutionReportSection; + private TestReportSection taskExecutionDenormalizedReportSection; private final ProgressOutputFile progressOutputFile = new ProgressOutputFile(); private final SummaryOutputFile summaryOutputFile = new SummaryOutputFile(); private final DetailsOutputFile detailsOutputFile = new DetailsOutputFile(); + private final List summaryReportHeader = new ArrayList<>(); + private final List summaryReportDataRow = new ArrayList<>(); + private long lastProgress; static { @@ -151,36 +161,28 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti for (TestResource resource : BUSINESS_ROLE_LIST) { repoAdd(resource, initResult); } - } - @Override - protected boolean isAvoidLoggingChange() { - return false; // we want logging from our system config + createSummaryReportData(); } - @Override - protected File getSystemConfigurationFile() { - return SYSTEM_CONFIGURATION_FILE; - } + private void createSummaryReportData() { - @Override - protected void importSystemTasks(OperationResult initResult) { - // nothing here - } - - @Test - public void test000LogStart() { - - testMonitor().addReportSection(REPORT_SECTION_SUMMARY_NAME) - .withColumns("schemaSingleValuedProperties", "schemaMultiValuedProperties", "schemaIndexedPercentage", + summaryReportHeader.clear(); + summaryReportHeader.addAll( + Arrays.asList( + "label", "sources", "accounts", "singleValuedInboundMappings", "multiValuedInboundMappings", "attributeValues", "targets", "singleValuedOutboundMappings", "multiValuedOutboundMappings", + "businessRoles", "technicalRoles", "assignmentsMin", "assignmentsMax", "inducementsMin", "inducementsMax", + "schemaSingleValuedProperties", "schemaMultiValuedProperties", "schemaIndexedPercentage", "importTaskThreads", "reconciliationTaskThreads", - "recomputationTaskThreads") - .addRow(SCHEMA_CONFIGURATION.getSingleValuedProperties(), - SCHEMA_CONFIGURATION.getMultiValuedProperties(), - SCHEMA_CONFIGURATION.getIndexedPercentage(), + "recomputationTaskThreads")); + + summaryReportDataRow.clear(); + summaryReportDataRow.addAll( + Arrays.asList( + OTHER_PARAMETERS.label, SOURCES_CONFIGURATION.getNumberOfResources(), SOURCES_CONFIGURATION.getNumberOfAccounts(), @@ -192,12 +194,50 @@ public void test000LogStart() { TARGETS_CONFIGURATION.getSingleValuedMappings(), TARGETS_CONFIGURATION.getMultiValuedMappings(), + ROLES_CONFIGURATION.getNumberOfBusinessRoles(), + ROLES_CONFIGURATION.getNumberOfTechnicalRoles(), + ROLES_CONFIGURATION.getNumberOfAssignmentsMin(), + ROLES_CONFIGURATION.getNumberOfAssignmentsMax(), + ROLES_CONFIGURATION.getNumberOfInducementsMin(), + ROLES_CONFIGURATION.getNumberOfInducementsMax(), + + SCHEMA_CONFIGURATION.getSingleValuedProperties(), + SCHEMA_CONFIGURATION.getMultiValuedProperties(), + SCHEMA_CONFIGURATION.getIndexedPercentage(), + IMPORTS_CONFIGURATION.getThreads(), RECONCILIATIONS_CONFIGURATION.getThreads(), - RECOMPUTATION_CONFIGURATION.getThreads()); + RECOMPUTATION_CONFIGURATION.getThreads())); + } + + @Override + protected boolean isAvoidLoggingChange() { + return false; // we want logging from our system config + } + + @Override + protected File getSystemConfigurationFile() { + return SYSTEM_CONFIGURATION_FILE; + } + @Override + protected void importSystemTasks(OperationResult initResult) { + // nothing here + } + + @Test + public void test000LogStart() { + + testMonitor().addReportSection(REPORT_SECTION_SUMMARY_NAME) + .withColumns(summaryReportHeader.toArray(new String[0])) + .addRow(summaryReportDataRow.toArray()); + + List taskExecutionHeader = Arrays.asList("task", "time", "timePerAccount"); taskExecutionReportSection = testMonitor().addReportSection(REPORT_SECTION_TASK_EXECUTION_NAME) - .withColumns("task", "time", "timePerAccount"); + .withColumns(taskExecutionHeader.toArray(new String[0])); + + taskExecutionDenormalizedReportSection = testMonitor().addReportSection(REPORT_SECTION_TASK_EXECUTION_DENORMALIZED_NAME) + .withColumns(ListUtils.union(summaryReportHeader, taskExecutionHeader).toArray(new String[0])); logger.info("********** STARTED **********\n"); logger.info("Extension schema: {}", SCHEMA_CONFIGURATION); @@ -264,7 +304,7 @@ public void test100Import() throws Exception { displayValue("Roles for " + accountName, roles); Set memberships = RESOURCE_TARGET_LIST.stream() - .flatMap(r -> getMemberships(accountName, r).stream()) + .flatMap(r -> emptyIfNull(getMemberships(accountName, r)).stream()) .collect(Collectors.toSet()); displayValue("Memberships for " + accountName, memberships); @@ -287,11 +327,12 @@ public void test100Import() throws Exception { .end() .getObject(); - if (TARGETS_CONFIGURATION.getNumberOfResources() > 0) { - assertThat(user.asObjectable().getRoleMembershipRef().size()) - .as("# of role membership refs") - .isEqualTo(roles.size() + technicalRoles.size() + 2); // 1. archetype, 2. role-targets) - } + // temporarily disabled +// if (TARGETS_CONFIGURATION.getNumberOfResources() > 0) { +// assertThat(user.asObjectable().getRoleMembershipRef().size()) +// .as("# of role membership refs") +// .isEqualTo(roles.size() + technicalRoles.size() + 2); // 1. archetype, 2. role-targets) +// } } private String getTechnicalRoleName(String membership) { @@ -448,8 +489,11 @@ private void logTaskFinish(PrismObject taskAfter, String label) { summaryOutputFile.logTaskFinish(desc, executionTime, timePerAccount); detailsOutputFile.logTaskFinish(desc, taskAfter.asObjectable(), performanceInformation); + List dataRow = Arrays.asList(desc, executionTime, timePerAccount); taskExecutionReportSection - .addRow(desc, executionTime, timePerAccount); + .addRow(dataRow.toArray()); + taskExecutionDenormalizedReportSection + .addRow(ListUtils.union(summaryReportDataRow, dataRow).toArray()); } private void recordProgress(String label, Task task) { From 99ef22ef34a9298421bb016e0ec7214b9d965248 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 4 May 2021 14:07:02 +0200 Subject: [PATCH 25/33] Fix target resource def in system perf test --- .../src/test/resources/system-perf/resource-target.vm.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testing/story/src/test/resources/system-perf/resource-target.vm.xml b/testing/story/src/test/resources/system-perf/resource-target.vm.xml index 8b2cf2ebee1..a8ac6cf4aad 100644 --- a/testing/story/src/test/resources/system-perf/resource-target.vm.xml +++ b/testing/story/src/test/resources/system-perf/resource-target.vm.xml @@ -70,11 +70,12 @@ Configuration parameters: ri:a-single-$index + data extension/p-single-$index @@ -85,11 +86,12 @@ Configuration parameters: ri:a-multi-$index + data extension/p-multi-$index From e54f48cdb03ec5b9fc1c73582b8f5fbb4de875ce Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Tue, 4 May 2021 10:41:19 +0200 Subject: [PATCH 26/33] TestMonitor.java: javadoc fixes --- .../midpoint/tools/testng/TestMonitor.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/TestMonitor.java b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/TestMonitor.java index 92ba1d7ebdd..10e4486f82f 100644 --- a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/TestMonitor.java +++ b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/TestMonitor.java @@ -36,7 +36,7 @@ public class TestMonitor { * Name of a system property that specifies file name prefix for report. * If system property is null, report is dumped to standard output. * Specified file name prefix can be absolute or relative from working directory, - * e.g. {@code target/perf-report}. + * e.g. `target/perf-report`. */ public static final String PERF_REPORT_PREFIX_PROPERTY_NAME = "mp.perf.report.prefix"; @@ -48,15 +48,16 @@ public class TestMonitor { /** * Collection of report sections that will be formatted using {@link #dumpReport(String)}. - * which can be extended in two ways: - *
    - *
  • calling {@link #addReportSection(String)} and then filling the
  • - *
+ * This can be extended in one of these ways: + * + * * Directly by using {@link #addReportSection(String)} and then filling the returned + * {@link TestReportSection}. + * * Using {@link #addReportCallback(ReportCallback)} which can be registered beforehand. */ private final List reportSections = new ArrayList<>(); /** - * + * Callbacks that are called during the report dump, see {@link #addReportCallback)}. */ private final List reportCallbacks = new ArrayList<>(); @@ -95,6 +96,12 @@ public Split stopwatchStart(String name, String description) { return stopwatch(name, description).start(); } + /** + * This registers the callback that will be executed during the report dump and can be used + * to add new sections. + * The advantage of callback is that it can be prepared during the initialization of the test + * monitor without the need to change the point where the dump occurs (some `@After...` method). + */ public TestMonitor addReportCallback(ReportCallback reportCallback) { reportCallbacks.add(reportCallback); return this; @@ -122,7 +129,7 @@ public void dumpReport(String testName) { new FileOutputStream(filename)))) { dumpReport(reportMetadata, out); } catch (FileNotFoundException e) { - System.out.println("Creating report file failed with: " + e.toString()); + System.out.println("Creating report file failed with: " + e); System.out.println("Falling back to stdout dump:"); dumpReportToStdout(reportMetadata); } From 33c4bd88dd2168747a4bf9068a887151889501c2 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Tue, 4 May 2021 14:16:21 +0200 Subject: [PATCH 27/33] perf testing: fixed @AfterClass dumpReport timing --- .../AbstractSchemaPerformanceTest.java | 15 +++-------- .../test/util/AbstractSpringTest.java | 25 +++++++++++-------- .../tools/testng/AbstractUnitTest.java | 8 ++++++ .../testng/PerformanceTestClassMixin.java | 13 +++++----- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java index d72640979f9..3b79dc30711 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2018 Evolveum and contributors + * Copyright (C) 2010-2021 Evolveum and contributors * * This work is dual-licensed under the Apache License 2.0 * and European Union Public License. See LICENSE file for details. @@ -10,18 +10,17 @@ import java.io.File; import java.io.IOException; -import com.evolveum.midpoint.prism.impl.match.MatchingRuleRegistryFactory; -import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import org.javasimon.Split; import org.javasimon.Stopwatch; import org.jetbrains.annotations.NotNull; -import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeSuite; import org.xml.sax.SAXException; import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.impl.match.MatchingRuleRegistryFactory; +import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; import com.evolveum.midpoint.schema.constants.MidPointConstants; @@ -34,7 +33,7 @@ import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; -public abstract class AbstractSchemaPerformanceTest extends AbstractUnitTest implements PerformanceTestClassMixin { +public abstract class AbstractSchemaPerformanceTest extends AbstractUnitTest implements PerformanceTestClassMixin { protected static final String LABEL = "new-mapxnode"; @@ -102,10 +101,4 @@ protected double measureSingle(String label, CheckedProducer producer, long e public PrismObject getJack() throws SchemaException, IOException { return getPrismContext().parserFor(USER_JACK_FILE).parse(); } - - @AfterClass - @Override - public void dumpReport() { - PerformanceTestClassMixin.super.dumpReport(); - } } diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java index 71a29dfc8a1..810ead8a432 100644 --- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2020 Evolveum and contributors + * Copyright (C) 2010-2021 Evolveum and contributors * * This work is dual-licensed under the Apache License 2.0 * and European Union Public License. See LICENSE file for details. @@ -17,10 +17,7 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; -import com.evolveum.midpoint.tools.testng.MidpointTestContext; -import com.evolveum.midpoint.tools.testng.MidpointTestMixin; -import com.evolveum.midpoint.tools.testng.SimpleMidpointTestContext; -import com.evolveum.midpoint.tools.testng.TestMonitor; +import com.evolveum.midpoint.tools.testng.*; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -65,6 +62,14 @@ public void displayTestClassFooter() { displayTestFooter("Finishing with TEST CLASS: " + getClass().getName()); } + // see the comment in PerformanceTestClassMixin for explanation + @AfterClass + public void dumpReport() { + if (this instanceof PerformanceTestClassMixin) { + ((PerformanceTestClassMixin) this).dumpReport(getClass().getSimpleName()); + } + } + @BeforeMethod public void startTestContext(ITestResult testResult) throws Exception { SimpleMidpointTestContext context = SimpleMidpointTestContext.create(testResult); @@ -91,18 +96,18 @@ public MidpointTestContext getTestContext() { /** * This method null all fields which are not static, final or primitive type. - *

+ * * All this is just to make GC work during DirtiesContext after every test class, * because test class instances are not GCed immediately. * If they hold autowired fields like sessionFactory (for example * through SqlRepositoryService impl), their memory footprint is getting big. * This can manifest as failed test initialization because of OOM in modules like model-intest. * Strangely, this will not fail the Jenkins build (but makes it much slower). - *

+ * * Note that this does not work for components injected through constructor into * final fields - if we need this cleanup, make the field non-final. */ - @AfterClass(alwaysRun = true) + @AfterClass(alwaysRun = true, dependsOnMethods = "dumpReport") protected void clearClassFields() throws Exception { logger.trace("Clearing all fields for test class {}", getClass().getName()); clearClassFields(this, getClass()); @@ -114,9 +119,7 @@ private void clearClassFields(Object object, Class forClass) throws Exception } for (Field field : forClass.getDeclaredFields()) { - // we need to skip testMonitor to have it non-null in PerformanceTestMixin#dumpReport - if (field.getName().equals("testMonitor") - || Modifier.isFinal(field.getModifiers()) + if (Modifier.isFinal(field.getModifiers()) || Modifier.isStatic(field.getModifiers()) || field.getType().isPrimitive()) { continue; diff --git a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/AbstractUnitTest.java b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/AbstractUnitTest.java index 25ead7f0b59..1c2188e8c37 100644 --- a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/AbstractUnitTest.java +++ b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/AbstractUnitTest.java @@ -51,6 +51,14 @@ public void displayTestClassFooter() { displayTestFooter("Finishing with TEST CLASS: " + getClass().getName()); } + // see the comment in PerformanceTestClassMixin for explanation + @AfterClass + public void dumpReport() { + if (this instanceof PerformanceTestClassMixin) { + ((PerformanceTestClassMixin) this).dumpReport(getClass().getSimpleName()); + } + } + @BeforeMethod public void startTestContext(ITestResult testResult) { SimpleMidpointTestContext context = SimpleMidpointTestContext.create(testResult); diff --git a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestClassMixin.java b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestClassMixin.java index 34aef7074f0..454b8b0c1d8 100644 --- a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestClassMixin.java +++ b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestClassMixin.java @@ -1,12 +1,11 @@ /* - * Copyright (C) 2010-2020 Evolveum and contributors + * Copyright (C) 2010-2021 Evolveum and contributors * * This work is dual-licensed under the Apache License 2.0 * and European Union Public License. See LICENSE file for details. */ package com.evolveum.midpoint.tools.testng; -import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; /** @@ -22,8 +21,10 @@ default void initTestMonitor() { createTestMonitor(); } - @AfterClass - default void dumpReport() { - dumpReport(getClass().getSimpleName()); - } + /* + * @AfterClass dumpReport() implemented in AbstractUnitTest and AbstractSpringTest. + * After-class method is implemented in both concrete classes with `instanceof` check, + * because if implemented here the method is called too late. + * This is not a problem for before-class method, so it stays here. + */ } From ff6cbadedb06da49560acaf0edbeec261da55beb Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Tue, 4 May 2021 21:12:14 +0200 Subject: [PATCH 28/33] perf-test-support: @Before/AfterMethod/Class support is now in classes Mixin interfaces are just marker interfaces, explanation there. --- .../AbstractSchemaPerformanceTest.java | 7 --- .../test/util/AbstractSpringTest.java | 44 +++++++++++++++---- .../tools/testng/AbstractUnitTest.java | 43 +++++++++++++++--- .../testng/PerformanceTestClassMixin.java | 28 ++++++------ .../testng/PerformanceTestMethodMixin.java | 31 +++++++------ 5 files changed, 101 insertions(+), 52 deletions(-) diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java index 3b79dc30711..fcca3fbefdc 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java @@ -14,7 +14,6 @@ import org.javasimon.Split; import org.javasimon.Stopwatch; import org.jetbrains.annotations.NotNull; -import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeSuite; import org.xml.sax.SAXException; @@ -58,12 +57,6 @@ public void setup() throws SchemaException, SAXException, IOException { assert !InternalsConfig.isConsistencyChecks(); } - @BeforeClass - @Override - public void initTestMonitor() { - PerformanceTestClassMixin.super.initTestMonitor(); - } - protected void measure(String label, String note, CheckedProducer producer) throws CommonException, IOException { measure(label, note, producer, DEFAULT_EXECUTION, DEFAULT_REPEATS); } diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java index 810ead8a432..22ca341fb36 100644 --- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java @@ -7,6 +7,7 @@ package com.evolveum.midpoint.test.util; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.jetbrains.annotations.Nullable; @@ -34,6 +35,7 @@ public abstract class AbstractSpringTest extends AbstractTestNGSpringContextTest */ protected final Trace logger = TraceManager.getTrace(getClass()); + // region perf-test support private TestMonitor testMonitor; /** Called only by tests that need it, implements performance mixin interface. */ @@ -52,23 +54,49 @@ public TestMonitor testMonitor() { return testMonitor; } - @BeforeClass - public void displayTestClassTitle() { - displayTestTitle("Starting TEST CLASS: " + getClass().getName()); + // see the comment in PerformanceTestMethodMixin for explanation + @BeforeMethod + public void initTestMethodMonitor() { + if (this instanceof PerformanceTestMethodMixin) { + createTestMonitor(); + } } - @AfterClass - public void displayTestClassFooter() { - displayTestFooter("Finishing with TEST CLASS: " + getClass().getName()); + // see the comment in PerformanceTestMethodMixin for explanation + @AfterMethod + public void dumpMethodReport(Method method) { + if (this instanceof PerformanceTestMethodMixin) { + ((PerformanceTestMethodMixin) this).dumpReport( + getClass().getSimpleName() + "#" + method.getName()); + } + } + + // see the comment in PerformanceTestClassMixin for explanation + @BeforeClass + public void initTestClassMonitor() { + if (this instanceof PerformanceTestClassMixin) { + createTestMonitor(); + } } // see the comment in PerformanceTestClassMixin for explanation @AfterClass - public void dumpReport() { + public void dumpClassReport() { if (this instanceof PerformanceTestClassMixin) { ((PerformanceTestClassMixin) this).dumpReport(getClass().getSimpleName()); } } + // endregion + + @BeforeClass + public void displayTestClassTitle() { + displayTestTitle("Starting TEST CLASS: " + getClass().getName()); + } + + @AfterClass + public void displayTestClassFooter() { + displayTestFooter("Finishing with TEST CLASS: " + getClass().getName()); + } @BeforeMethod public void startTestContext(ITestResult testResult) throws Exception { @@ -107,7 +135,7 @@ public MidpointTestContext getTestContext() { * Note that this does not work for components injected through constructor into * final fields - if we need this cleanup, make the field non-final. */ - @AfterClass(alwaysRun = true, dependsOnMethods = "dumpReport") + @AfterClass(alwaysRun = true, dependsOnMethods = "dumpClassReport") protected void clearClassFields() throws Exception { logger.trace("Clearing all fields for test class {}", getClass().getName()); clearClassFields(this, getClass()); diff --git a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/AbstractUnitTest.java b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/AbstractUnitTest.java index 1c2188e8c37..297299eb8c2 100644 --- a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/AbstractUnitTest.java +++ b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/AbstractUnitTest.java @@ -6,6 +6,8 @@ */ package com.evolveum.midpoint.tools.testng; +import java.lang.reflect.Method; + import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,6 +25,7 @@ public abstract class AbstractUnitTest implements MidpointTestMixin { protected final Logger logger = LoggerFactory.getLogger(getClass()); + // region perf-test support private TestMonitor testMonitor; /** Called only by tests that need it, implements performance mixin interface. */ @@ -41,23 +44,49 @@ public TestMonitor testMonitor() { return testMonitor; } - @BeforeClass - public void displayTestClassTitle() { - displayTestTitle("Starting TEST CLASS: " + getClass().getName()); + // see the comment in PerformanceTestMethodMixin for explanation + @BeforeMethod + public void initTestMethodMonitor() { + if (this instanceof PerformanceTestMethodMixin) { + createTestMonitor(); + } } - @AfterClass - public void displayTestClassFooter() { - displayTestFooter("Finishing with TEST CLASS: " + getClass().getName()); + // see the comment in PerformanceTestMethodMixin for explanation + @AfterMethod + public void dumpMethodReport(Method method) { + if (this instanceof PerformanceTestMethodMixin) { + ((PerformanceTestMethodMixin) this).dumpReport( + getClass().getSimpleName() + "#" + method.getName()); + } + } + + // see the comment in PerformanceTestClassMixin for explanation + @BeforeClass + public void initTestClassMonitor() { + if (this instanceof PerformanceTestClassMixin) { + createTestMonitor(); + } } // see the comment in PerformanceTestClassMixin for explanation @AfterClass - public void dumpReport() { + public void dumpClassReport() { if (this instanceof PerformanceTestClassMixin) { ((PerformanceTestClassMixin) this).dumpReport(getClass().getSimpleName()); } } + // endregion + + @BeforeClass + public void displayTestClassTitle() { + displayTestTitle("Starting TEST CLASS: " + getClass().getName()); + } + + @AfterClass + public void displayTestClassFooter() { + displayTestFooter("Finishing with TEST CLASS: " + getClass().getName()); + } @BeforeMethod public void startTestContext(ITestResult testResult) { diff --git a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestClassMixin.java b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestClassMixin.java index 454b8b0c1d8..8207ad5ac96 100644 --- a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestClassMixin.java +++ b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestClassMixin.java @@ -6,25 +6,25 @@ */ package com.evolveum.midpoint.tools.testng; -import org.testng.annotations.BeforeClass; - /** * Mixin supporting work with {@link TestMonitor} at the class-scope level * (one test report for all the methods in the test class). * Details of setting of {@link TestMonitor} is up to the class, methods from * {@link PerformanceTestCommonMixin} must be implemented. + * + * [NOTE] + * ==== + * Actual `@Before/AfterClass` methods are implemented in `AbstractUnitTest` + * and `AbstractSpringTest` using `instanceof` check for two reasons: + * + * * If `@AfterClass` is in interface it is executed after all lifecycle methods from the class + * hierarchy - which may happen after the Spring context is destroyed (for integration tests). + * * If mixin interface is on the abstract class the lifecycle methods *are not called at all* + * in the test subclasses, which really sucks. + * + * So currently this is only marker interface used by lifecycle methods in our two top-level + * classes (unit/Spring) and everything works fine. + * ==== */ public interface PerformanceTestClassMixin extends PerformanceTestCommonMixin { - - @BeforeClass - default void initTestMonitor() { - createTestMonitor(); - } - - /* - * @AfterClass dumpReport() implemented in AbstractUnitTest and AbstractSpringTest. - * After-class method is implemented in both concrete classes with `instanceof` check, - * because if implemented here the method is called too late. - * This is not a problem for before-class method, so it stays here. - */ } diff --git a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestMethodMixin.java b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestMethodMixin.java index 90dd37fa043..6a74808d235 100644 --- a/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestMethodMixin.java +++ b/tools/test-ng/src/main/java/com/evolveum/midpoint/tools/testng/PerformanceTestMethodMixin.java @@ -1,31 +1,30 @@ /* - * Copyright (C) 2010-2020 Evolveum and contributors + * Copyright (C) 2010-2021 Evolveum and contributors * * This work is dual-licensed under the Apache License 2.0 * and European Union Public License. See LICENSE file for details. */ package com.evolveum.midpoint.tools.testng; -import java.lang.reflect.Method; - -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; - /** * Mixin supporting work with {@link TestMonitor} at the method-scope level * (one test report for each test method). * Details of setting of {@link TestMonitor} is up to the class, methods from * {@link PerformanceTestCommonMixin} must be implemented. + * + * [NOTE] + * ==== + * Actual `@Before/AfterMethod` methods are implemented in `AbstractUnitTest` + * and `AbstractSpringTest` using `instanceof` check for two reasons: + * + * * If mixin interface is on the abstract class the lifecycle methods *are not called at all* + * in the test subclasses, which really sucks. + * * To use the same strategy as in {@link PerformanceTestClassMixin} which actually has another + * good reason to do this (issue that does not affect the method lifecycle that much). + * + * So currently this is only marker interface used by lifecycle methods in our two top-level + * classes (unit/Spring) and everything works fine. + * ==== */ public interface PerformanceTestMethodMixin extends PerformanceTestCommonMixin { - - @BeforeMethod - default void initTestMonitor() { - createTestMonitor(); - } - - @AfterMethod - default void dumpReport(Method method) { - dumpReport(getClass().getSimpleName() + "#" + method.getName()); - } } From 9204d039472696135bed0fb4a75e0d452205ef7f Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Wed, 5 May 2021 13:05:02 +0200 Subject: [PATCH 29/33] common-core-3.xsd: removed superfluous [ZWNBSP] chars from docs --- .../src/main/resources/xml/ns/public/common/common-core-3.xsd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd index 9d5d6096f8e..3a2ceaa5352 100755 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -141,7 +141,7 @@ that each object must have to live in our system (identifier, name).

- All objects are identified by OID. The OID is an immutable identifier + All objects are identified by OID. The OID is an immutable identifier (usually UUID). Except the OID all the objects have human-readable name. The name is usually unique for each object type, but this is not a strict requirement. @@ -7455,7 +7455,7 @@ When set to true, midPoint will try to avoid adding attribute values that are already there and remove values that are not there. Some resources do not tolerate such operations and they respond with errors. However midPoint cannot rely on transactions. MidPoint's - lock-free relativistic model provides the necessary consistency, occasional redundant + lock-free relativistic model provides the necessary consistency, occasional redundant additions or deletions may happen. If this option is turned on then midPoint will read the data from resource right before the operation and filter our any redundant changes. This requires additional operation and it increases the risk of inconsistencies. However From b69ee7c4aab14da8b33f444114e00a84fd7bde33 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Wed, 5 May 2021 20:14:46 +0200 Subject: [PATCH 30/33] Fill performance report directly from stat printer AbstractStatisticsPrinter was refactored to be able to provide access to the raw data. This raw data is then fed to TestReportSection when creating global performance report. --- .../statistics/AbstractStatisticsPrinter.java | 62 +++++++++++++------ .../statistics/AsciiTableFormatting.java | 5 ++ .../CachePerformanceInformationPrinter.java | 5 +- .../midpoint/schema/statistics/Data.java | 12 +++- .../schema/statistics/Formatting.java | 11 ++++ .../IterativeTaskInformationPrinter.java | 5 +- ...erationsPerformanceInformationPrinter.java | 15 +++-- .../ProvisioningStatisticsPrinter.java | 5 +- .../schema/statistics/RawFormatting.java | 23 +++++++ ...positoryPerformanceInformationPrinter.java | 4 +- .../StructuredTaskProgressPrinter.java | 8 ++- .../SynchronizationInformationPrinter.java | 5 +- ...nagementPerformanceInformationPrinter.java | 4 +- .../midpoint/test/util/TestReportUtil.java | 43 ++++--------- 14 files changed, 130 insertions(+), 77 deletions(-) create mode 100644 infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/RawFormatting.java diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/AbstractStatisticsPrinter.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/AbstractStatisticsPrinter.java index 840d45549c8..1e983bf7aef 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/AbstractStatisticsPrinter.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/AbstractStatisticsPrinter.java @@ -9,6 +9,8 @@ import org.jetbrains.annotations.NotNull; +import java.util.function.Supplier; + import static com.evolveum.midpoint.util.MiscUtil.or0; /** @@ -17,7 +19,20 @@ public abstract class AbstractStatisticsPrinter { public enum Format { - TEXT, CSV + + TEXT(AsciiTableFormatting::new), + CSV(CsvFormatting::new), + RAW(RawFormatting::new); + + @NotNull private final Supplier formattingSupplier; + + Format(@NotNull Supplier formattingSupplier) { + this.formattingSupplier = formattingSupplier; + } + + Formatting createFormatting() { + return formattingSupplier.get(); + } } public enum SortBy { @@ -60,7 +75,7 @@ public AbstractStatisticsPrinter(@NotNull T information, Options options, Intege this.seconds = seconds; } - protected void initData() { + void initData() { if (data == null) { data = new Data(); } else { @@ -68,23 +83,22 @@ protected void initData() { } } - protected void initFormatting() { + void initFormatting() { if (formatting == null) { - if (isCsv()) { - formatting = new CsvFormatting(); - } else { - formatting = new AsciiTableFormatting(); - } + formatting = options.format.createFormatting(); } else { throw new IllegalStateException("formatting already created"); } } - protected boolean isCsv() { - return options.format == Format.CSV; + public String print() { + prepare(); + return applyFormatting(); } - protected String applyFormatting() { + public abstract void prepare(); + + String applyFormatting() { return formatting.apply(data); } @@ -123,21 +137,21 @@ long zeroIfNull(Long n) { return n != null ? n : 0; } - protected X nullIfFalse(boolean condition, X value) { + X nullIfFalse(boolean condition, X value) { return condition ? value : null; } public static class Options { - final Format format; - final SortBy sortBy; + @NotNull final Format format; + @NotNull final SortBy sortBy; public Options() { this(null, null); } public Options(Format format, SortBy sortBy) { - this.format = format; - this.sortBy = sortBy; + this.format = format != null ? format : Format.TEXT; + this.sortBy = sortBy != null ? sortBy : SortBy.NAME; } } @@ -146,18 +160,26 @@ String formatString() { } String formatInt() { - return isCsv() ? "%d" : "%,d"; + return formatting.isNiceNumbersFormatting() ? "%,d" : "%d"; } String formatFloat1() { - return isCsv() ? "%f" : "%,.1f"; + return formatting.isNiceNumbersFormatting() ? "%,.1f" : "%f"; } String formatPercent1() { - return isCsv() ? "%f%%" : "%.1f%%"; + return formatting.isNiceNumbersFormatting() ? "%.1f%%" : "%f%%"; } String formatPercent2() { - return isCsv() ? "%f%%" : "%.2f%%"; + return formatting.isNiceNumbersFormatting() ? "%.2f%%" : "%f%%"; + } + + public Data getData() { + return data; + } + + public Formatting getFormatting() { + return formatting; } } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/AsciiTableFormatting.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/AsciiTableFormatting.java index 26f7ada5588..26ad8629926 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/AsciiTableFormatting.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/AsciiTableFormatting.java @@ -98,4 +98,9 @@ private String getTableAsString() { } return sb.toString(); } + + @Override + public boolean isNiceNumbersFormatting() { + return true; + } } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/CachePerformanceInformationPrinter.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/CachePerformanceInformationPrinter.java index 9248b35fd50..5abdafdf92a 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/CachePerformanceInformationPrinter.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/CachePerformanceInformationPrinter.java @@ -24,15 +24,14 @@ */ public class CachePerformanceInformationPrinter extends AbstractStatisticsPrinter { - public CachePerformanceInformationPrinter(@NotNull CachesPerformanceInformationType information, Options options) { + CachePerformanceInformationPrinter(@NotNull CachesPerformanceInformationType information, Options options) { super(information, options, null, null); } - public String print() { + public void prepare() { List caches = getSortedCaches(); createData(caches); createFormatting(); - return applyFormatting(); } @NotNull diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/Data.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/Data.java index dc8c833cc41..3e67e0f70d5 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/Data.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/Data.java @@ -7,16 +7,17 @@ package com.evolveum.midpoint.schema.statistics; -import com.evolveum.midpoint.util.annotation.Experimental; - import java.util.ArrayList; import java.util.List; +import java.util.stream.Stream; + +import com.evolveum.midpoint.util.annotation.Experimental; /** * Data to be displayed. This is an abstract form suitable for outputting in various formats (ascii, csv, ...). */ @Experimental -class Data { +public class Data { private final List records = new ArrayList<>(); @@ -34,6 +35,11 @@ public List getRecords() { return records; } + public Stream getRawDataStream() { + return records.stream() + .map(record -> record.values.toArray()); + } + static class Record { private final List values = new ArrayList<>(); diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/Formatting.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/Formatting.java index d8d0921c214..443710f6477 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/Formatting.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/Formatting.java @@ -15,6 +15,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.stream.Collectors; /** * Describes formatting at abstract level. @@ -25,6 +26,12 @@ public abstract class Formatting { final List columns = new ArrayList<>(); + public List getColumnLabels() { + return columns.stream() + .map(column -> column.label) + .collect(Collectors.toList()); + } + static class Column { final String label; final Alignment alignment; @@ -63,5 +70,9 @@ enum Alignment { LEFT, RIGHT } + public boolean isNiceNumbersFormatting() { + return false; + } + public abstract String apply(Data data); } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/IterativeTaskInformationPrinter.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/IterativeTaskInformationPrinter.java index 20d64109102..b4dc3f57273 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/IterativeTaskInformationPrinter.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/IterativeTaskInformationPrinter.java @@ -28,11 +28,10 @@ public IterativeTaskInformationPrinter(@NotNull IterativeTaskInformationType inf super(information, options, null, null); } - public String print() { + @Override + public void prepare() { createData(); createFormatting(); - - return applyFormatting() + "\n"; } private void createData() { diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/OperationsPerformanceInformationPrinter.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/OperationsPerformanceInformationPrinter.java index 506f7174b5c..5a3224c25e5 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/OperationsPerformanceInformationPrinter.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/OperationsPerformanceInformationPrinter.java @@ -28,6 +28,8 @@ public class OperationsPerformanceInformationPrinter extends AbstractStatisticsP private final boolean viaAspect; + private List operations; + public OperationsPerformanceInformationPrinter(@NotNull OperationsPerformanceInformationType information, Options options, Integer iterations, Integer seconds, boolean viaAspect) { super(information, options, iterations, seconds); @@ -37,17 +39,22 @@ public OperationsPerformanceInformationPrinter(@NotNull OperationsPerformanceInf /** * @param nullIfNone If there are no data, returns empty string. */ - public String print(boolean nullIfNone) { - List operations = getSortedOperations(); + String print(boolean nullIfNone) { + prepare(); if (operations.isEmpty() && nullIfNone) { return null; } else { - createData(operations); - createFormatting(); return applyFormatting(); } } + @Override + public void prepare() { + operations = getSortedOperations(); + createData(operations); + createFormatting(); + } + @NotNull private List getSortedOperations() { return information.getOperation().stream() diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/ProvisioningStatisticsPrinter.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/ProvisioningStatisticsPrinter.java index cedf92dd2a7..3bed0fc3ade 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/ProvisioningStatisticsPrinter.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/ProvisioningStatisticsPrinter.java @@ -24,11 +24,10 @@ public ProvisioningStatisticsPrinter(ProvisioningStatisticsType information, Opt super(information, options, null, null); } - public String print() { + @Override + public void prepare() { createData(); createFormatting(); - - return applyFormatting() + "\n"; } private void createData() { diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/RawFormatting.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/RawFormatting.java new file mode 100644 index 00000000000..1503b4237e9 --- /dev/null +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/RawFormatting.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.schema.statistics; + +import com.evolveum.midpoint.util.annotation.Experimental; + +/** + * Formatting that - in fact - does nothing. + * + * It just provides abstract Formatting functionality, namely maintains a list of column names. + */ +@Experimental +public class RawFormatting extends Formatting { + + public String apply(Data data) { + return "Raw formatting has no String representation"; + } +} diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/RepositoryPerformanceInformationPrinter.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/RepositoryPerformanceInformationPrinter.java index 09a0c82c7cc..4c2b2427c1d 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/RepositoryPerformanceInformationPrinter.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/RepositoryPerformanceInformationPrinter.java @@ -29,11 +29,11 @@ public RepositoryPerformanceInformationPrinter(@NotNull RepositoryPerformanceInf super(information, options, iterations, seconds); } - public String print() { + @Override + public void prepare() { List operations = getSortedOperations(); createData(operations); createFormatting(); - return applyFormatting(); } @NotNull diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/StructuredTaskProgressPrinter.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/StructuredTaskProgressPrinter.java index e0021e81bcb..66dcd3edd5b 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/StructuredTaskProgressPrinter.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/StructuredTaskProgressPrinter.java @@ -27,13 +27,17 @@ public class StructuredTaskProgressPrinter extends AbstractStatisticsPrinter operations = getSortedOperations(); createData(operations); createFormatting(); - return applyFormatting(); } @NotNull diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java index dc2028284f0..bb5529a5fb8 100644 --- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java @@ -6,14 +6,14 @@ */ package com.evolveum.midpoint.test.util; -import java.util.Comparator; +import static com.evolveum.midpoint.schema.statistics.AbstractStatisticsPrinter.Format.RAW; +import static com.evolveum.midpoint.schema.statistics.AbstractStatisticsPrinter.SortBy.TIME; -import com.evolveum.midpoint.schema.statistics.OperationsPerformanceInformationUtil; +import com.evolveum.midpoint.schema.statistics.*; import com.evolveum.midpoint.tools.testng.TestMonitor; import com.evolveum.midpoint.tools.testng.TestReportSection; import com.evolveum.midpoint.util.statistics.OperationsPerformanceMonitor; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationsPerformanceInformationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SingleOperationPerformanceInformationType; public class TestReportUtil { @@ -25,37 +25,16 @@ public static void reportGlobalPerfData(TestMonitor testMonitor) { OperationsPerformanceInformationType performanceInformation = OperationsPerformanceInformationUtil.toOperationsPerformanceInformationType( OperationsPerformanceMonitor.INSTANCE.getGlobalPerformanceInformation()); - TestReportSection section = testMonitor.addReportSection("globalPerformanceInformation") - .withColumns("Operation", "Count", "Total time (ms)", "Min", "Max", "Avg"); - - performanceInformation.getOperation().stream() - .sorted(Comparator.comparing(SingleOperationPerformanceInformationType::getTotalTime).reversed()) - .forEach(op -> { - int count = zeroIfNull(op.getInvocationCount()); - float totalTime = zeroIfNull(op.getTotalTime()) / 1000.0f; - section.addRow( - op.getName(), - count, - totalTime, - zeroIfNull(op.getMinTime()) / 1000.0f, - zeroIfNull(op.getMaxTime()) / 1000.0f, - avg(totalTime, count)); - }); - // TODO: How to adapt this to the code above? See OperationsPerformanceInformationPrinter for the details. -// OperationsPerformanceInformationUtil.format(performanceInformation, -// new AbstractStatisticsPrinter.Options(CSV, TIME), null, null)); - } - // TODO: cleanup! taken from AbstractStatisticsPrinter - private static int zeroIfNull(Integer n) { - return n != null ? n : 0; - } + OperationsPerformanceInformationPrinter printer = new OperationsPerformanceInformationPrinter(performanceInformation, + new AbstractStatisticsPrinter.Options(RAW, TIME), null, null, false); - private static long zeroIfNull(Long n) { - return n != null ? n : 0; - } + printer.prepare(); + Data data = printer.getData(); + Formatting formatting = printer.getFormatting(); - private static Number avg(Number total, int count) { - return total != null && count > 0 ? total.floatValue() / count : null; + TestReportSection section = testMonitor.addReportSection("globalPerformanceInformation") + .withColumns(formatting.getColumnLabels().toArray(new String[0])); + data.getRawDataStream().forEach(section::addRow); } } From cb41a8e2018f67ea68d09545fdf2473c19e2b08a Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Thu, 6 May 2021 09:37:19 +0200 Subject: [PATCH 31/33] Improve system performance test 1) Various task statistics are logged in CSV format. 2) File names now contain short test characterization. 3) Overall time is logged into summary file. --- .../CachePerformanceInformationPrinter.java | 2 +- .../midpoint/test/util/TestReportUtil.java | 73 ++++++++++++++++++- .../story/sysperf/DetailsOutputFile.java | 16 ++-- .../story/sysperf/ProgressOutputFile.java | 12 +-- .../story/sysperf/SummaryOutputFile.java | 21 +++++- .../story/sysperf/TestSystemPerformance.java | 32 ++++++-- 6 files changed, 132 insertions(+), 24 deletions(-) diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/CachePerformanceInformationPrinter.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/CachePerformanceInformationPrinter.java index 5abdafdf92a..2de89ec7f1f 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/CachePerformanceInformationPrinter.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/statistics/CachePerformanceInformationPrinter.java @@ -24,7 +24,7 @@ */ public class CachePerformanceInformationPrinter extends AbstractStatisticsPrinter { - CachePerformanceInformationPrinter(@NotNull CachesPerformanceInformationType information, Options options) { + public CachePerformanceInformationPrinter(@NotNull CachesPerformanceInformationType information, Options options) { super(information, options, null, null); } diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java index bb5529a5fb8..5132804b409 100644 --- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java @@ -7,13 +7,14 @@ package com.evolveum.midpoint.test.util; import static com.evolveum.midpoint.schema.statistics.AbstractStatisticsPrinter.Format.RAW; +import static com.evolveum.midpoint.schema.statistics.AbstractStatisticsPrinter.SortBy.NAME; import static com.evolveum.midpoint.schema.statistics.AbstractStatisticsPrinter.SortBy.TIME; import com.evolveum.midpoint.schema.statistics.*; import com.evolveum.midpoint.tools.testng.TestMonitor; import com.evolveum.midpoint.tools.testng.TestReportSection; import com.evolveum.midpoint.util.statistics.OperationsPerformanceMonitor; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationsPerformanceInformationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; public class TestReportUtil { @@ -29,12 +30,80 @@ public static void reportGlobalPerfData(TestMonitor testMonitor) { OperationsPerformanceInformationPrinter printer = new OperationsPerformanceInformationPrinter(performanceInformation, new AbstractStatisticsPrinter.Options(RAW, TIME), null, null, false); + addPrinterData(testMonitor, "globalPerformanceInformation", printer); + } + + private static void addPrinterData(TestMonitor testMonitor, String sectionName, AbstractStatisticsPrinter printer) { printer.prepare(); Data data = printer.getData(); Formatting formatting = printer.getFormatting(); - TestReportSection section = testMonitor.addReportSection("globalPerformanceInformation") + TestReportSection section = testMonitor.addReportSection(sectionName) .withColumns(formatting.getColumnLabels().toArray(new String[0])); data.getRawDataStream().forEach(section::addRow); } + + /** + * Adds operation performance for a given task to the {@link TestMonitor}. + */ + public static void reportTaskOperationPerformance(TestMonitor testMonitor, String label, + TaskType task, Integer iterations, Integer seconds) { + OperationsPerformanceInformationType performanceInformationFromTask = + task.getOperationStats() != null ? task.getOperationStats().getOperationsPerformanceInformation() : null; + OperationsPerformanceInformationType performanceInformation = performanceInformationFromTask != null ? + performanceInformationFromTask : new OperationsPerformanceInformationType(); + + OperationsPerformanceInformationPrinter printer = new OperationsPerformanceInformationPrinter(performanceInformation, + new AbstractStatisticsPrinter.Options(RAW, TIME), iterations, seconds, false); + + addPrinterData(testMonitor, label + ":operationPerformance", printer); + } + + /** + * Adds repository performance for a given task to the {@link TestMonitor}. + */ + public static void reportTaskRepositoryPerformance(TestMonitor testMonitor, String label, + TaskType task, Integer iterations, Integer seconds) { + RepositoryPerformanceInformationType performanceInformationFromTask = + task.getOperationStats() != null ? task.getOperationStats().getRepositoryPerformanceInformation() : null; + RepositoryPerformanceInformationType performanceInformation = performanceInformationFromTask != null ? + performanceInformationFromTask : new RepositoryPerformanceInformationType(); + + RepositoryPerformanceInformationPrinter printer = new RepositoryPerformanceInformationPrinter(performanceInformation, + new AbstractStatisticsPrinter.Options(RAW, NAME), iterations, seconds); + + addPrinterData(testMonitor, label + ":repositoryPerformance", printer); + } + + /** + * Adds caches performance for a given task to the {@link TestMonitor}. + */ + public static void reportTaskCachesPerformance(TestMonitor testMonitor, String label, TaskType task) { + CachesPerformanceInformationType performanceInformationFromTask = + task.getOperationStats() != null ? task.getOperationStats().getCachesPerformanceInformation() : null; + CachesPerformanceInformationType performanceInformation = performanceInformationFromTask != null ? + performanceInformationFromTask : new CachesPerformanceInformationType(); + + CachePerformanceInformationPrinter printer = new CachePerformanceInformationPrinter(performanceInformation, + new AbstractStatisticsPrinter.Options(RAW, NAME)); + + addPrinterData(testMonitor, label + ":cachePerformance", printer); + } + + /** + * Adds provisioning operations statistics for a given task to the {@link TestMonitor}. + */ + public static void reportTaskProvisioningStatistics(TestMonitor testMonitor, String label, TaskType task) { + EnvironmentalPerformanceInformationType envPerformanceInformationFromTask = + task.getOperationStats() != null ? task.getOperationStats().getEnvironmentalPerformanceInformation() : null; + ProvisioningStatisticsType provisioningStatisticsFromTask = envPerformanceInformationFromTask != null ? + envPerformanceInformationFromTask.getProvisioningStatistics() : null; + ProvisioningStatisticsType provisioningStatistics = provisioningStatisticsFromTask != null ? + provisioningStatisticsFromTask : new ProvisioningStatisticsType(); + + ProvisioningStatisticsPrinter printer = new ProvisioningStatisticsPrinter(provisioningStatistics, + new AbstractStatisticsPrinter.Options(RAW, NAME)); + + addPrinterData(testMonitor, label + ":provisioningStatistics", printer); + } } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java index eca72ed5495..5da5a5c7f2d 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/DetailsOutputFile.java @@ -1,24 +1,26 @@ package com.evolveum.midpoint.testing.story.sysperf; -import com.evolveum.midpoint.schema.util.task.TaskOperationStatsUtil; -import com.evolveum.midpoint.schema.util.task.TaskPerformanceInformation; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.*; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; -import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.START; -import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TARGET_DIR; +import com.evolveum.midpoint.schema.util.task.TaskOperationStatsUtil; +import com.evolveum.midpoint.schema.util.task.TaskPerformanceInformation; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; class DetailsOutputFile { - private static final File FILE = new File(TARGET_DIR, START + "-details.txt"); private final PrintWriter writer; DetailsOutputFile() throws IOException { - writer = new PrintWriter(new FileWriter(FILE)); + writer = new PrintWriter(new FileWriter(getFile())); + } + + private File getFile() { + return new File(TARGET_DIR, START + "-" + OTHER_PARAMETERS.label + "-details.txt"); } void logTaskFinish(String desc, TaskType taskAfter, TaskPerformanceInformation performanceInformation) { diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java index 03fe38a50e7..54e05b49f48 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/ProgressOutputFile.java @@ -1,25 +1,27 @@ package com.evolveum.midpoint.testing.story.sysperf; -import com.evolveum.midpoint.task.api.Task; +import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.*; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; -import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.TARGET_DIR; -import static com.evolveum.midpoint.testing.story.sysperf.TestSystemPerformance.START; +import com.evolveum.midpoint.task.api.Task; class ProgressOutputFile { - static final File FILE = new File(TARGET_DIR, START + "-progress.csv"); private final PrintWriter writer; ProgressOutputFile() throws IOException { - writer = new PrintWriter(new FileWriter(FILE)); + writer = new PrintWriter(new FileWriter(getFile())); writer.println("test;time;progress"); } + private File getFile() { + return new File(TARGET_DIR, START + "-" + OTHER_PARAMETERS.label + "-progress.csv"); + } + void recordProgress(String label, Task task) { long start = task.getLastRunStartTimestamp(); Long lastFinish = task.getLastRunFinishTimestamp(); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java index 3c6c0f3652f..c6834e0d5cf 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/SummaryOutputFile.java @@ -10,23 +10,27 @@ class SummaryOutputFile { - private static final File FILE = new File(TARGET_DIR, START + "-summary.txt"); private final PrintWriter writer; SummaryOutputFile() throws IOException { - writer = new PrintWriter(new FileWriter(FILE)); + writer = new PrintWriter(new FileWriter(getFile())); + } + + private File getFile() { + return new File(TARGET_DIR, START + "-" + OTHER_PARAMETERS.label + "-summary.txt"); } void logStart() { writer.println("Started: " + new Date(START) + " (" + START + ")"); + writer.println("Label: " + OTHER_PARAMETERS.label); + writer.println(); writer.printf("Schema: %s\n", SCHEMA_CONFIGURATION); writer.printf("Sources: %s\n", SOURCES_CONFIGURATION); writer.printf("Targets: %s\n", TARGETS_CONFIGURATION); writer.printf("Roles: %s\n", ROLES_CONFIGURATION); writer.printf("Import: %s\n", IMPORTS_CONFIGURATION); writer.printf("Reconciliation: %s\n", RECONCILIATIONS_CONFIGURATION); - writer.printf("Recomputation: %s\n", RECOMPUTATION_CONFIGURATION); - writer.printf("Progress file: %s\n\n", ProgressOutputFile.FILE); + writer.printf("Recomputation: %s\n\n", RECOMPUTATION_CONFIGURATION); writer.flush(); } @@ -36,4 +40,13 @@ void logTaskFinish(String desc, long executionTime, double timePerAccount) { writer.printf("Time per account: %,.1f ms\n\n", timePerAccount); writer.flush(); } + + void logFinish() { + long end = System.currentTimeMillis(); + writer.printf("Finished at: %s\n", new Date(end)); + long millis = end - START; + writer.printf("Took: %,.1f seconds = %.1f minutes\n", millis / 1000.0, millis / 60000.0); + writer.printf("Accounts: %,d\n", SOURCES_CONFIGURATION.getNumberOfAccounts()); + writer.flush(); + } } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java index 07d3650a772..6ecf85a4899 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/sysperf/TestSystemPerformance.java @@ -24,6 +24,8 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; +import com.evolveum.midpoint.test.util.TestReportUtil; + import org.apache.commons.collections4.ListUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; @@ -75,7 +77,7 @@ public class TestSystemPerformance extends AbstractStoryTest implements Performa static final ReconciliationConfiguration RECONCILIATIONS_CONFIGURATION; static final RecomputationConfiguration RECOMPUTATION_CONFIGURATION; - private static final OtherParameters OTHER_PARAMETERS; + static final OtherParameters OTHER_PARAMETERS; private static final List RESOURCE_SOURCE_LIST; private static final List RESOURCE_TARGET_LIST; @@ -94,7 +96,6 @@ public class TestSystemPerformance extends AbstractStoryTest implements Performa static final long START = System.currentTimeMillis(); - private static final String REPORT_FILE_PREFIX = TARGET_DIR_PATH + "/" + START + "-report"; private static final String REPORT_SECTION_SUMMARY_NAME = "summary"; private static final String REPORT_SECTION_TASK_EXECUTION_NAME = "taskExecution"; private static final String REPORT_SECTION_TASK_EXECUTION_DENORMALIZED_NAME = "taskExecutionDenormalized"; @@ -130,7 +131,11 @@ public class TestSystemPerformance extends AbstractStoryTest implements Performa TASK_RECONCILIATION_LIST = RECONCILIATIONS_CONFIGURATION.getGeneratedTasks(); TASK_RECOMPUTE = RECOMPUTATION_CONFIGURATION.getGeneratedTask(); - System.setProperty(PERF_REPORT_PREFIX_PROPERTY_NAME, REPORT_FILE_PREFIX); + System.setProperty(PERF_REPORT_PREFIX_PROPERTY_NAME, createReportFilePrefix()); + } + + private static String createReportFilePrefix() { + return TARGET_DIR_PATH + "/" + START + "-" + OTHER_PARAMETERS.label + "-report"; } public TestSystemPerformance() throws IOException { @@ -247,7 +252,6 @@ public void test000LogStart() { logger.info("Import: {}", IMPORTS_CONFIGURATION); logger.info("Reconciliation: {}", RECONCILIATIONS_CONFIGURATION); logger.info("Recomputation: {}", RECOMPUTATION_CONFIGURATION); - logger.info("Progress file: {}", ProgressOutputFile.FILE); summaryOutputFile.logStart(); } @@ -457,6 +461,11 @@ public void test130RecomputeUsers() throws Exception { logTaskFinish(taskAfter, ""); } + @Test + public void test999Finish() { + logFinish(); + } + private long getExecutionTime(PrismObject taskAfter) { long start = XmlTypeConverter.toMillis(taskAfter.asObjectable().getLastRunStartTimestamp()); long end = XmlTypeConverter.toMillis(taskAfter.asObjectable().getLastRunFinishTimestamp()); @@ -478,7 +487,9 @@ private void logTaskFinish(PrismObject taskAfter, String label) { TaskPerformanceInformation performanceInformation = TaskPerformanceInformation.fromTaskTree(taskAfter.asObjectable()); long executionTime = getExecutionTime(taskAfter); - double timePerAccount = (double) executionTime / (double) SOURCES_CONFIGURATION.getNumberOfAccounts(); + int executionTimeSeconds = (int) (executionTime / 1000); + int numberOfAccounts = SOURCES_CONFIGURATION.getNumberOfAccounts(); + double timePerAccount = (double) executionTime / (double) numberOfAccounts; logger.info("********** FINISHED: {} **********\n", desc); logger.info(String.format("Task execution time: %,d ms", executionTime)); @@ -494,6 +505,17 @@ private void logTaskFinish(PrismObject taskAfter, String label) { .addRow(dataRow.toArray()); taskExecutionDenormalizedReportSection .addRow(ListUtils.union(summaryReportDataRow, dataRow).toArray()); + + TestReportUtil.reportTaskOperationPerformance(testMonitor(), desc, taskAfter.asObjectable(), + numberOfAccounts, executionTimeSeconds); + TestReportUtil.reportTaskRepositoryPerformance(testMonitor(), desc, taskAfter.asObjectable(), + numberOfAccounts, executionTimeSeconds); + TestReportUtil.reportTaskCachesPerformance(testMonitor(), desc, taskAfter.asObjectable()); + TestReportUtil.reportTaskProvisioningStatistics(testMonitor(), desc, taskAfter.asObjectable()); + } + + private void logFinish() { + summaryOutputFile.logFinish(); } private void recordProgress(String label, Task task) { From 94633f26070b58b42826e3548db29ee4c10b2d56 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Thu, 6 May 2021 10:34:23 +0200 Subject: [PATCH 32/33] Removed unused/forgotten OracleConverter.java --- .../midpoint/repo/sql/OracleConverter.java | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/OracleConverter.java diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/OracleConverter.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/OracleConverter.java deleted file mode 100644 index 712e743b148..00000000000 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/OracleConverter.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2010-2013 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.repo.sql; - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Types; -/** - * @author skublik - */ -public class OracleConverter {//extends ConverterSqlAndJavaObject { - -// public T convertToValue(ResultSet rs, String nameOfColumn, Class javaClazz) throws SQLException { -// int index = rs.findColumn(nameOfColumn); -// return convertToValue(rs, index, javaClazz); -// } -// -// public T convertToValue(ResultSet rs, int index, Class javaClazz) throws SQLException { -// ResultSetMetaData metadata = rs.getMetaData(); -// int type = metadata.getColumnType(index); -//// if(javaClazz.equals(Long.class)) { -//// -//// } -// if(Types.) -// if(javaClazz.equals(String.class)) { -// return (T) rs.getString(nameOfColumn); -// } -// } - -// public Types getSqlType(Object value) { -// -// } -} From 546864be718dde61ecb0e0030c6d5a2f2f556599 Mon Sep 17 00:00:00 2001 From: kate Date: Thu, 6 May 2021 12:53:24 +0200 Subject: [PATCH 33/33] captcha schrodinger id is changed --- .../web/util/SchrodingerComponentInitListener.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/SchrodingerComponentInitListener.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/SchrodingerComponentInitListener.java index 3294754e4e9..0f4c1ffe42a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/SchrodingerComponentInitListener.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/SchrodingerComponentInitListener.java @@ -9,6 +9,8 @@ import java.io.Serializable; import javax.xml.namespace.QName; +import com.evolveum.midpoint.gui.api.component.captcha.CaptchaPanel; + import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.wicket.AttributeModifier; @@ -52,7 +54,11 @@ public void onInitialize(Component component) { } private void handleId(Component component) { - writeDataAttribute(component, ATTR_ID, component.getId()); + if (component instanceof CaptchaPanel) { + writeDataAttribute(component, ATTR_ID, component.getId() + ((CaptchaPanel) component).getRandomText()); + } else { + writeDataAttribute(component, ATTR_ID, component.getId()); + } } private void writeDataAttribute(Component component, String key, String value) {