This is an automated email from the ASF dual-hosted git repository.
aleks pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 6a0928eb9 Rework custom auditing handler
6a0928eb9 is described below
commit 6a0928eb958acdb2679a8757b8daf8a95fcad515
Author: Adam Saghy <[email protected]>
AuthorDate: Fri Jul 29 19:05:20 2022 +0200
Rework custom auditing handler
---
.../auditing/CustomAuditingHandler.java | 94 ++++++++++++
.../core/auditing/JpaAuditingHandlerRegistrar.java | 2 +-
.../data/auditing/CustomAuditingHandler.java | 167 ---------------------
.../data/auditing/CustomAuditingHandlerTest.java | 13 +-
4 files changed, 100 insertions(+), 176 deletions(-)
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/auditing/CustomAuditingHandler.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/auditing/CustomAuditingHandler.java
new file mode 100644
index 000000000..480769feb
--- /dev/null
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/auditing/CustomAuditingHandler.java
@@ -0,0 +1,94 @@
+/**
+ * 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.fineract.infrastructure.auditing;
+
+import org.apache.fineract.infrastructure.core.auditing.CustomDateTimeProvider;
+import
org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.data.auditing.AuditableBeanWrapper;
+import org.springframework.data.auditing.AuditingHandler;
+import org.springframework.data.auditing.DateTimeProvider;
+import org.springframework.data.domain.AuditorAware;
+import org.springframework.data.mapping.PersistentEntity;
+import org.springframework.data.mapping.PersistentProperty;
+import org.springframework.data.mapping.context.MappingContext;
+import org.springframework.data.mapping.context.PersistentEntities;
+import org.springframework.util.Assert;
+
+public class CustomAuditingHandler extends AuditingHandler {
+
+ /**
+ * Creates a new {@link AuditableBeanWrapper} using the given {@link
PersistentEntities} when looking up auditing
+ * metadata via reflection.
+ *
+ * @param entities
+ * must not be {@literal null}.
+ * @since 1.10
+ */
+ public CustomAuditingHandler(PersistentEntities entities) {
+ super(entities);
+ }
+
+ /**
+ * Creates a new {@link AuditableBeanWrapper} using the given {@link
MappingContext} when looking up auditing
+ * metadata via reflection.
+ *
+ * @param mappingContext
+ * must not be {@literal null}.
+ * @since 1.8
+ * @deprecated use {@link AuditingHandler(PersistentEntities)} instead.
+ */
+ public CustomAuditingHandler(MappingContext<? extends PersistentEntity<?,
?>, ? extends PersistentProperty<?>> mappingContext,
+ AuditorAware<?> auditorAware) {
+ this(PersistentEntities.of(mappingContext));
+ setAuditorAware(auditorAware);
+ }
+
+ private DateTimeProvider fetchDateTimeProvider(Object bean) {
+ return bean instanceof AbstractAuditableWithUTCDateTimeCustom ?
CustomDateTimeProvider.TENANT : CustomDateTimeProvider.INSTANCE;
+ }
+
+ /**
+ * Marks the given object as created.
+ *
+ * @param source
+ * must not be {@literal null}.
+ */
+ @NotNull
+ @Override
+ public <T> T markCreated(@NotNull T source) {
+ Assert.notNull(source, "Source entity must not be null");
+ setDateTimeProvider(fetchDateTimeProvider(source));
+ return super.markCreated(source);
+ }
+
+ /**
+ * Marks the given object as modified.
+ *
+ * @param source
+ * must not be {@literal null}.
+ */
+ @NotNull
+ @Override
+ public <T> T markModified(@NotNull T source) {
+ Assert.notNull(source, "Source entity must not be null");
+ setDateTimeProvider(fetchDateTimeProvider(source));
+ return super.markModified(source);
+ }
+}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/auditing/JpaAuditingHandlerRegistrar.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/auditing/JpaAuditingHandlerRegistrar.java
index 6375b271e..1375e8bbe 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/auditing/JpaAuditingHandlerRegistrar.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/auditing/JpaAuditingHandlerRegistrar.java
@@ -18,11 +18,11 @@
*/
package org.apache.fineract.infrastructure.core.auditing;
+import org.apache.fineract.infrastructure.auditing.CustomAuditingHandler;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
-import org.springframework.data.auditing.CustomAuditingHandler;
public class JpaAuditingHandlerRegistrar implements
ImportBeanDefinitionRegistrar {
diff --git
a/fineract-provider/src/main/java/org/springframework/data/auditing/CustomAuditingHandler.java
b/fineract-provider/src/main/java/org/springframework/data/auditing/CustomAuditingHandler.java
deleted file mode 100644
index 9157d01d0..000000000
---
a/fineract-provider/src/main/java/org/springframework/data/auditing/CustomAuditingHandler.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
- * 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.springframework.data.auditing;
-
-import java.time.temporal.TemporalAccessor;
-import java.util.Optional;
-import org.apache.fineract.infrastructure.core.auditing.CustomDateTimeProvider;
-import
org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.data.domain.AuditorAware;
-import org.springframework.data.mapping.PersistentEntity;
-import org.springframework.data.mapping.PersistentProperty;
-import org.springframework.data.mapping.context.MappingContext;
-import org.springframework.data.mapping.context.PersistentEntities;
-import org.springframework.util.Assert;
-
-/**
- * Due to the package-private visibility of the Auditor, temporarely The
CustomAuditingHandler must be placed in the
- * same package. Later when we don't need to distinct the Auditable entities
by interface anymore, it will be reworked.
- */
-public class CustomAuditingHandler extends AuditingHandler {
-
- private static final Logger LOG =
LoggerFactory.getLogger(CustomAuditingHandler.class);
- private final AuditableBeanWrapperFactory factory;
- private boolean dateTimeForNow = true;
- private boolean modifyOnCreation = true;
-
- /**
- * Creates a new {@link AuditableBeanWrapper} using the given {@link
PersistentEntities} when looking up auditing
- * metadata via reflection.
- *
- * @param entities
- * must not be {@literal null}.
- * @since 1.10
- */
- public CustomAuditingHandler(PersistentEntities entities) {
- super(entities);
- this.factory = new MappingAuditableBeanWrapperFactory(entities);
- }
-
- /**
- * Creates a new {@link AuditableBeanWrapper} using the given {@link
MappingContext} when looking up auditing
- * metadata via reflection.
- *
- * @param mappingContext
- * must not be {@literal null}.
- * @since 1.8
- * @deprecated use {@link AuditingHandler(PersistentEntities)} instead.
- */
- public CustomAuditingHandler(MappingContext<? extends PersistentEntity<?,
?>, ? extends PersistentProperty<?>> mappingContext,
- AuditorAware<?> auditorAware) {
- this(PersistentEntities.of(mappingContext));
- setAuditorAware(auditorAware);
- }
-
- private Optional<TemporalAccessor> touchDate(AuditableBeanWrapper<?>
wrapper, boolean isNew) {
-
- Assert.notNull(wrapper, "AuditableBeanWrapper must not be null");
-
- DateTimeProvider dateTimeProvider =
fetchDateTimeProvider(wrapper.getBean());
- Optional<TemporalAccessor> now = dateTimeProvider.getNow();
-
- Assert.notNull(now, () -> String.format("Now must not be null Returned
by: %s", dateTimeProvider.getClass()));
-
- now.filter(__ -> isNew).ifPresent(wrapper::setCreatedDate);
- now.filter(__ -> !isNew ||
modifyOnCreation).ifPresent(wrapper::setLastModifiedDate);
-
- return now;
- }
-
- private DateTimeProvider fetchDateTimeProvider(Object bean) {
- return bean instanceof AbstractAuditableWithUTCDateTimeCustom ?
CustomDateTimeProvider.TENANT : CustomDateTimeProvider.INSTANCE;
- }
-
- /**
- * Marks the given object as created.
- *
- * @param auditor
- * can be {@literal null}.
- * @param source
- * must not be {@literal null}.
- */
- @Override
- <T> T markCreated(Auditor auditor, T source) {
-
- Assert.notNull(source, "Source entity must not be null");
-
- return touch(auditor, source, true);
- }
-
- /**
- * Marks the given object as modified.
- *
- * @param auditor
- * @param source
- */
- @Override
- <T> T markModified(Auditor auditor, T source) {
-
- Assert.notNull(source, "Source entity must not be null");
-
- return touch(auditor, source, false);
- }
-
- private <T> T touch(Auditor auditor, T target, boolean isNew) {
-
- Optional<AuditableBeanWrapper<T>> wrapper =
factory.getBeanWrapperFor(target);
-
- return wrapper.map(it -> {
-
- touchAuditor(auditor, it, isNew);
- Optional<TemporalAccessor> now = dateTimeForNow ? touchDate(it,
isNew) : Optional.empty();
-
- if (LOG.isDebugEnabled()) {
-
- Object defaultedNow = now.map(Object::toString).orElse("not
set");
- Object defaultedAuditor = auditor.isPresent() ?
auditor.toString() : "unknown";
-
- LOG.debug("Touched {} - Last modification at {} by {}",
target, defaultedNow, defaultedAuditor);
- }
-
- return it.getBean();
- }).orElse(target);
- }
-
- /**
- * Sets modifying and creating auditor. Creating auditor is only set on
new auditables.
- *
- * @param auditor
- * @param wrapper
- * @param isNew
- * @return
- */
- private void touchAuditor(Auditor auditor, AuditableBeanWrapper<?>
wrapper, boolean isNew) {
-
- if (!auditor.isPresent()) {
- return;
- }
-
- Assert.notNull(wrapper, "AuditableBeanWrapper must not be null");
-
- if (isNew) {
- wrapper.setCreatedBy(auditor.getValue());
- }
-
- if (!isNew || modifyOnCreation) {
- wrapper.setLastModifiedBy(auditor.getValue());
- }
- }
-}
diff --git
a/fineract-provider/src/test/java/org/springframework/data/auditing/CustomAuditingHandlerTest.java
b/fineract-provider/src/test/java/org/springframework/data/auditing/CustomAuditingHandlerTest.java
index 4abe7b77f..a5f7e15c2 100644
---
a/fineract-provider/src/test/java/org/springframework/data/auditing/CustomAuditingHandlerTest.java
+++
b/fineract-provider/src/test/java/org/springframework/data/auditing/CustomAuditingHandlerTest.java
@@ -27,6 +27,7 @@ import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;
+import org.apache.fineract.infrastructure.auditing.CustomAuditingHandler;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
import
org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
@@ -50,11 +51,10 @@ public class CustomAuditingHandlerTest {
@Test
public void markCreated() {
- Auditor auditor = Mockito.mock(Auditor.class);
MappingContext mappingContext = Mockito.mock(MappingContext.class);
CustomAuditingHandler testInstance = new
CustomAuditingHandler(PersistentEntities.of(mappingContext));
AbstractAuditableWithUTCDateTimeCustom targetObject =
Mockito.spy(AbstractAuditableWithUTCDateTimeCustom.class);
- targetObject = testInstance.markCreated(auditor, targetObject);
+ targetObject = testInstance.markCreated(targetObject);
OffsetDateTime now =
OffsetDateTime.now(DateUtils.getDateTimeZoneOfTenant());
assertTrue(targetObject.getCreatedDate().isPresent());
@@ -67,11 +67,10 @@ public class CustomAuditingHandlerTest {
@Test
public void markModified() {
- Auditor auditor = Mockito.mock(Auditor.class);
MappingContext mappingContext = Mockito.mock(MappingContext.class);
CustomAuditingHandler testInstance = new
CustomAuditingHandler(PersistentEntities.of(mappingContext));
AbstractAuditableWithUTCDateTimeCustom targetObject =
Mockito.spy(AbstractAuditableWithUTCDateTimeCustom.class);
- targetObject = testInstance.markModified(auditor, targetObject);
+ targetObject = testInstance.markModified(targetObject);
OffsetDateTime now =
OffsetDateTime.now(DateUtils.getDateTimeZoneOfTenant());
assertTrue(targetObject.getLastModifiedDate().isPresent());
@@ -84,11 +83,10 @@ public class CustomAuditingHandlerTest {
@Test
public void markModifiedOldDateTimeProvider() {
- Auditor auditor = Mockito.mock(Auditor.class);
MappingContext mappingContext = Mockito.mock(MappingContext.class);
CustomAuditingHandler testInstance = new
CustomAuditingHandler(PersistentEntities.of(mappingContext));
AbstractAuditableCustom targetObject =
Mockito.spy(AbstractAuditableCustom.class);
- targetObject = testInstance.markModified(auditor, targetObject);
+ targetObject = testInstance.markModified(targetObject);
LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
assertTrue(targetObject.getLastModifiedDate().isPresent());
@@ -101,11 +99,10 @@ public class CustomAuditingHandlerTest {
@Test
public void markCreatedOldDateTimeProvider() {
- Auditor auditor = Mockito.mock(Auditor.class);
MappingContext mappingContext = Mockito.mock(MappingContext.class);
CustomAuditingHandler testInstance = new
CustomAuditingHandler(PersistentEntities.of(mappingContext));
AbstractAuditableCustom targetObject =
Mockito.spy(AbstractAuditableCustom.class);
- targetObject = testInstance.markCreated(auditor, targetObject);
+ targetObject = testInstance.markCreated(targetObject);
LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
assertTrue(targetObject.getCreatedDate().isPresent());