Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Aug 31, 2021
2 parents 788b9af + 4497e9f commit a8f0c0a
Show file tree
Hide file tree
Showing 15 changed files with 186 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ public PrismContainerValueWrapper<C> createValueWrapper(PrismContainerWrapper<C>

List<ItemWrapper<?, ?>> children = createChildren(parent, value, containerValueWrapper, context);

VirtualContainersSpecificationType virtualContainerSpec = context.findVirtualContainerConfiguration(parent.getPath());
VirtualContainersSpecificationType virtualContainerSpec = null;
if (parent != null) {
virtualContainerSpec = context.findVirtualContainerConfiguration(parent.getPath());
}
if (virtualContainerSpec != null) {
for (ItemWrapper<?, ?> child : children) {
if (childNotDefined(virtualContainerSpec, child)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ protected boolean getOptionsPanelVisibility() {

public ExecuteChangeOptionsDto getExecuteChangeOptions() {
ExecuteChangeOptionsPanel optionsPanel = (ExecuteChangeOptionsPanel) get(ID_EXECUTE_OPTIONS);
return optionsPanel.getModelObject();
return optionsPanel != null ? optionsPanel.getModelObject() : new ExecuteChangeOptionsDto();
}

//TODO make abstract
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ protected boolean getOptionsPanelVisibility() {

public ExecuteChangeOptionsDto getExecuteChangeOptions() {
ExecuteChangeOptionsPanel optionsPanel = (ExecuteChangeOptionsPanel) get(ID_EXECUTE_OPTIONS);
return optionsPanel.getModelObject();
return optionsPanel != null ? optionsPanel.getModelObject() : new ExecuteChangeOptionsDto();
}

public PrismObject<O> getPrismObject() {
Expand Down
4 changes: 4 additions & 0 deletions repo/repo-sqale/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>

<dependency>
<groupId>org.jetbrains</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
package com.evolveum.midpoint.repo.sqale;

import java.lang.reflect.Field;
import java.util.UUID;
import javax.xml.namespace.QName;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.jetbrains.annotations.Nullable;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;

Expand Down Expand Up @@ -53,6 +55,14 @@ public static int objectVersionAsInt(PrismObject<?> prismObject) {
}
}

public static @Nullable UUID oidToUUid(@Nullable String oid) {
try {
return oid != null ? UUID.fromString(oid) : null;
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Cannot convert oid '" + oid + "' to UUID", e);
}
}

/** Parametrized type friendly version of {@link Object#getClass()}. */
public static <S> Class<S> getClass(S object) {
//noinspection unchecked
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,11 @@ private void initCustomColumns(
subConfigColumn, CONF_AUDIT_SERVICE_EVENT_RECORD_PROPERTY_NAME);
// No type definition for now, it's all String or String implicit conversion.

ColumnMetadata columnMetadata =
ColumnMetadata.named(columnName).ofType(Types.NVARCHAR).withSize(255);
ColumnMetadata columnMetadata = ColumnMetadata.named(columnName).ofType(Types.VARCHAR);
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().startTransaction()) {
jdbcSession.addColumn(QAuditEventRecord.TABLE_NAME,
ColumnMetadata.named(columnName).ofType(Types.VARCHAR).withSize(255));
jdbcSession.addColumn(QAuditEventRecord.TABLE_NAME, columnMetadata);
jdbcSession.commit();
}
}
Expand All @@ -181,7 +178,6 @@ private String getStringFromConfig(Configuration config, String key) {
}

return value;

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public class MAuditEventRecord {
public String parameter;
public String result;
public String message;

// values normalized with PrismContext.createCanonicalItemPath
public String[] changedItemPaths;
public UUID[] resourceOids;
public Jsonb properties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
import java.sql.Types;
import java.time.Instant;

import com.querydsl.core.types.dsl.DateTimePath;
import com.querydsl.core.types.dsl.EnumPath;
import com.querydsl.core.types.dsl.NumberPath;
import com.querydsl.core.types.dsl.StringPath;
import com.querydsl.core.types.dsl.*;
import com.querydsl.sql.ColumnMetadata;

import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType;
Expand Down Expand Up @@ -88,7 +85,8 @@ public class QAuditEventRecord extends FlexibleRelationalPathBase<MAuditEventRec
ColumnMetadata.named("result").ofType(Types.VARCHAR);
public static final ColumnMetadata MESSAGE =
ColumnMetadata.named("message").ofType(Types.VARCHAR);
// TODO String[] changedItemPaths;
public static final ColumnMetadata CHANGED_ITEM_PATHS =
ColumnMetadata.named("changedItemPaths").ofType(Types.ARRAY);
// TODO UUID[] resourceOids;
// TODO Jsonb properties;
// TODO Jsonb ext;
Expand Down Expand Up @@ -131,6 +129,8 @@ public class QAuditEventRecord extends FlexibleRelationalPathBase<MAuditEventRec
public final StringPath parameter = createString("parameter", PARAMETER);
public final StringPath result = createString("result", RESULT);
public final StringPath message = createString("message", MESSAGE);
public final ArrayPath<String[], String> changedItemPaths =
createArray("changedItemPaths", String[].class, CHANGED_ITEM_PATHS);
// TODO columns above

public QAuditEventRecord(String variable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@
import com.evolveum.midpoint.audit.api.AuditEventStage;
import com.evolveum.midpoint.audit.api.AuditEventType;
import com.evolveum.midpoint.prism.PrismReferenceValue;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.SqaleUtils;
import com.evolveum.midpoint.repo.sqale.mapping.SqaleTableMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.xml.ns._public.common.audit_3.*;
import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordCustomColumnPropertyType;
import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;

/**
* Mapping between {@link QAuditEventRecord} and {@link AuditEventRecordType}.
Expand Down Expand Up @@ -68,12 +72,10 @@ private QAuditEventRecordMapping(@NotNull SqaleRepoContext repositoryContext) {
addItemMapping(F_RESULT, stringMapper(q -> q.result));
addItemMapping(F_MESSAGE, stringMapper(q -> q.message));

/* TODO the rest
addItemMapping(F_CHANGED_ITEM, DetailTableItemFilterProcessor.mapper(
QAuditItem.class,
joinOn((r, i) -> r.id.eq(i.recordId)),
CanonicalItemPathItemFilterProcessor.mapper(ai -> ai.changedItemPath)));
addItemMapping(F_CHANGED_ITEM, multiValueMapper(q -> q.changedItemPaths, String.class,
(ItemPathType i) -> prismContext().createCanonicalItemPath(i.getItemPath()).asString()));

/* TODO
Function<QAuditResource, StringPath> rootToQueryItem = ai -> ai.resourceOid;
addItemMapping(F_RESOURCE_OID, DetailTableItemFilterProcessor.mapper(
QAuditResource.class,
Expand Down Expand Up @@ -138,30 +140,30 @@ public AuditEventRecordType toSchemaObject(MAuditEventRecord row) {
// prismContext in constructor ensures complex type definition
AuditEventRecordType record = new AuditEventRecordType(prismContext())
.repoId(row.id)
.channel(row.channel)
.timestamp(MiscUtil.asXMLGregorianCalendar(row.timestamp))
.eventIdentifier(row.eventIdentifier)
.eventStage(row.eventStage)
.eventType(row.eventType)
.hostIdentifier(row.hostIdentifier)
.message(row.message)
.nodeIdentifier(row.nodeIdentifier)
.outcome(row.outcome)
.parameter(row.parameter)
.remoteHostAddress(row.remoteHostAddress)
.requestIdentifier(row.requestIdentifier)
.result(row.result)
.eventStage(row.eventStage)
.sessionIdentifier(row.sessionIdentifier)
.requestIdentifier(row.requestIdentifier)
.taskIdentifier(row.taskIdentifier)
.taskOID(row.taskOid != null ? row.taskOid.toString() : null)
.timestamp(MiscUtil.asXMLGregorianCalendar(row.timestamp))
.hostIdentifier(row.hostIdentifier)
.nodeIdentifier(row.nodeIdentifier)
.remoteHostAddress(row.remoteHostAddress)
.initiatorRef(objectReference(row.initiatorOid, row.initiatorType, row.initiatorName))
.attorneyRef(objectReference(row.attorneyOid, MObjectType.FOCUS, row.attorneyName))
.targetRef(objectReference(row.targetOid, row.targetType, row.targetName))
.targetOwnerRef(objectReference(row.targetOwnerOid, row.targetOwnerType, row.targetOwnerName));
.targetOwnerRef(objectReference(row.targetOwnerOid, row.targetOwnerType, row.targetOwnerName))
.channel(row.channel)
.outcome(row.outcome)
.parameter(row.parameter)
.result(row.result)
.message(row.message);

// TODO
// mapDeltas(record, row.deltas);
// mapChangedItems(record, row.changedItemPaths);
mapChangedItems(record, row.changedItemPaths);
// mapRefValues(record, row.refValues);
// mapProperties(record, row.properties);
// mapResourceOids(record, row.resourceOids);
Expand All @@ -178,8 +180,9 @@ private void mapDeltas(AuditEventRecordType record, List<MAuditDelta> deltas) {
record.delta(QAuditDeltaMapping.get().toSchemaObject(delta));
}
}
*/

private void mapChangedItems(AuditEventRecordType record, List<String> changedItemPaths) {
private void mapChangedItems(AuditEventRecordType record, String[] changedItemPaths) {
if (changedItemPaths == null) {
return;
}
Expand All @@ -190,6 +193,7 @@ private void mapChangedItems(AuditEventRecordType record, List<String> changedIt
}
}

/*
private void mapRefValues(
AuditEventRecordType record, Map<String, List<MAuditRefValue>> refValues) {
if (refValues == null) {
Expand Down Expand Up @@ -242,21 +246,23 @@ 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();
bean.timestamp = MiscUtil.asInstant(record.getTimestamp());
// Timestamp should be set, but this is last resort, as partitioning key it MUST be set.
bean.timestamp = MiscUtil.asInstant(
Objects.requireNonNullElse(record.getTimestamp(), System.currentTimeMillis()));
bean.channel = record.getChannel();
bean.eventStage = AuditEventStage.toSchemaValue(record.getEventStage());
bean.eventType = AuditEventType.toSchemaValue(record.getEventType());
bean.hostIdentifier = record.getHostIdentifier();

PrismReferenceValue attorney = record.getAttorneyRef();
if (attorney != null) {
bean.attorneyOid = oidToUUid(attorney.getOid());
bean.attorneyOid = SqaleUtils.oidToUUid(attorney.getOid());
bean.attorneyName = attorney.getDescription();
}

PrismReferenceValue initiator = record.getInitiatorRef();
if (initiator != null) {
bean.initiatorOid = oidToUUid(initiator.getOid());
bean.initiatorOid = SqaleUtils.oidToUUid(initiator.getOid());
bean.initiatorType = Objects.requireNonNullElse(
MObjectType.fromTypeQName(initiator.getTargetType()),
MObjectType.FOCUS);
Expand All @@ -274,18 +280,18 @@ public MAuditEventRecord toRowObject(AuditEventRecord record) {

PrismReferenceValue target = record.getTargetRef();
if (target != null) {
bean.targetOid = oidToUUid(target.getOid());
bean.targetOid = SqaleUtils.oidToUUid(target.getOid());
bean.targetType = MObjectType.fromTypeQName(target.getTargetType());
bean.targetName = target.getDescription();
}
PrismReferenceValue targetOwner = record.getTargetOwnerRef();
if (targetOwner != null) {
bean.targetOwnerOid = oidToUUid(targetOwner.getOid());
bean.targetOwnerOid = SqaleUtils.oidToUUid(targetOwner.getOid());
bean.targetOwnerType = MObjectType.fromTypeQName(targetOwner.getTargetType());
bean.targetOwnerName = targetOwner.getDescription();
}
bean.taskIdentifier = record.getTaskIdentifier();
bean.taskOid = oidToUUid(record.getTaskOid());
bean.taskOid = SqaleUtils.oidToUUid(record.getTaskOid());
return bean;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ public Predicate process(PropertyValueFilter<T> filter) throws RepositoryExcepti
}

ValueFilterValues<T, E> values = ValueFilterValues.from(filter, conversionFunction);
if (values.isEmpty()) {
return Expressions.booleanTemplate("({0} = '{}' OR {0} is null)", path);
}

// valueArray can't be just Object[], it must be concrete type, e.g. String[],
// otherwise PG JDBC driver will complain.
//noinspection unchecked
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,23 @@ protected ItemSqlMapper<Q, R> multiUriMapper(
ctx.repositoryContext()::processCacheableUri));
}

/**
* Returns the mapper creating general array-stored multi-value filter/delta processors.
*
* @param <VT> real-value type from schema
* @param <ST> stored type (e.g. String for TEXT[])
*/
protected <VT, ST> ItemSqlMapper<Q, R> multiValueMapper(
Function<Q, ArrayPath<ST[], ST>> rootToQueryItem,
Class<ST> storeType,
Function<VT, ST> conversionFunction) {
return new SqaleItemSqlMapper<>(
ctx -> new ArrayPathItemFilterProcessor<>(
ctx, rootToQueryItem, "TEXT", storeType, conversionFunction),
ctx -> new ArrayItemDeltaProcessor<>(
ctx, rootToQueryItem, storeType, conversionFunction));
}

@Override
public S toSchemaObject(R row) throws SchemaException {
throw new UnsupportedOperationException(
Expand Down Expand Up @@ -361,14 +378,6 @@ public QName resolveUriIdToQName(Integer uriId) {
return repositoryContext().resolveUriIdToQName(uriId);
}

protected @Nullable UUID oidToUUid(@Nullable String oid) {
try {
return oid != null ? UUID.fromString(oid) : null;
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Cannot convert oid '" + oid + "' to UUID", e);
}
}

protected MObjectType schemaTypeToObjectType(QName schemaType) {
return schemaType == null ? null :
MObjectType.fromSchemaType(repositoryContext().qNameToSchemaClass(schemaType));
Expand All @@ -389,7 +398,7 @@ protected void setReference(Referencable ref,
if (ref.getType() == null) {
ref = SqaleUtils.referenceWithTypeFixed(ref);
}
targetOidConsumer.accept(oidToUUid(ref.getOid()));
targetOidConsumer.accept(SqaleUtils.oidToUUid(ref.getOid()));
targetTypeConsumer.accept(schemaTypeToObjectType(ref.getType()));
relationIdConsumer.accept(processCacheableRelation(ref.getRelation()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public S toSchemaObject(Tuple row, Q entityPath,
public R toRowObjectWithoutFullObject(S schemaObject, JdbcSession jdbcSession) {
R row = newRowObject();

row.oid = oidToUUid(schemaObject.getOid());
row.oid = SqaleUtils.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 this method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@ public void test350SearchWithWrongQuery() {
and("operation result is fatal error");
OperationResult subresult = operationResult.getLastSubresult();
assertThat(subresult).isNotNull();
assertThat(subresult.getOperation()).isEqualTo("SqlAuditServiceImpl.searchObjects");
assertThat(subresult.getOperation()).isEqualTo("SqaleAuditService.searchObjects");
assertThat(subresult.getStatus()).isEqualTo(OperationResultStatus.FATAL_ERROR);
}

Expand Down Expand Up @@ -1328,7 +1328,7 @@ public void test900CountWithAllFilter() throws SchemaException {
and("operation result is success");
OperationResult subresult = operationResult.getLastSubresult();
assertThat(subresult).isNotNull();
assertThat(subresult.getOperation()).isEqualTo("SqlAuditServiceImpl.countObjects");
assertThat(subresult.getOperation()).isEqualTo("SqaleAuditService.countObjects");
assertThat(subresult.getStatus()).isEqualTo(OperationResultStatus.SUCCESS);
}

Expand Down Expand Up @@ -1409,7 +1409,7 @@ public void test960CountWithWrongQuery() {
and("operation result is fatal error");
OperationResult subresult = operationResult.getLastSubresult();
assertThat(subresult).isNotNull();
assertThat(subresult.getOperation()).isEqualTo("SqlAuditServiceImpl.countObjects");
assertThat(subresult.getOperation()).isEqualTo("SqaleAuditService.countObjects");
assertThat(subresult.getStatus()).isEqualTo(OperationResultStatus.FATAL_ERROR);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,4 @@ public enum SupportedDatabase {
SQLSERVER,
MYSQL,
MARIADB;

public boolean supportsLimitOffset() {
return this == H2 || this == POSTGRESQL || this == MYSQL || this == MARIADB;
}
}

0 comments on commit a8f0c0a

Please sign in to comment.