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); - } - } -}