You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2019/11/29 14:57:35 UTC
[syncope] 02/02: [SYNCOPE-1511] Enhancements for PostgreSQL JSONB
and MySQL JSON
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
commit c1502d5db7c8d3d4bca05380627108986738dc32
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Fri Nov 29 14:47:15 2019 +0100
[SYNCOPE-1511] Enhancements for PostgreSQL JSONB and MySQL JSON
---
archetype/pom.xml | 5 +-
.../apache/syncope/common/lib/to/AuditEntryTO.java | 15 +-
.../syncope/common/lib/types/AuditLoggerName.java | 2 +-
.../syncope/common/rest/api/beans/AuditQuery.java | 155 ++++++++++------
.../syncope/common/rest/api/beans/TaskQuery.java | 2 -
.../common/rest/api/service/AuditService.java | 4 +-
.../org/apache/syncope/core/logic/AuditLogic.java | 14 +-
.../syncope/core/logic/init/LoggerLoader.java | 27 ++-
.../core/rest/cxf/service/AuditServiceImpl.java | 7 +-
.../syncope/core/persistence/api/dao/AuditDAO.java | 20 ++-
.../core/persistence/api/entity/AuditEntry.java | 5 +-
.../jpa/dao/AbstractJPAJSONAuditDAO.java | 125 +++++++++++++
.../persistence/jpa/dao/MyJPAJSONAuditDAO.java | 53 ++++++
.../persistence/jpa/dao/PGJPAJSONAuditDAO.java | 59 +++++++
.../src/main/resources/audit/audit_myjson.sql} | 6 +-
.../src/main/resources/audit/audit_pgjsonb.sql} | 5 +-
.../resources/myjson/domains/Master.properties | 2 +-
.../main/resources/myjson/persistence.properties | 1 +
.../resources/pgjsonb/domains/Master.properties | 2 +-
.../main/resources/pgjsonb/persistence.properties | 1 +
.../core/persistence/jpa/PersistenceContext.java | 46 +++--
.../core/persistence/jpa/dao/JPAAuditDAO.java | 194 +++++++++++----------
.../src/main/resources/audit/audit.sql | 2 -
.../src/main/resources/audit/audit_sqlserver.sql | 9 +-
.../src/main/resources/persistence.properties | 1 +
.../core/provisioning/api/AuditEntryImpl.java | 12 --
.../provisioning/api/data/AuditDataBinder.java | 2 +-
.../java/data/AuditDataBinderImpl.java | 28 +--
.../java/job/report/AuditReportlet.java | 4 +-
.../src/main/resources/persistence.properties.all | 1 +
.../main/resources/persistence.properties.myjson | 1 +
.../main/resources/persistence.properties.pgjsonb | 1 +
.../src/main/resources/persistence.properties | 1 +
fit/core-reference/pom.xml | 7 +-
.../resources/elasticsearch/persistence.properties | 1 +
.../resources/myjson/domains/Master.properties | 2 +-
.../src/main/resources/oracle/Dockerfile | 4 +-
.../resources/pgjsonb/domains/Master.properties | 2 +-
.../org/apache/syncope/fit/core/AuditITCase.java | 15 +-
.../systemadministration/dbms.adoc | 25 ++-
40 files changed, 600 insertions(+), 268 deletions(-)
diff --git a/archetype/pom.xml b/archetype/pom.xml
index d8564e1..54a749a 100644
--- a/archetype/pom.xml
+++ b/archetype/pom.xml
@@ -42,7 +42,7 @@ under the License.
<extension>
<groupId>org.apache.maven.archetype</groupId>
<artifactId>archetype-packaging</artifactId>
- <version>3.1.1</version>
+ <version>3.1.2</version>
</extension>
</extensions>
@@ -51,7 +51,7 @@ under the License.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-archetype-plugin</artifactId>
- <version>3.1.1</version>
+ <version>3.1.2</version>
<extensions>true</extensions>
</plugin>
</plugins>
@@ -151,6 +151,7 @@ under the License.
<directory>../core/persistence-jpa-json/src/main/resources/</directory>
<includes>
<include>META-INF/*</include>
+ <include>audit/*</include>
</includes>
<targetPath>${project.build.outputDirectory}/archetype-resources/core/src/main/resources</targetPath>
</resource>
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AuditEntryTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AuditEntryTO.java
index fbaf0ca..9d183e6 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AuditEntryTO.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AuditEntryTO.java
@@ -18,21 +18,18 @@
*/
package org.apache.syncope.common.lib.to;
-import org.apache.syncope.common.lib.BaseBean;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.BaseBean;
@XmlRootElement(name = "audit")
@XmlType
-public class AuditEntryTO extends BaseBean implements EntityTO {
- private static final long serialVersionUID = 1215115961911228005L;
+public class AuditEntryTO extends BaseBean implements EntityTO {
- private final List<String> inputs = new ArrayList<>();
+ private static final long serialVersionUID = 1215115961911228005L;
private String who;
@@ -44,6 +41,8 @@ public class AuditEntryTO extends BaseBean implements EntityTO {
private String before;
+ private final List<String> inputs = new ArrayList<>();
+
private String output;
private Date date;
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
index 7b36554..53a7675 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
@@ -45,7 +45,7 @@ public class AuditLoggerName implements Serializable {
return domain + '.' + loggerName;
}
- private final AuditElements.EventCategoryType type;
+ private final EventCategoryType type;
private final String category;
diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java
index d5dcd1a..5992024 100644
--- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java
+++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java
@@ -18,68 +18,49 @@
*/
package org.apache.syncope.common.rest.api.beans;
-import org.apache.syncope.common.lib.types.AuditElements;
-
-import javax.ws.rs.QueryParam;
-
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Schema;
import java.util.ArrayList;
import java.util.List;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.QueryParam;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
public class AuditQuery extends AbstractQuery {
private static final long serialVersionUID = -2863334226169614417L;
- private String key;
-
- private final List<AuditElements.Result> results = new ArrayList<>();
-
- private final List<String> events = new ArrayList<>();
-
- public String getKey() {
- return key;
- }
-
- @QueryParam("key")
- public void setKey(final String key) {
- this.key = key;
- }
-
- public List<AuditElements.Result> getResults() {
- return results;
- }
+ public static class Builder extends AbstractQuery.Builder<AuditQuery, Builder> {
- @QueryParam("results")
- public void setResults(final List<AuditElements.Result> results) {
- if (results != null) {
- this.results.addAll(results);
+ public Builder(final String entityKey) {
+ super();
+ getInstance().setEntityKey(entityKey);
}
- }
- public List<String> getEvents() {
- return events;
- }
-
- @QueryParam("events")
- public void setEvents(final List<String> events) {
- if (events != null) {
- this.events.addAll(events);
+ @Override
+ protected AuditQuery newInstance() {
+ return new AuditQuery();
}
- }
- public static class Builder extends AbstractQuery.Builder<AuditQuery, Builder> {
+ public Builder type(final AuditElements.EventCategoryType type) {
+ getInstance().setType(type);
+ return this;
+ }
- public Builder key(final String keyword) {
- getInstance().setKey(keyword);
+ public Builder category(final String category) {
+ getInstance().setCategory(category);
return this;
}
- public Builder results(final List<AuditElements.Result> results) {
- getInstance().setResults(results);
+ public Builder subcategory(final String subcategory) {
+ getInstance().setSubcategory(subcategory);
return this;
}
- public Builder result(final AuditElements.Result result) {
- getInstance().getResults().add(result);
+ public Builder event(final String event) {
+ getInstance().getEvents().add(event);
return this;
}
@@ -88,15 +69,91 @@ public class AuditQuery extends AbstractQuery {
return this;
}
- public Builder event(final String event) {
- getInstance().getEvents().add(event);
+ public Builder result(final AuditElements.Result result) {
+ getInstance().setResult(result);
return this;
}
+ }
- @Override
- protected AuditQuery newInstance() {
- return new AuditQuery();
- }
+ private String entityKey;
+
+ private AuditElements.EventCategoryType type;
+
+ private String category;
+
+ private String subcategory;
+
+ private final List<String> events = new ArrayList<>();
+
+ private AuditElements.Result result;
+
+ @Parameter(name = JAXRSService.PARAM_ENTITY_KEY, description = "audit entity key to match", schema =
+ @Schema(implementation = String.class, example = "50592942-73ec-44c4-a377-e859524245e4"))
+ public String getEntityKey() {
+ return entityKey;
+ }
+
+ @NotNull
+ @QueryParam(JAXRSService.PARAM_ENTITY_KEY)
+ public void setEntityKey(final String entityKey) {
+ this.entityKey = entityKey;
+ }
+
+ @Parameter(name = "type", description = "audit type to match", schema =
+ @Schema(implementation = AuditElements.EventCategoryType.class))
+ public AuditElements.EventCategoryType getType() {
+ return type;
}
+ @QueryParam("type")
+ public void setType(final AuditElements.EventCategoryType type) {
+ this.type = type;
+ }
+
+ @Parameter(name = "category", description = "audit category to match", schema =
+ @Schema(implementation = String.class))
+ public String getCategory() {
+ return category;
+ }
+
+ @QueryParam("category")
+ public void setCategory(final String category) {
+ this.category = category;
+ }
+
+ @Parameter(name = "subcategory", description = "audit subcategory to match", schema =
+ @Schema(implementation = String.class))
+ public String getSubcategory() {
+ return subcategory;
+ }
+
+ @QueryParam("subcategory")
+ public void setSubcategory(final String subcategory) {
+ this.subcategory = subcategory;
+ }
+
+ @Parameter(name = "result", description = "audit result to match", schema =
+ @Schema(implementation = AuditElements.Result.class))
+ public AuditElements.Result getResult() {
+ return result;
+ }
+
+ @QueryParam("result")
+ public void setResult(final AuditElements.Result result) {
+ this.result = result;
+ }
+
+ @Parameter(name = "events", description = "audit events(s) to match", array =
+ @ArraySchema(uniqueItems = true, schema =
+ @Schema(implementation = String.class)))
+ public List<String> getEvents() {
+ return events;
+ }
+
+ @QueryParam("events")
+ public void setEvents(final List<String> events) {
+ if (events != null) {
+ this.events.addAll(events);
+ }
+ }
}
diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/TaskQuery.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/TaskQuery.java
index 22e9e97..6a5ac61 100644
--- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/TaskQuery.java
+++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/TaskQuery.java
@@ -133,8 +133,6 @@ public class TaskQuery extends AbstractQuery {
return entityKey;
}
- @Parameter(name = JAXRSService.PARAM_RESOURCE, description = " key", schema =
- @Schema(implementation = String.class, example = "resource-ldap"))
@QueryParam(JAXRSService.PARAM_ENTITY_KEY)
public void setEntityKey(final String entityKey) {
this.entityKey = entityKey;
diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AuditService.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AuditService.java
index 897131e..5035494 100644
--- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AuditService.java
+++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AuditService.java
@@ -38,7 +38,7 @@ import javax.ws.rs.core.MediaType;
@Tag(name = "Audits")
@SecurityRequirements({
@SecurityRequirement(name = "BasicAuthentication"),
- @SecurityRequirement(name = "Bearer")})
+ @SecurityRequirement(name = "Bearer") })
@Path("audits")
public interface AuditService {
@@ -49,6 +49,6 @@ public interface AuditService {
* @return paged list of objects matching the given query
*/
@GET
- @Produces({MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML})
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
PagedResult<AuditEntryTO> search(@BeanParam AuditQuery auditQuery);
}
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java
index f730de2..f57eda9 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java
@@ -46,17 +46,21 @@ public class AuditLogic extends AbstractTransactionalLogic<AuditEntryTO> {
@PreAuthorize("hasRole('" + IdRepoEntitlement.AUDIT_SEARCH + "')")
@Transactional(readOnly = true)
public Pair<Integer, List<AuditEntryTO>> search(
- final String key,
+ final String entityKey,
final int page,
final int size,
- final List<AuditElements.Result> results,
+ final AuditElements.EventCategoryType type,
+ final String category,
+ final String subcategory,
final List<String> events,
+ final AuditElements.Result result,
final List<OrderByClause> orderByClauses) {
- Integer count = auditDAO.count(key);
- List<AuditEntry> matching = auditDAO.findByEntityKey(key, page, size, results, events, orderByClauses);
+ Integer count = auditDAO.count(entityKey);
+ List<AuditEntry> matching = auditDAO.findByEntityKey(
+ entityKey, page, size, type, category, subcategory, events, result, orderByClauses);
List<AuditEntryTO> searchResults = matching.stream().
- map(binder::getAuditTO).
+ map(auditEntry -> binder.getAuditTO(entityKey, auditEntry)).
collect(Collectors.toList());
return Pair.of(count, searchResults);
}
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
index 17e357c..282d726 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.logic.init;
import java.sql.Connection;
import java.sql.SQLException;
+import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -31,7 +32,6 @@ import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.db.ColumnMapping;
import org.apache.logging.log4j.core.appender.db.jdbc.AbstractConnectionSource;
-import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
import org.apache.logging.log4j.core.appender.rewrite.RewriteAppender;
import org.apache.logging.log4j.core.config.LoggerConfig;
@@ -65,21 +65,19 @@ public class LoggerLoader implements SyncopeCoreLoader {
return 300;
}
- private static ColumnConfig[] buildColumnConfigs(final LoggerContext ctx) {
- ColumnConfig[] columnConfigs = {
- ColumnConfig.newBuilder().
- setConfiguration(ctx.getConfiguration()).setName("EVENT_DATE").setEventTimestamp(true).build(),
- ColumnConfig.newBuilder().setUnicode(false).
+ private static ColumnMapping[] buildColumnMappings(final LoggerContext ctx) {
+ return new ColumnMapping[] {
+ ColumnMapping.newBuilder().
+ setConfiguration(ctx.getConfiguration()).setName("EVENT_DATE").setType(Timestamp.class).build(),
+ ColumnMapping.newBuilder().
setConfiguration(ctx.getConfiguration()).setName("LOGGER_LEVEL").setPattern("%level").build(),
- ColumnConfig.newBuilder().setUnicode(false).
+ ColumnMapping.newBuilder().
setConfiguration(ctx.getConfiguration()).setName("LOGGER").setPattern("%logger").build(),
- ColumnConfig.newBuilder().setUnicode(false).
- setConfiguration(ctx.getConfiguration()).setName("MESSAGE").setPattern("%message").build(),
- ColumnConfig.newBuilder().setUnicode(false).
+ ColumnMapping.newBuilder().
+ setConfiguration(ctx.getConfiguration()).setName(AuditDAO.MESSAGE_COLUMN).setPattern("%message").build(),
+ ColumnMapping.newBuilder().
setConfiguration(ctx.getConfiguration()).setName("THROWABLE").setPattern("%ex{full}").build()
};
-
- return columnConfigs;
}
@Override
@@ -98,9 +96,8 @@ public class LoggerLoader implements SyncopeCoreLoader {
setIgnoreExceptions(false).
setConnectionSource(new DataSourceConnectionSource(domain, datasource)).
setBufferSize(0).
- setTableName(AuditDAO.TABLE_NAME).
- setColumnConfigs(buildColumnConfigs(ctx)).
- setColumnMappings(new ColumnMapping[0]).
+ setTableName(AuditDAO.TABLE).
+ setColumnMappings(buildColumnMappings(ctx)).
build();
appender.start();
ctx.getConfiguration().addAppender(appender);
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java
index 67126f7..b646f91 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java
@@ -38,11 +38,14 @@ public class AuditServiceImpl extends AbstractServiceImpl implements AuditServic
@Override
public PagedResult<AuditEntryTO> search(final AuditQuery auditQuery) {
Pair<Integer, List<AuditEntryTO>> result = logic.search(
- auditQuery.getKey(),
+ auditQuery.getEntityKey(),
auditQuery.getPage(),
auditQuery.getSize(),
- auditQuery.getResults(),
+ auditQuery.getType(),
+ auditQuery.getCategory(),
+ auditQuery.getSubcategory(),
auditQuery.getEvents(),
+ auditQuery.getResult(),
getOrderByClauses(auditQuery.getOrderBy()));
return buildPagedResult(result.getRight(), auditQuery.getPage(), auditQuery.getSize(), result.getLeft());
}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuditDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuditDAO.java
index 3f1994c..5a78787 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuditDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuditDAO.java
@@ -26,12 +26,20 @@ import org.apache.syncope.core.persistence.api.entity.AuditEntry;
public interface AuditDAO {
- String TABLE_NAME = "SYNCOPEAUDIT";
+ String TABLE = "SYNCOPEAUDIT";
- List<AuditEntry> findByEntityKey(String key, int page, int size,
- List<AuditElements.Result> results,
- List<String> events,
- List<OrderByClause> orderByClauses);
+ String MESSAGE_COLUMN = "MESSAGE";
- Integer count(String key);
+ List<AuditEntry> findByEntityKey(
+ String entityKey,
+ int page,
+ int size,
+ AuditElements.EventCategoryType type,
+ String category,
+ String subcategory,
+ List<String> events,
+ AuditElements.Result result,
+ List<OrderByClause> orderByClauses);
+
+ int count(String key);
}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AuditEntry.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AuditEntry.java
index 7bcb134..2b10e43 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AuditEntry.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AuditEntry.java
@@ -18,10 +18,9 @@
*/
package org.apache.syncope.core.persistence.api.entity;
-import org.apache.syncope.common.lib.types.AuditLoggerName;
-
import java.io.Serializable;
import java.util.Date;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
public interface AuditEntry extends Serializable {
@@ -38,6 +37,4 @@ public interface AuditEntry extends Serializable {
String getThrowable();
Date getDate();
-
- String getKey();
}
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAuditDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAuditDAO.java
new file mode 100644
index 0000000..a921db1
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAuditDAO.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.springframework.util.CollectionUtils;
+
+public abstract class AbstractJPAJSONAuditDAO extends JPAAuditDAO {
+
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ protected abstract static class JSONMessageCriteriaBuilder extends MessageCriteriaBuilder {
+
+ protected String entityKey;
+
+ private AuditElements.EventCategoryType type;
+
+ private String category;
+
+ private String subcategory;
+
+ private List<String> events;
+
+ private AuditElements.Result result;
+
+ @Override
+ protected MessageCriteriaBuilder entityKey(final String entityKey) {
+ this.entityKey = entityKey;
+ return this;
+ }
+
+ @Override
+ public MessageCriteriaBuilder type(final AuditElements.EventCategoryType type) {
+ this.type = type;
+ return this;
+ }
+
+ @Override
+ public MessageCriteriaBuilder category(final String category) {
+ this.category = category;
+ return this;
+ }
+
+ @Override
+ public MessageCriteriaBuilder subcategory(final String subcategory) {
+ this.subcategory = subcategory;
+ return this;
+ }
+
+ @Override
+ public MessageCriteriaBuilder events(final List<String> events) {
+ this.events = events;
+ return this;
+ }
+
+ @Override
+ public MessageCriteriaBuilder result(final AuditElements.Result result) {
+ this.result = result;
+ return this;
+ }
+
+ private Optional<ObjectNode> buildContainer() {
+ ObjectNode logger = MAPPER.createObjectNode();
+ if (type != null) {
+ logger.put("type", type.name());
+ }
+ if (StringUtils.isNotBlank(category)) {
+ logger.put("category", category);
+ }
+ if (StringUtils.isNotBlank(subcategory)) {
+ logger.put("subcategory", subcategory);
+ }
+ if (result != null) {
+ logger.put("result", result.name());
+ }
+
+ if (!logger.isEmpty()) {
+ ObjectNode container = MAPPER.createObjectNode();
+ container.set("logger", logger);
+ return Optional.of(container);
+ }
+
+ return Optional.empty();
+ }
+
+ protected abstract String doBuild(List<ObjectNode> containers);
+
+ @Override
+ public String build() {
+ List<ObjectNode> containers = new ArrayList<>();
+ if (CollectionUtils.isEmpty(events)) {
+ buildContainer().ifPresent(containers::add);
+ } else {
+ events.forEach(event -> buildContainer().ifPresent(container -> {
+ ((ObjectNode) container.get("logger")).put("event", event);
+ containers.add(container);
+ }));
+ }
+
+ return doBuild(containers);
+ }
+ }
+}
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAuditDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAuditDAO.java
new file mode 100644
index 0000000..020069b
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAuditDAO.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+
+public class MyJPAJSONAuditDAO extends AbstractJPAJSONAuditDAO {
+
+ private static class MyMessageCriteriaBuilder extends JSONMessageCriteriaBuilder {
+
+ @Override
+ protected String doBuild(final List<ObjectNode> containers) {
+ query.append('(').append(MESSAGE_COLUMN).append(" -> '$.before' LIKE '%").append(entityKey).
+ append("%' OR ").append(MESSAGE_COLUMN).append(" -> '$.input' LIKE '%").append(entityKey).
+ append("%' OR ").append(MESSAGE_COLUMN).append(" -> '$.output' LIKE '%").append(entityKey).
+ append("%')");
+
+ if (!containers.isEmpty()) {
+ query.append(" AND (").
+ append(containers.stream().map(container -> "JSON_CONTAINS(" + MESSAGE_COLUMN + ", '"
+ + POJOHelper.serialize(container).replace("'", "''")
+ + "')").collect(Collectors.joining(" OR "))).
+ append(')');
+ }
+
+ return query.toString();
+ }
+ }
+
+ @Override
+ protected MessageCriteriaBuilder messageCriteriaBuilder(final String entityKey) {
+ return new MyMessageCriteriaBuilder().entityKey(entityKey);
+ }
+}
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAuditDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAuditDAO.java
new file mode 100644
index 0000000..54ea828
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAuditDAO.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.syncope.core.persistence.jpa.dao.AbstractJPAJSONAuditDAO.JSONMessageCriteriaBuilder;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+
+public class PGJPAJSONAuditDAO extends AbstractJPAJSONAuditDAO {
+
+ private static class PGMessageCriteriaBuilder extends JSONMessageCriteriaBuilder {
+
+ @Override
+ protected String doBuild(final List<ObjectNode> containers) {
+ query.append('(').append(MESSAGE_COLUMN).append(" ->> 'before' LIKE '%").append(entityKey).
+ append("%' OR ").append(MESSAGE_COLUMN).append(" ->> 'input' LIKE '%").append(entityKey).
+ append("%' OR ").append(MESSAGE_COLUMN).append(" ->> 'output' LIKE '%").append(entityKey).
+ append("%')");
+
+ if (!containers.isEmpty()) {
+ query.append(" AND (").
+ append(containers.stream().map(container -> MESSAGE_COLUMN + " @> '"
+ + POJOHelper.serialize(container).replace("'", "''")
+ + "'::jsonb").collect(Collectors.joining(" OR "))).
+ append(')');
+ }
+
+ return query.toString();
+ }
+ }
+
+ @Override
+ protected String select() {
+ return MESSAGE_COLUMN + "::text";
+ }
+
+ @Override
+ protected MessageCriteriaBuilder messageCriteriaBuilder(final String entityKey) {
+ return new PGMessageCriteriaBuilder().entityKey(entityKey);
+ }
+}
diff --git a/core/persistence-jpa/src/main/resources/audit/audit.sql b/core/persistence-jpa-json/src/main/resources/audit/audit_myjson.sql
similarity index 95%
copy from core/persistence-jpa/src/main/resources/audit/audit.sql
copy to core/persistence-jpa-json/src/main/resources/audit/audit_myjson.sql
index 44ffb17..af5d37b 100644
--- a/core/persistence-jpa/src/main/resources/audit/audit.sql
+++ b/core/persistence-jpa-json/src/main/resources/audit/audit_myjson.sql
@@ -19,8 +19,6 @@ CREATE TABLE IF NOT EXISTS SYNCOPEAUDIT (
EVENT_DATE TIMESTAMP,
LOGGER_LEVEL VARCHAR(255) NOT NULL,
LOGGER VARCHAR(255) NOT NULL,
- MESSAGE TEXT NOT NULL,
+ MESSAGE JSON NOT NULL,
THROWABLE TEXT
-);
-
-COMMIT;
+) ENGINE=InnoDB;
diff --git a/core/persistence-jpa/src/main/resources/audit/audit.sql b/core/persistence-jpa-json/src/main/resources/audit/audit_pgjsonb.sql
similarity index 89%
copy from core/persistence-jpa/src/main/resources/audit/audit.sql
copy to core/persistence-jpa-json/src/main/resources/audit/audit_pgjsonb.sql
index 44ffb17..0edbdf8 100644
--- a/core/persistence-jpa/src/main/resources/audit/audit.sql
+++ b/core/persistence-jpa-json/src/main/resources/audit/audit_pgjsonb.sql
@@ -19,8 +19,7 @@ CREATE TABLE IF NOT EXISTS SYNCOPEAUDIT (
EVENT_DATE TIMESTAMP,
LOGGER_LEVEL VARCHAR(255) NOT NULL,
LOGGER VARCHAR(255) NOT NULL,
- MESSAGE TEXT NOT NULL,
+ MESSAGE JSONB NOT NULL,
THROWABLE TEXT
);
-
-COMMIT;
+CREATE INDEX SYNCOPEAUDIT_idx ON SYNCOPEAUDIT USING gin ((MESSAGE) jsonb_path_ops)
diff --git a/core/persistence-jpa-json/src/main/resources/myjson/domains/Master.properties b/core/persistence-jpa-json/src/main/resources/myjson/domains/Master.properties
index 2197c87..6dfdf26 100644
--- a/core/persistence-jpa-json/src/main/resources/myjson/domains/Master.properties
+++ b/core/persistence-jpa-json/src/main/resources/myjson/domains/Master.properties
@@ -25,4 +25,4 @@ Master.orm=META-INF/spring-orm-myjson.xml
Master.pool.maxActive=10
Master.pool.minIdle=2
-Master.audit.sql=audit_mysql_innodb.sql
+Master.audit.sql=audit_myjson.sql
diff --git a/core/persistence-jpa-json/src/main/resources/myjson/persistence.properties b/core/persistence-jpa-json/src/main/resources/myjson/persistence.properties
index 438ba5d..a80d72e 100644
--- a/core/persistence-jpa-json/src/main/resources/myjson/persistence.properties
+++ b/core/persistence-jpa-json/src/main/resources/myjson/persistence.properties
@@ -23,4 +23,5 @@ any.search.dao=org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnySearchDAO
user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONUserDAO
group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONGroupDAO
anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONAnyObjectDAO
+audit.dao=org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAuditDAO
openjpa.RemoteCommitProvider=sjvm
diff --git a/core/persistence-jpa-json/src/main/resources/pgjsonb/domains/Master.properties b/core/persistence-jpa-json/src/main/resources/pgjsonb/domains/Master.properties
index d9a648f..4ab67b0 100644
--- a/core/persistence-jpa-json/src/main/resources/pgjsonb/domains/Master.properties
+++ b/core/persistence-jpa-json/src/main/resources/pgjsonb/domains/Master.properties
@@ -25,4 +25,4 @@ Master.orm=META-INF/spring-orm-pgjsonb.xml
Master.pool.maxActive=10
Master.pool.minIdle=2
-Master.audit.sql=audit.sql
+Master.audit.sql=audit_pgjsonb.sql
diff --git a/core/persistence-jpa-json/src/main/resources/pgjsonb/persistence.properties b/core/persistence-jpa-json/src/main/resources/pgjsonb/persistence.properties
index 53172d9..0912595 100644
--- a/core/persistence-jpa-json/src/main/resources/pgjsonb/persistence.properties
+++ b/core/persistence-jpa-json/src/main/resources/pgjsonb/persistence.properties
@@ -23,4 +23,5 @@ any.search.dao=org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnySearchDAO
user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONUserDAO
group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONGroupDAO
anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONAnyObjectDAO
+audit.dao=org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAuditDAO
openjpa.RemoteCommitProvider=sjvm
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
index a26084f..4ce8ec6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
@@ -25,6 +25,7 @@ import javax.persistence.ValidationMode;
import javax.validation.Validator;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AuditDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
@@ -80,13 +81,13 @@ public class PersistenceContext implements EnvironmentAware {
if (OPENJPA_LOG.isDebugEnabled()) {
jpaPropertyMap.put("openjpa.Log", "SQL=TRACE");
jpaPropertyMap.put("openjpa.ConnectionFactoryProperties",
- "PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=120");
+ "PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=120");
}
jpaPropertyMap.put("openjpa.NontransactionalWrite", false);
jpaPropertyMap.put("openjpa.jdbc.MappingDefaults",
- "ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict,"
+ "ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict,"
+ "FieldStrategies='"
+ "java.util.Locale=org.apache.syncope.core.persistence.jpa.openjpa.LocaleValueHandler,"
+ "java.lang.Boolean=org.apache.syncope.core.persistence.jpa.openjpa.BooleanValueHandler'");
@@ -102,8 +103,8 @@ public class PersistenceContext implements EnvironmentAware {
@Bean
public EntityFactory entityFactory()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
+ IllegalArgumentException, InvocationTargetException {
return (EntityFactory) Class.forName(env.getProperty("entity.factory")).getConstructor().newInstance();
}
@@ -111,8 +112,8 @@ public class PersistenceContext implements EnvironmentAware {
@ConditionalOnMissingBean(name = "plainSchemaDAO")
@Bean
public PlainSchemaDAO plainSchemaDAO()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
+ IllegalArgumentException, InvocationTargetException {
return (PlainSchemaDAO) Class.forName(env.getProperty("plainSchema.dao")).getConstructor().newInstance();
}
@@ -120,8 +121,8 @@ public class PersistenceContext implements EnvironmentAware {
@ConditionalOnMissingBean(name = "plainAttrDAO")
@Bean
public PlainAttrDAO plainAttrDAO()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
+ IllegalArgumentException, InvocationTargetException {
return (PlainAttrDAO) Class.forName(env.getProperty("plainAttr.dao")).getConstructor().newInstance();
}
@@ -129,8 +130,8 @@ public class PersistenceContext implements EnvironmentAware {
@ConditionalOnMissingBean(name = "plainAttrValueDAO")
@Bean
public PlainAttrValueDAO plainAttrValueDAO()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
+ IllegalArgumentException, InvocationTargetException {
return (PlainAttrValueDAO) Class.forName(env.getProperty("plainAttrValue.dao")).getConstructor().newInstance();
}
@@ -138,8 +139,8 @@ public class PersistenceContext implements EnvironmentAware {
@ConditionalOnMissingBean(name = "anySearchDAO")
@Bean
public AnySearchDAO anySearchDAO()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
+ IllegalArgumentException, InvocationTargetException {
return (AnySearchDAO) Class.forName(env.getProperty("any.search.dao")).getConstructor().newInstance();
}
@@ -147,8 +148,8 @@ public class PersistenceContext implements EnvironmentAware {
@ConditionalOnMissingBean(name = "userDAO")
@Bean
public UserDAO userDAO()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
+ IllegalArgumentException, InvocationTargetException {
return (UserDAO) Class.forName(env.getProperty("user.dao")).getConstructor().newInstance();
}
@@ -156,8 +157,8 @@ public class PersistenceContext implements EnvironmentAware {
@ConditionalOnMissingBean(name = "groupDAO")
@Bean
public GroupDAO groupDAO()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
+ IllegalArgumentException, InvocationTargetException {
return (GroupDAO) Class.forName(env.getProperty("group.dao")).getConstructor().newInstance();
}
@@ -165,12 +166,21 @@ public class PersistenceContext implements EnvironmentAware {
@ConditionalOnMissingBean(name = "anyObjectDAO")
@Bean
public AnyObjectDAO anyObjectDAO()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
+ IllegalArgumentException, InvocationTargetException {
return (AnyObjectDAO) Class.forName(env.getProperty("anyObject.dao")).getConstructor().newInstance();
}
+ @ConditionalOnMissingBean(name = "auditDAO")
+ @Bean
+ public AuditDAO auditDAO()
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
+ IllegalArgumentException, InvocationTargetException {
+
+ return (AuditDAO) Class.forName(env.getProperty("audit.dao")).getConstructor().newInstance();
+ }
+
@Bean
public Validator localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuditDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuditDAO.java
index 1fd173c..be47a81 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuditDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuditDAO.java
@@ -18,14 +18,13 @@
*/
package org.apache.syncope.core.persistence.jpa.dao;
-import javax.sql.DataSource;
-import java.sql.Timestamp;
-import java.util.Collections;
-import java.util.Date;
+import java.sql.Clob;
+import java.sql.SQLException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
-import org.apache.syncope.core.persistence.api.DomainHolder;
+import javax.persistence.Query;
+import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.types.AuditElements;
import org.apache.syncope.core.persistence.api.dao.AuditDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -33,113 +32,132 @@ import org.apache.syncope.core.persistence.api.entity.AuditEntry;
import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
import org.apache.syncope.core.provisioning.api.AuditEntryImpl;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
-import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
-@Transactional(rollbackFor = Throwable.class)
-@Repository
public class JPAAuditDAO extends AbstractDAO<AbstractEntity> implements AuditDAO {
- @Autowired
- private DomainHolder domainHolder;
+ protected static class MessageCriteriaBuilder {
- private static String buildWhereClauseForEntityKey(final String key) {
- return " WHERE MESSAGE LIKE '%" + key + "%' ";
- }
-
- @Override
- public List<AuditEntry> findByEntityKey(
- final String key,
- final int page,
- final int itemsPerPage,
- final List<AuditElements.Result> results,
- final List<String> events,
- final List<OrderByClause> orderByClauses) {
-
- try {
- String query = new MessageCriteriaBuilder().
- results(results).
- events(events).
- key(key).
- build();
- String queryString = "SELECT * FROM " + TABLE_NAME + " WHERE " + query;
- if (!orderByClauses.isEmpty()) {
- queryString += " ORDER BY " + orderByClauses.stream().
- map(orderBy -> orderBy.getField() + ' ' + orderBy.getDirection().name()).
- collect(Collectors.joining(","));
- }
- JdbcTemplate template = getJdbcTemplate();
- template.setMaxRows(itemsPerPage);
- template.setFetchSize(itemsPerPage * (page <= 0 ? 0 : page - 1));
- return template.query(queryString, (resultSet, i) -> {
- AuditEntryImpl entry = POJOHelper.deserialize(resultSet.getString("MESSAGE"), AuditEntryImpl.class);
- String throwable = resultSet.getString("THROWABLE");
- entry.setThrowable(throwable);
- Timestamp date = resultSet.getTimestamp("EVENT_DATE");
- entry.setDate(new Date(date.getTime()));
- entry.setKey(key);
- return entry;
- });
- } catch (Exception e) {
- LOG.error("Unable to execute search query to find entity " + key, e);
- }
- return Collections.emptyList();
- }
+ protected final StringBuilder query = new StringBuilder();
- @Override
- public Integer count(final String key) {
- try {
- String queryString = "SELECT COUNT(0) FROM " + AuditDAO.TABLE_NAME + buildWhereClauseForEntityKey(key);
- return Objects.requireNonNull(getJdbcTemplate().queryForObject(queryString, Integer.class));
- } catch (Exception e) {
- LOG.error("Unable to execute count query for entity " + key, e);
+ protected MessageCriteriaBuilder entityKey(final String entityKey) {
+ query.append(' ').append(MESSAGE_COLUMN).append(" LIKE '%\"key\":\"").append(entityKey).append("\"%'");
+ return this;
}
- return 0;
- }
- private JdbcTemplate getJdbcTemplate() {
- String domain = AuthContextUtils.getDomain();
- DataSource datasource = domainHolder.getDomains().get(domain);
- if (datasource == null) {
- throw new IllegalArgumentException("Could not get to DataSource for domain " + domain);
+ public MessageCriteriaBuilder type(final AuditElements.EventCategoryType type) {
+ if (type != null) {
+ query.append(" AND " + MESSAGE_COLUMN + " LIKE '%\"type\":\"").append(type.name()).append("\"%'");
+ }
+ return this;
}
- return new JdbcTemplate(datasource);
- }
- private static class MessageCriteriaBuilder {
-
- private final StringBuilder query = new StringBuilder(" 1=1 ");
-
- public MessageCriteriaBuilder key(final String key) {
- query.append(" AND MESSAGE LIKE '%\"key\":\"").append(key).append("\"%' ");
+ public MessageCriteriaBuilder category(final String category) {
+ if (StringUtils.isNotBlank(category)) {
+ query.append(" AND " + MESSAGE_COLUMN + " LIKE '%\"category\":\"").append(category).append("\"%'");
+ }
return this;
}
- public MessageCriteriaBuilder results(final List<AuditElements.Result> results) {
- buildCriteriaFor(results.stream().map(Enum::name).collect(Collectors.toList()), "result");
+ public MessageCriteriaBuilder subcategory(final String subcategory) {
+ if (StringUtils.isNotBlank(subcategory)) {
+ query.append(" AND " + MESSAGE_COLUMN + " LIKE '%\"subcategory\":\"").
+ append(subcategory).append("\"%'");
+ }
return this;
}
- private void buildCriteriaFor(final List<String> items, final String field) {
- if (!items.isEmpty()) {
- query.append(" AND ( ");
- query.append(items.stream().map(res -> "MESSAGE LIKE '%\"" + field + "\":\"" + res + "\"%'").
- collect(Collectors.joining(" OR ")));
- query.append(" )");
+ public MessageCriteriaBuilder events(final List<String> events) {
+ if (!events.isEmpty()) {
+ query.append(" AND ( ").
+ append(events.stream().
+ map(event -> MESSAGE_COLUMN + " LIKE '%\"event\":\"" + event + "\"%'").
+ collect(Collectors.joining(" OR "))).
+ append(" )");
}
+ return this;
}
- public MessageCriteriaBuilder events(final List<String> events) {
- buildCriteriaFor(events, "event");
+ public MessageCriteriaBuilder result(final AuditElements.Result result) {
+ if (result != null) {
+ query.append(" AND ").
+ append(MESSAGE_COLUMN).append(" LIKE '%\"result\":\"").append(result.name()).append("\"%' ");
+ }
return this;
}
public String build() {
- query.trimToSize();
return query.toString();
}
}
+
+ protected MessageCriteriaBuilder messageCriteriaBuilder(final String entityKey) {
+ return new MessageCriteriaBuilder().entityKey(entityKey);
+ }
+
+ protected String select() {
+ return MESSAGE_COLUMN;
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public List<AuditEntry> findByEntityKey(
+ final String entityKey,
+ final int page,
+ final int itemsPerPage,
+ final AuditElements.EventCategoryType type,
+ final String category,
+ final String subcategory,
+ final List<String> events,
+ final AuditElements.Result result,
+ final List<OrderByClause> orderByClauses) {
+
+ String queryString = "SELECT " + select()
+ + " FROM " + TABLE
+ + " WHERE " + messageCriteriaBuilder(entityKey).
+ type(type).
+ category(category).
+ subcategory(subcategory).
+ result(result).
+ events(events).
+ build();
+ if (!orderByClauses.isEmpty()) {
+ queryString += " ORDER BY " + orderByClauses.stream().
+ map(orderBy -> orderBy.getField() + ' ' + orderBy.getDirection().name()).
+ collect(Collectors.joining(","));
+ }
+
+ Query query = entityManager().createNativeQuery(queryString);
+ query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
+ if (itemsPerPage >= 0) {
+ query.setMaxResults(itemsPerPage);
+ }
+
+ @SuppressWarnings("unchecked")
+ List<Object> entries = query.getResultList();
+ return entries.stream().map(row -> {
+ String value;
+ if (row instanceof Clob) {
+ Clob clob = (Clob) row;
+ try {
+ value = clob.getSubString(1, (int) clob.length());
+ } catch (SQLException e) {
+ LOG.error("Unexpected error reading Audit Entry for entity key {}", entityKey, e);
+ return null;
+ }
+ } else {
+ value = row.toString();
+ }
+ return POJOHelper.deserialize(value, AuditEntryImpl.class);
+ }).filter(Objects::nonNull).collect(Collectors.toList());
+ }
+
+ @Override
+ public int count(final String key) {
+ String queryString = "SELECT COUNT(0) FROM " + TABLE
+ + " WHERE " + messageCriteriaBuilder(key).build();
+ Query countQuery = entityManager().createNativeQuery(queryString);
+
+ return ((Number) countQuery.getSingleResult()).intValue();
+ }
}
diff --git a/core/persistence-jpa/src/main/resources/audit/audit.sql b/core/persistence-jpa/src/main/resources/audit/audit.sql
index 44ffb17..1526b50 100644
--- a/core/persistence-jpa/src/main/resources/audit/audit.sql
+++ b/core/persistence-jpa/src/main/resources/audit/audit.sql
@@ -22,5 +22,3 @@ CREATE TABLE IF NOT EXISTS SYNCOPEAUDIT (
MESSAGE TEXT NOT NULL,
THROWABLE TEXT
);
-
-COMMIT;
diff --git a/core/persistence-jpa/src/main/resources/audit/audit_sqlserver.sql b/core/persistence-jpa/src/main/resources/audit/audit_sqlserver.sql
index 191428a..4615af6 100644
--- a/core/persistence-jpa/src/main/resources/audit/audit_sqlserver.sql
+++ b/core/persistence-jpa/src/main/resources/audit/audit_sqlserver.sql
@@ -15,14 +15,13 @@
-- specific language governing permissions and limitations
-- under the License.
-IF NOT EXISTS
-(SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SYNCOPEAUDIT]') AND type in (N'U'))
-BEGIN
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYNCOPEAUDIT]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[SYNCOPEAUDIT];
+
CREATE TABLE SYNCOPEAUDIT (
EVENT_DATE DATETIME,
LOGGER_LEVEL VARCHAR(255) NOT NULL,
LOGGER VARCHAR(255) NOT NULL,
MESSAGE TEXT NOT NULL,
THROWABLE TEXT
-)
-END
+) ON [PRIMARY];
diff --git a/core/persistence-jpa/src/main/resources/persistence.properties b/core/persistence-jpa/src/main/resources/persistence.properties
index 0841aa0..448aaef 100644
--- a/core/persistence-jpa/src/main/resources/persistence.properties
+++ b/core/persistence-jpa/src/main/resources/persistence.properties
@@ -23,4 +23,5 @@ any.search.dao=org.apache.syncope.core.persistence.jpa.dao.JPAAnySearchDAO
user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO
group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAGroupDAO
anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO
+audit.dao=org.apache.syncope.core.persistence.jpa.dao.JPAAuditDAO
openjpa.RemoteCommitProvider=sjvm
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditEntryImpl.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditEntryImpl.java
index 2d6d118..9681919 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditEntryImpl.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditEntryImpl.java
@@ -49,8 +49,6 @@ public class AuditEntryImpl implements AuditEntry {
private Date date;
- private String key;
-
@JsonCreator
public AuditEntryImpl(
@JsonProperty("who") final String who,
@@ -145,15 +143,6 @@ public class AuditEntryImpl implements AuditEntry {
this.date = date;
}
- @Override
- public String getKey() {
- return key;
- }
-
- public void setKey(final String key) {
- this.key = key;
- }
-
public static Builder builder() {
return new Builder();
}
@@ -223,7 +212,6 @@ public class AuditEntryImpl implements AuditEntry {
AuditEntryImpl entry = new AuditEntryImpl(who, logger, before, output, input);
entry.setDate(date);
entry.setThrowable(throwable);
- entry.setKey(key);
return entry;
}
}
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AuditDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AuditDataBinder.java
index 2f79388..082f71f 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AuditDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AuditDataBinder.java
@@ -23,5 +23,5 @@ import org.apache.syncope.core.persistence.api.entity.AuditEntry;
public interface AuditDataBinder {
- AuditEntryTO getAuditTO(AuditEntry auditEntry);
+ AuditEntryTO getAuditTO(String key, AuditEntry auditEntry);
}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuditDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuditDataBinderImpl.java
index 8d74e11..de49702 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuditDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuditDataBinderImpl.java
@@ -31,36 +31,36 @@ import org.springframework.stereotype.Component;
public class AuditDataBinderImpl implements AuditDataBinder {
@Override
- public AuditEntryTO getAuditTO(final AuditEntry auditEntry) {
- AuditEntryTO auditTO = new AuditEntryTO();
- auditTO.setKey(auditEntry.getKey());
- auditTO.setWho(auditEntry.getWho());
- auditTO.setDate(auditEntry.getDate());
- auditTO.setThrowable(auditEntry.getThrowable());
- auditTO.setLoggerName(auditEntry.getLogger().toLoggerName());
+ public AuditEntryTO getAuditTO(final String key, final AuditEntry auditEntry) {
+ AuditEntryTO auditEntryTO = new AuditEntryTO();
+ auditEntryTO.setKey(key);
+ auditEntryTO.setWho(auditEntry.getWho());
+ auditEntryTO.setDate(auditEntry.getDate());
+ auditEntryTO.setThrowable(auditEntry.getThrowable());
+ auditEntryTO.setLoggerName(auditEntry.getLogger().toLoggerName());
- auditTO.setSubCategory(auditEntry.getLogger().getSubcategory());
- auditTO.setEvent(auditEntry.getLogger().getEvent());
+ auditEntryTO.setSubCategory(auditEntry.getLogger().getSubcategory());
+ auditEntryTO.setEvent(auditEntry.getLogger().getEvent());
if (auditEntry.getLogger().getResult() != null) {
- auditTO.setResult(auditEntry.getLogger().getResult().name());
+ auditEntryTO.setResult(auditEntry.getLogger().getResult().name());
}
if (auditEntry.getBefore() != null) {
- auditTO.setBefore(POJOHelper.serialize(auditEntry.getBefore()));
+ auditEntryTO.setBefore(POJOHelper.serialize(auditEntry.getBefore()));
}
if (auditEntry.getInput() != null) {
- auditTO.getInputs().addAll(Arrays.stream(auditEntry.getInput()).
+ auditEntryTO.getInputs().addAll(Arrays.stream(auditEntry.getInput()).
filter(Objects::nonNull).
map(POJOHelper::serialize).
collect(Collectors.toList()));
}
if (auditEntry.getOutput() != null) {
- auditTO.setOutput(POJOHelper.serialize(auditEntry.getOutput()));
+ auditEntryTO.setOutput(POJOHelper.serialize(auditEntry.getOutput()));
}
- return auditTO;
+ return auditEntryTO;
}
}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AuditReportlet.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AuditReportlet.java
index 7b9c555..a0632d4 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AuditReportlet.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AuditReportlet.java
@@ -49,12 +49,12 @@ public class AuditReportlet extends AbstractReportlet {
private DataSource datasource;
private void doExtractConf(final ContentHandler handler, final AtomicReference<String> status) throws SAXException {
- status.set("Fetching " + conf.getSize() + " rows from the " + AuditDAO.TABLE_NAME + " table");
+ status.set("Fetching " + conf.getSize() + " rows from the " + AuditDAO.TABLE + " table");
JdbcTemplate jdbcTemplate = new JdbcTemplate(datasource);
jdbcTemplate.setMaxRows(conf.getSize());
List<Map<String, Object>> rows = jdbcTemplate.
- queryForList("SELECT * FROM " + AuditDAO.TABLE_NAME + " ORDER BY EVENT_DATE DESC");
+ queryForList("SELECT * FROM " + AuditDAO.TABLE + " ORDER BY EVENT_DATE DESC");
handler.startElement("", "", "events", null);
AttributesImpl atts = new AttributesImpl();
diff --git a/docker/core/src/main/resources/persistence.properties.all b/docker/core/src/main/resources/persistence.properties.all
index 2393a4e..42f7758 100644
--- a/docker/core/src/main/resources/persistence.properties.all
+++ b/docker/core/src/main/resources/persistence.properties.all
@@ -23,4 +23,5 @@ any.search.dao=org.apache.syncope.core.persistence.jpa.dao.JPAAnySearchDAO
user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO
group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAGroupDAO
anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO
+audit.dao=org.apache.syncope.core.persistence.jpa.dao.JPAAuditDAO
openjpa.RemoteCommitProvider=${OPENJPA_REMOTE_COMMIT}
diff --git a/docker/core/src/main/resources/persistence.properties.myjson b/docker/core/src/main/resources/persistence.properties.myjson
index 31a2dd8..cac21af 100644
--- a/docker/core/src/main/resources/persistence.properties.myjson
+++ b/docker/core/src/main/resources/persistence.properties.myjson
@@ -24,4 +24,5 @@ user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONUserDAO
group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONGroupDAO
anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONAnyObjectDAO
conf.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONConfDAO
+audit.dao=org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAuditDAO
openjpa.RemoteCommitProvider=sjvm
diff --git a/docker/core/src/main/resources/persistence.properties.pgjsonb b/docker/core/src/main/resources/persistence.properties.pgjsonb
index d5a5128..b88b052 100644
--- a/docker/core/src/main/resources/persistence.properties.pgjsonb
+++ b/docker/core/src/main/resources/persistence.properties.pgjsonb
@@ -23,4 +23,5 @@ any.search.dao=org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnySearchDAO
user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONUserDAO
group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONGroupDAO
anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONAnyObjectDAO
+audit.dao=org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAuditDAO
openjpa.RemoteCommitProvider=${OPENJPA_REMOTE_COMMIT}
diff --git a/ext/elasticsearch/persistence-jpa/src/main/resources/persistence.properties b/ext/elasticsearch/persistence-jpa/src/main/resources/persistence.properties
index 194c758..14b5143 100644
--- a/ext/elasticsearch/persistence-jpa/src/main/resources/persistence.properties
+++ b/ext/elasticsearch/persistence-jpa/src/main/resources/persistence.properties
@@ -23,4 +23,5 @@ any.search.dao=org.apache.syncope.core.persistence.jpa.dao.ElasticsearchAnySearc
user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO
group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAGroupDAO
anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO
+audit.dao=org.apache.syncope.core.persistence.jpa.dao.JPAAuditDAO
openjpa.RemoteCommitProvider=sjvm
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 3dcb28a..a761142 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -1251,14 +1251,15 @@ under the License.
</build>
<run>
<env>
- <ORACLE_DISABLE_ASYNCH_IO>true</ORACLE_DISABLE_ASYNCH_IO>
+ <ORACLE_ALLOW_REMOTE>true</ORACLE_ALLOW_REMOTE>
+ <ORACLE_ENABLE_XDB>true</ORACLE_ENABLE_XDB>
</env>
<ports>
<port>1521:1521</port>
</ports>
<wait>
- <log>Disconnected from Oracle Database</log>
- <time>300000</time>
+ <log>Disconnected from Oracle Database 11g Express Edition</log>
+ <time>30000</time>
</wait>
</run>
</image>
diff --git a/fit/core-reference/src/main/resources/elasticsearch/persistence.properties b/fit/core-reference/src/main/resources/elasticsearch/persistence.properties
index 194c758..14b5143 100644
--- a/fit/core-reference/src/main/resources/elasticsearch/persistence.properties
+++ b/fit/core-reference/src/main/resources/elasticsearch/persistence.properties
@@ -23,4 +23,5 @@ any.search.dao=org.apache.syncope.core.persistence.jpa.dao.ElasticsearchAnySearc
user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO
group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAGroupDAO
anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO
+audit.dao=org.apache.syncope.core.persistence.jpa.dao.JPAAuditDAO
openjpa.RemoteCommitProvider=sjvm
diff --git a/fit/core-reference/src/main/resources/myjson/domains/Master.properties b/fit/core-reference/src/main/resources/myjson/domains/Master.properties
index 2197c87..6dfdf26 100644
--- a/fit/core-reference/src/main/resources/myjson/domains/Master.properties
+++ b/fit/core-reference/src/main/resources/myjson/domains/Master.properties
@@ -25,4 +25,4 @@ Master.orm=META-INF/spring-orm-myjson.xml
Master.pool.maxActive=10
Master.pool.minIdle=2
-Master.audit.sql=audit_mysql_innodb.sql
+Master.audit.sql=audit_myjson.sql
diff --git a/fit/core-reference/src/main/resources/oracle/Dockerfile b/fit/core-reference/src/main/resources/oracle/Dockerfile
index eec9268..ede2331 100644
--- a/fit/core-reference/src/main/resources/oracle/Dockerfile
+++ b/fit/core-reference/src/main/resources/oracle/Dockerfile
@@ -15,5 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-FROM store/oracle/database-enterprise:12.2.0.1-slim
+FROM oracleinanutshell/oracle-xe-11g
+
ADD init.sql /docker-entrypoint-initdb.d/
+
diff --git a/fit/core-reference/src/main/resources/pgjsonb/domains/Master.properties b/fit/core-reference/src/main/resources/pgjsonb/domains/Master.properties
index d9a648f..4ab67b0 100644
--- a/fit/core-reference/src/main/resources/pgjsonb/domains/Master.properties
+++ b/fit/core-reference/src/main/resources/pgjsonb/domains/Master.properties
@@ -25,4 +25,4 @@ Master.orm=META-INF/spring-orm-pgjsonb.xml
Master.pool.maxActive=10
Master.pool.minIdle=2
-Master.audit.sql=audit.sql
+Master.audit.sql=audit_pgjsonb.sql
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java
index d8fc20a..7fa4904 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java
@@ -47,7 +47,7 @@ public class AuditITCase extends AbstractITCase {
i++;
} while (results.isEmpty() && i < maxWaitSeconds);
if (results.isEmpty()) {
- fail("Timeout when executing query for key " + query.getKey());
+ fail("Timeout when executing query for key " + query.getEntityKey());
}
return results.get(0);
@@ -58,8 +58,7 @@ public class AuditITCase extends AbstractITCase {
UserTO userTO = createUser(UserITCase.getUniqueSample("audit@syncope.org")).getEntity();
assertNotNull(userTO.getKey());
- AuditQuery query = new AuditQuery.Builder().
- key(userTO.getKey()).orderBy("event_date desc").
+ AuditQuery query = new AuditQuery.Builder(userTO.getKey()).orderBy("event_date desc").
page(1).size(1).build();
AuditEntryTO entry = query(query, 50);
assertEquals(userTO.getKey(), entry.getKey());
@@ -67,15 +66,16 @@ public class AuditITCase extends AbstractITCase {
}
@Test
- public void findByUserAndByEventAndByResults() {
+ public void findByUserAndOther() {
UserTO userTO = createUser(UserITCase.getUniqueSample("audit-2@syncope.org")).getEntity();
assertNotNull(userTO.getKey());
- AuditQuery query = new AuditQuery.Builder().
- key(userTO.getKey()).
+ AuditQuery query = new AuditQuery.Builder(userTO.getKey()).
orderBy("event_date desc").
page(1).
size(1).
+ type(AuditElements.EventCategoryType.LOGIC).
+ category("UserLogic").
event("create").
result(AuditElements.Result.SUCCESS).
build();
@@ -89,8 +89,7 @@ public class AuditITCase extends AbstractITCase {
GroupTO groupTO = createGroup(GroupITCase.getBasicSample("AuditGroup")).getEntity();
assertNotNull(groupTO.getKey());
- AuditQuery query = new AuditQuery.Builder().
- key(groupTO.getKey()).orderBy("event_date desc").
+ AuditQuery query = new AuditQuery.Builder(groupTO.getKey()).orderBy("event_date desc").
page(1).size(1).build();
AuditEntryTO entry = query(query, 50);
assertEquals(groupTO.getKey(), entry.getKey());
diff --git a/src/main/asciidoc/reference-guide/workingwithapachesyncope/systemadministration/dbms.adoc b/src/main/asciidoc/reference-guide/workingwithapachesyncope/systemadministration/dbms.adoc
index 865ad48..6048c2f 100644
--- a/src/main/asciidoc/reference-guide/workingwithapachesyncope/systemadministration/dbms.adoc
+++ b/src/main/asciidoc/reference-guide/workingwithapachesyncope/systemadministration/dbms.adoc
@@ -90,6 +90,7 @@ any.search.dao=org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnySearchDAO
user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONUserDAO
group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONGroupDAO
anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONAnyObjectDAO
+audit.dao=org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAuditDAO
....
In `provisioning.properties`, replace as follows:
@@ -109,6 +110,7 @@ Master.username=syncope
Master.password=syncope
Master.databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary
Master.orm=META-INF/spring-orm-pgjsonb.xml
+Master.audit.sql=audit_pgjsonb.sql
....
[WARNING]
@@ -209,6 +211,20 @@ Add the following dependency to `core/pom.xml`:
</dependency>
----
+In `persistence.properties`, replace as follows:
+
+....
+entity.factory=org.apache.syncope.core.persistence.jpa.entity.MyJPAJSONEntityFactory
+plainSchema.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainSchemaDAO
+plainAttr.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrDAO
+plainAttrValue.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrValueDAO
+any.search.dao=org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnySearchDAO
+user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONUserDAO
+group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONGroupDAO
+anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONAnyObjectDAO
+audit.dao=org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAuditDAO
+....
+
In `provisioning.properties`, replace as follows:
....
@@ -217,8 +233,7 @@ quartz.sql=tables_mysql_innodb.sql
....
[WARNING]
-This assumes that the InnoDB engine is enabled in your MySQL instance - if this is not the case, then change the value
-for `quartz.sql` to `tables_mysql.sql`.
+This assumes that the InnoDB engine is enabled in your MySQL instance.
In `domains/Master.properties` (for the `Master` domain), replace as follows:
@@ -230,17 +245,13 @@ Master.username=syncope
Master.password=syncope
Master.databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3)
Master.orm=META-INF/spring-orm-myjson.xml
-Master.audit.sql=audit_mysql_innodb.sql
+Master.audit.sql=audit_myjson.sql
....
[CAUTION]
It is important to set the collation to `utf8_general_ci` after creation of `syncope` database.
[WARNING]
-This assumes that the InnoDB engine is enabled in your MySQL instance - if this is not the case, then change the value
-for `Master.audit` to `audit.sql`.
-
-[WARNING]
This assumes that you have a MySQL instance running on localhost, listening on its default port 3306 with a database
`syncope` fully accessible by user `syncope` with password `syncope`.