Skip to content

Commit

Permalink
MID-8842 ninja - AuditService#getRepositoryDiag method added, code re…
Browse files Browse the repository at this point in the history
…used from existing repository service
  • Loading branch information
1azyman committed Aug 3, 2023
1 parent 63670fb commit 97fa361
Show file tree
Hide file tree
Showing 12 changed files with 370 additions and 261 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@

import java.util.Collection;

import com.evolveum.midpoint.schema.*;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SearchResultList;
import com.evolveum.midpoint.schema.SearchResultMetadata;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.annotation.Experimental;
Expand Down Expand Up @@ -125,4 +123,6 @@ SearchResultMetadata searchObjectsIterative(
@NotNull AuditResultHandler handler,
@Nullable Collection<SelectorOptions<GetOperationOptions>> options,
@NotNull OperationResult parentResult) throws SchemaException;

@NotNull RepositoryDiag getRepositoryDiag();
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,11 @@ public SearchResultMetadata searchObjectsIterative(
@NotNull OperationResult parentResult) throws SchemaException {
throw new UnsupportedOperationException("searchObjectsIterative not supported");
}

@Override
public @NotNull RepositoryDiag getRepositoryDiag() {
RepositoryDiag diag = new RepositoryDiag();
diag.setImplementationShortName(getClass().getSimpleName());
return diag;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,15 @@
import static com.evolveum.midpoint.schema.GetOperationOptions.isAllowNotFound;

import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.*;
import java.util.function.Consumer;

import java.util.stream.Collectors;

import com.google.common.base.Strings;
import com.google.common.collect.ObjectArrays;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.*;
import com.querydsl.core.types.dsl.*;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.sql.SQLQuery;
import org.apache.commons.lang3.Validate;
import org.jetbrains.annotations.NotNull;
Expand All @@ -47,8 +42,6 @@
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.repo.api.*;
import com.evolveum.midpoint.repo.sqale.mapping.SqaleTableMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.common.MGlobalMetadata;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QGlobalMetadata;
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;
Expand All @@ -73,7 +66,10 @@
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.schema.util.ObjectQueryUtil;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;

Expand All @@ -96,13 +92,6 @@
*/
public class SqaleRepositoryService extends SqaleServiceBase implements RepositoryService {

/**
* Name of the repository implementation, returned by {@link #getRepositoryType()}.
* While public, the value is often copied because this service class is implementation
* detail for the rest of the midPoint.
*/
public static final String REPOSITORY_IMPL_NAME = "Native";

public static final int INITIAL_VERSION_NUMBER = 0;
public static final String INITIAL_VERSION_STRING = String.valueOf(INITIAL_VERSION_NUMBER);

Expand Down Expand Up @@ -1672,110 +1661,11 @@ private void executeReturnUnusedValuesToSequence(UUID oid, Collection<Long> unus
}
}

@Override
public RepositoryDiag getRepositoryDiag() {
logger.debug("Getting repository diagnostics.");

RepositoryDiag diag = new RepositoryDiag();
diag.setImplementationShortName(REPOSITORY_IMPL_NAME);
diag.setImplementationDescription(
"Implementation that stores data in PostgreSQL database using JDBC with Querydsl.");

JdbcRepositoryConfiguration config = repositoryConfiguration();
diag.setDriverShortName(config.getDriverClassName());
diag.setRepositoryUrl(config.getJdbcUrl());
diag.setEmbedded(config.isEmbedded());

Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
if (!driver.getClass().getName().equals(config.getDriverClassName())) {
continue;
}

diag.setDriverVersion(driver.getMajorVersion() + "." + driver.getMinorVersion());
}

List<LabeledString> details = new ArrayList<>();
diag.setAdditionalDetails(details);
details.add(new LabeledString("dataSource", config.getDataSource()));

try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) {
details.add(new LabeledString("transactionIsolation",
getTransactionIsolation(jdbcSession.connection(), config)));

try {
Properties info = jdbcSession.connection().getClientInfo();
if (info != null) {
for (String name : info.stringPropertyNames()) {
details.add(new LabeledString("clientInfo." + name, info.getProperty(name)));
}
}
} catch (SQLException e) {
details.add(new LabeledString("clientInfo-error", e.toString()));
}

long startMs = System.currentTimeMillis();
jdbcSession.executeStatement("select 1");
details.add(new LabeledString("select-1-round-trip-ms",
String.valueOf(System.currentTimeMillis() - startMs)));

addGlobalMetadataInfo(jdbcSession, details);
}

details.sort((o1, o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.getLabel(), o2.getLabel()));

return diag;
}

private void addGlobalMetadataInfo(JdbcSession jdbcSession, List<LabeledString> details) {
List<MGlobalMetadata> list = jdbcSession.newQuery()
.from(QGlobalMetadata.DEFAULT)
.select(QGlobalMetadata.DEFAULT)
.fetch();

for (MGlobalMetadata metadata : list) {
details.add(new LabeledString(metadata.name, metadata.value));
}
}

@Override
public @NotNull String getRepositoryType() {
return REPOSITORY_IMPL_NAME;
}

private String getTransactionIsolation(
Connection connection, JdbcRepositoryConfiguration config) {
String value = config.getTransactionIsolation() != null ?
config.getTransactionIsolation().name() + "(read from repo configuration)" : null;

try {
switch (connection.getTransactionIsolation()) {
case Connection.TRANSACTION_NONE:
value = "TRANSACTION_NONE (read from connection)";
break;
case Connection.TRANSACTION_READ_COMMITTED:
value = "TRANSACTION_READ_COMMITTED (read from connection)";
break;
case Connection.TRANSACTION_READ_UNCOMMITTED:
value = "TRANSACTION_READ_UNCOMMITTED (read from connection)";
break;
case Connection.TRANSACTION_REPEATABLE_READ:
value = "TRANSACTION_REPEATABLE_READ (read from connection)";
break;
case Connection.TRANSACTION_SERIALIZABLE:
value = "TRANSACTION_SERIALIZABLE (read from connection)";
break;
default:
value = "Unknown value in connection.";
}
} catch (Exception ex) {
//nowhere to report error (no operation result available)
}

return value;
}

@Override
public void repositorySelfTest(OperationResult parentResult) {
OperationResult operationResult =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@
*/
package com.evolveum.midpoint.repo.sqale;

import jakarta.annotation.PreDestroy;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;

import jakarta.annotation.PreDestroy;
import org.jetbrains.annotations.NotNull;
import org.postgresql.util.PSQLException;

Expand All @@ -17,8 +25,13 @@
import com.evolveum.midpoint.prism.query.ObjectPaging;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.repo.api.SqlPerformanceMonitorsCollection;
import com.evolveum.midpoint.repo.sqale.qmodel.common.MGlobalMetadata;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QGlobalMetadata;
import com.evolveum.midpoint.repo.sqlbase.JdbcRepositoryConfiguration;
import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.repo.sqlbase.perfmon.SqlPerformanceMonitorImpl;
import com.evolveum.midpoint.schema.LabeledString;
import com.evolveum.midpoint.schema.RepositoryDiag;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.ExceptionUtil;
import com.evolveum.midpoint.util.exception.SystemException;
Expand All @@ -29,6 +42,13 @@ public class SqaleServiceBase {

protected final Trace logger = TraceManager.getTrace(getClass());

/**
* Name of the repository implementation.
* While public, the value is often copied because this service class is implementation
* detail for the rest of the midPoint.
*/
public static final String REPOSITORY_IMPL_NAME = "Native";

/**
* Class name prefix for operation names, including the dot separator.
* Use with various `RepositoryService.OP_*` constants, not with constants without `OP_`
Expand Down Expand Up @@ -148,4 +168,102 @@ public void destroy() {
}
}
// endregion

@NotNull public RepositoryDiag getRepositoryDiag() {
logger.debug("Getting repository diagnostics.");

RepositoryDiag diag = new RepositoryDiag();
diag.setImplementationShortName(REPOSITORY_IMPL_NAME);
diag.setImplementationDescription(
"Implementation that stores data in PostgreSQL database using JDBC with Querydsl.");

JdbcRepositoryConfiguration config = repositoryConfiguration();
diag.setDriverShortName(config.getDriverClassName());
diag.setRepositoryUrl(config.getJdbcUrl());
diag.setEmbedded(config.isEmbedded());

Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
if (!driver.getClass().getName().equals(config.getDriverClassName())) {
continue;
}

diag.setDriverVersion(driver.getMajorVersion() + "." + driver.getMinorVersion());
}

List<LabeledString> details = new ArrayList<>();
diag.setAdditionalDetails(details);
details.add(new LabeledString("dataSource", config.getDataSource()));

try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) {
details.add(new LabeledString("transactionIsolation",
getTransactionIsolation(jdbcSession.connection(), config)));

try {
Properties info = jdbcSession.connection().getClientInfo();
if (info != null) {
for (String name : info.stringPropertyNames()) {
details.add(new LabeledString("clientInfo." + name, info.getProperty(name)));
}
}
} catch (SQLException e) {
details.add(new LabeledString("clientInfo-error", e.toString()));
}

long startMs = System.currentTimeMillis();
jdbcSession.executeStatement("select 1");
details.add(new LabeledString("select-1-round-trip-ms",
String.valueOf(System.currentTimeMillis() - startMs)));

addGlobalMetadataInfo(jdbcSession, details);
}

details.sort((o1, o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.getLabel(), o2.getLabel()));

return diag;
}

private void addGlobalMetadataInfo(JdbcSession jdbcSession, List<LabeledString> details) {
List<MGlobalMetadata> list = jdbcSession.newQuery()
.from(QGlobalMetadata.DEFAULT)
.select(QGlobalMetadata.DEFAULT)
.fetch();

for (MGlobalMetadata metadata : list) {
details.add(new LabeledString(metadata.name, metadata.value));
}
}

private String getTransactionIsolation(
Connection connection, JdbcRepositoryConfiguration config) {
String value = config.getTransactionIsolation() != null ?
config.getTransactionIsolation().name() + "(read from repo configuration)" : null;

try {
switch (connection.getTransactionIsolation()) {
case Connection.TRANSACTION_NONE:
value = "TRANSACTION_NONE (read from connection)";
break;
case Connection.TRANSACTION_READ_COMMITTED:
value = "TRANSACTION_READ_COMMITTED (read from connection)";
break;
case Connection.TRANSACTION_READ_UNCOMMITTED:
value = "TRANSACTION_READ_UNCOMMITTED (read from connection)";
break;
case Connection.TRANSACTION_REPEATABLE_READ:
value = "TRANSACTION_REPEATABLE_READ (read from connection)";
break;
case Connection.TRANSACTION_SERIALIZABLE:
value = "TRANSACTION_SERIALIZABLE (read from connection)";
break;
default:
value = "Unknown value in connection.";
}
} catch (Exception ex) {
//nowhere to report error (no operation result available)
}

return value;
}
}

0 comments on commit 97fa361

Please sign in to comment.