diff --git a/.github/workflows/build-mariadb.yml b/.github/workflows/build-mariadb.yml index 517fcc354..c84dbefca 100644 --- a/.github/workflows/build-mariadb.yml +++ b/.github/workflows/build-mariadb.yml @@ -58,13 +58,13 @@ jobs: sudo apt-get install ghostscript graphviz -y - name: Basic Auth Build & Test - run: ./gradlew --no-daemon -q --console=plain build test --fail-fast doc -x :twofactor-tests:test -x :oauth2-test:test + run: ./gradlew --no-daemon --console=plain build test --fail-fast doc -x :twofactor-tests:test -x :oauth2-test:test - name: 2FA Build & Test - run: ./gradlew --no-daemon -q --console=plain :twofactor-tests:test --fail-fast + run: ./gradlew --no-daemon --console=plain :twofactor-tests:test --fail-fast - name: OAuth2 Build & Test - run: ./gradlew --no-daemon -q --console=plain :oauth2-tests:test --fail-fast + run: ./gradlew --no-daemon --console=plain :oauth2-tests:test --fail-fast - name: Archive test results if: always() diff --git a/.github/workflows/build-mysql.yml b/.github/workflows/build-mysql.yml index 55a9312e1..d2fb2c6fa 100644 --- a/.github/workflows/build-mysql.yml +++ b/.github/workflows/build-mysql.yml @@ -58,13 +58,13 @@ jobs: sudo apt-get install ghostscript graphviz -y - name: Basic Auth Build & Test - run: ./gradlew --no-daemon -q --console=plain build test --fail-fast doc -x :twofactor-tests:test -x :oauth2-test:test -PdbType=mysql + run: ./gradlew --no-daemon --console=plain build test --fail-fast doc -x :twofactor-tests:test -x :oauth2-test:test -PdbType=mysql - name: 2FA Build & Test - run: ./gradlew --no-daemon -q --console=plain :twofactor-tests:test --fail-fast -PdbType=mysql + run: ./gradlew --no-daemon --console=plain :twofactor-tests:test --fail-fast -PdbType=mysql - name: OAuth2 Build & Test - run: ./gradlew --no-daemon -q --console=plain :oauth2-tests:test --fail-fast -PdbType=mysql + run: ./gradlew --no-daemon --console=plain :oauth2-tests:test --fail-fast -PdbType=mysql - name: Archive test results if: always() diff --git a/.github/workflows/build-postgresql.yml b/.github/workflows/build-postgresql.yml index 6bb628c9c..d09e68c04 100644 --- a/.github/workflows/build-postgresql.yml +++ b/.github/workflows/build-postgresql.yml @@ -59,13 +59,13 @@ jobs: sudo apt-get install ghostscript graphviz -y - name: Basic Auth Build & Test - run: ./gradlew --no-daemon -q --console=plain build test --fail-fast doc -x :twofactor-tests:test -x :oauth2-test:test -PdbType=postgresql + run: ./gradlew --no-daemon --console=plain build test --fail-fast doc -x :twofactor-tests:test -x :oauth2-test:test -PdbType=postgresql - name: 2FA Build & Test - run: ./gradlew --no-daemon -q --console=plain :twofactor-tests:test --fail-fast -PdbType=postgresql + run: ./gradlew --no-daemon --console=plain :twofactor-tests:test --fail-fast -PdbType=postgresql - name: OAuth2 Build & Test - run: ./gradlew --no-daemon -q --console=plain :oauth2-tests:test --fail-fast -PdbType=postgresql + run: ./gradlew --no-daemon --console=plain :oauth2-tests:test --fail-fast -PdbType=postgresql - name: Archive test results if: always() diff --git a/fineract-avro-schemas/src/main/avro/MessageV1.avsc b/fineract-avro-schemas/src/main/avro/MessageV1.avsc index cfbff9bc4..d20c5b626 100644 --- a/fineract-avro-schemas/src/main/avro/MessageV1.avsc +++ b/fineract-avro-schemas/src/main/avro/MessageV1.avsc @@ -15,7 +15,7 @@ }, { "name": "type", - "doc": "The type of event the payload refers to. For example LOAN_APPROVED", + "doc": "The type of event the payload refers to. For example LoanApprovedBusinessEvent", "type": "string" }, { @@ -44,8 +44,13 @@ "type": "string" }, { - "name": "payload", - "doc": "The payload serialized into Avro bytes", + "name": "dataschema", + "doc": "The fully qualified name of the schema of the event payload. For example org.apache.fineract.avro.loan.v1.LoanAccountDataV1", + "type": "string" + }, + { + "name": "data", + "doc": "The payload data serialized into Avro bytes", "type": "bytes" } ] diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEvent.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEvent.java index 961d51cbc..16f98f283 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEvent.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEvent.java @@ -42,6 +42,9 @@ public class ExternalEvent extends AbstractPersistableCustom { @Column(name = "type", nullable = false) private String type; + @Column(name = "schema", nullable = false) + private String schema; + @Basic(fetch = FetchType.LAZY) @Column(name = "data", nullable = false) private byte[] data; @@ -64,8 +67,9 @@ public class ExternalEvent extends AbstractPersistableCustom { @Column(name = "business_date", nullable = false) private LocalDate businessDate; - public ExternalEvent(String type, byte[] data, String idempotencyKey) { + public ExternalEvent(String type, String schema, byte[] data, String idempotencyKey) { this.type = type; + this.schema = schema; this.data = data; this.idempotencyKey = idempotencyKey; this.createdAt = DateUtils.getOffsetDateTimeOfTenant(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java index 216836f6e..0f79a0895 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java @@ -25,6 +25,7 @@ import org.apache.fineract.infrastructure.event.external.repository.ExternalEven import org.apache.fineract.infrastructure.event.external.repository.domain.ExternalEvent; import org.apache.fineract.infrastructure.event.external.service.idempotency.ExternalEventIdempotencyKeyGenerator; import org.apache.fineract.infrastructure.event.external.service.serialization.BusinessEventSerializerFactory; +import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.BusinessEventSerializer; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -45,8 +46,10 @@ public class ExternalEventService { String eventType = event.getType(); String idempotencyKey = idempotencyKeyGenerator.generate(event); try { - byte[] data = serializerFactory.create(event).serialize(event); - ExternalEvent externalEvent = new ExternalEvent(eventType, data, idempotencyKey); + BusinessEventSerializer serializer = serializerFactory.create(event); + String schema = serializer.getSupportedSchema().getName(); + byte[] data = serializer.serialize(event); + ExternalEvent externalEvent = new ExternalEvent(eventType, schema, data, idempotencyKey); repository.save(externalEvent); } catch (IOException e) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializer.java index ceb59dd06..ddb2ce9f6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializer.java @@ -19,6 +19,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.serializer; import java.io.IOException; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; public interface BusinessEventSerializer { @@ -26,4 +27,6 @@ public interface BusinessEventSerializer { boolean canSerialize(BusinessEvent event); byte[] serialize(BusinessEvent rawEvent) throws IOException; + + Class getSupportedSchema(); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/client/ClientBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/client/ClientBusinessEventSerializer.java index aebd3b7a3..d53ae4452 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/client/ClientBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/client/ClientBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.client.v1.ClientDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.client.ClientBusinessEvent; @@ -52,4 +53,9 @@ public class ClientBusinessEventSerializer implements BusinessEventSerializer { ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return ClientDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/fixeddeposit/FixedDepositAccountBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/fixeddeposit/FixedDepositAccountBusinessEventSerializer.java index 970990a0b..7abfb69bb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/fixeddeposit/FixedDepositAccountBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/fixeddeposit/FixedDepositAccountBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.fixeddeposit.v1.FixedDepositAccountDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.deposit.FixedDepositAccountBusinessEvent; @@ -53,4 +54,9 @@ public class FixedDepositAccountBusinessEventSerializer implements BusinessEvent ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return FixedDepositAccountDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/group/GroupsBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/group/GroupsBusinessEventSerializer.java index 267443cb2..b2b4a18c2 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/group/GroupsBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/group/GroupsBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.generic.v1.CommandProcessingResultV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.group.GroupsBusinessEvent; @@ -48,4 +49,9 @@ public class GroupsBusinessEventSerializer implements BusinessEventSerializer { ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return CommandProcessingResultV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAdjustTransactionBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAdjustTransactionBusinessEventSerializer.java index 62af64ff7..db7ef7d20 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAdjustTransactionBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAdjustTransactionBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.loan.v1.LoanTransactionAdjustmentDataV1; import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; @@ -67,4 +68,9 @@ public class LoanAdjustTransactionBusinessEventSerializer implements BusinessEve ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return LoanTransactionAdjustmentDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanBusinessEventSerializer.java index 9077e40d2..8da6be97d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.loan.v1.LoanAccountDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.LoanBusinessEvent; @@ -52,4 +53,9 @@ public class LoanBusinessEventSerializer implements BusinessEventSerializer { ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return LoanAccountDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanChargeBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanChargeBusinessEventSerializer.java index ce8d52bb2..8a1bf90b4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanChargeBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanChargeBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.loan.v1.LoanChargeDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.charge.LoanChargeBusinessEvent; @@ -52,4 +53,9 @@ public class LoanChargeBusinessEventSerializer implements BusinessEventSerialize ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return LoanChargeDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanProductBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanProductBusinessEventSerializer.java index 12d73d604..645ec907d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanProductBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanProductBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.loan.v1.LoanProductDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.product.LoanProductBusinessEvent; @@ -52,4 +53,9 @@ public class LoanProductBusinessEventSerializer implements BusinessEventSerializ ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return LoanProductDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanTransactionBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanTransactionBusinessEventSerializer.java index ca932e978..8b4522fe7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanTransactionBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanTransactionBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent; @@ -52,4 +53,9 @@ public class LoanTransactionBusinessEventSerializer implements BusinessEventSeri ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return LoanTransactionDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/recurringdeposit/RecurringDepositAccountBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/recurringdeposit/RecurringDepositAccountBusinessEventSerializer.java index dd13a1aab..f01ef6adc 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/recurringdeposit/RecurringDepositAccountBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/recurringdeposit/RecurringDepositAccountBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.recurringdeposit.v1.RecurringDepositAccountDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.deposit.RecurringDepositAccountBusinessEvent; @@ -54,4 +55,9 @@ public class RecurringDepositAccountBusinessEventSerializer implements BusinessE ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return RecurringDepositAccountDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/savings/SavingsAccountBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/savings/SavingsAccountBusinessEventSerializer.java index 6952209c7..248b1d34e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/savings/SavingsAccountBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/savings/SavingsAccountBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.savings.v1.SavingsAccountDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.savings.SavingsAccountBusinessEvent; @@ -52,4 +53,9 @@ public class SavingsAccountBusinessEventSerializer implements BusinessEventSeria ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return SavingsAccountDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/savings/SavingsAccountTransactionBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/savings/SavingsAccountTransactionBusinessEventSerializer.java index 31537a688..c9c3fd1c5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/savings/SavingsAccountTransactionBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/savings/SavingsAccountTransactionBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.savings.v1.SavingsAccountTransactionDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.savings.transaction.SavingsAccountTransactionBusinessEvent; @@ -55,4 +56,9 @@ public class SavingsAccountTransactionBusinessEventSerializer implements Busines ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return SavingsAccountTransactionDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/share/ShareAccountBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/share/ShareAccountBusinessEventSerializer.java index 4632c66a7..9d14a5905 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/share/ShareAccountBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/share/ShareAccountBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.share.v1.ShareAccountDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.share.ShareAccountBusinessEvent; @@ -52,4 +53,9 @@ public class ShareAccountBusinessEventSerializer implements BusinessEventSeriali ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return ShareAccountDataV1.class; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/share/ShareProductDividentsCreateBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/share/ShareProductDividentsCreateBusinessEventSerializer.java index d847de340..dadf9c91c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/share/ShareProductDividentsCreateBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/share/ShareProductDividentsCreateBusinessEventSerializer.java @@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization. import java.io.IOException; import java.nio.ByteBuffer; import lombok.RequiredArgsConstructor; +import org.apache.avro.generic.GenericContainer; import org.apache.fineract.avro.share.v1.ShareProductDataV1; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.share.ShareProductDividentsCreateBusinessEvent; @@ -52,4 +53,9 @@ public class ShareProductDividentsCreateBusinessEventSerializer implements Busin ByteBuffer buffer = avroDto.toByteBuffer(); return byteBufferConverter.convert(buffer); } + + @Override + public Class getSupportedSchema() { + return ShareProductDataV1.class; + } } diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml index a1dc85eb5..73aee0f7c 100644 --- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml +++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml @@ -65,4 +65,5 @@ + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0046_external_event_table_schema_info.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0046_external_event_table_schema_info.xml new file mode 100644 index 000000000..0a10244d0 --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0046_external_event_table_schema_info.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventServiceTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventServiceTest.java index f560b80a0..b384fcce9 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventServiceTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventServiceTest.java @@ -29,6 +29,7 @@ import java.time.LocalDate; import java.time.ZoneId; import java.util.HashMap; import java.util.Map; +import org.apache.fineract.avro.loan.v1.LoanAccountDataV1; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant; import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; @@ -83,6 +84,7 @@ class ExternalEventServiceTest { given(idempotencyKeyGenerator.generate(event)).willReturn(""); given(serializerFactory.create(event)).willReturn(eventSerializer); + given(eventSerializer.getSupportedSchema()).will(invocation -> LoanAccountDataV1.class); given(eventSerializer.serialize(event)).willThrow(IOException.class); // when & then assertThatThrownBy(() -> underTest.postEvent(event)).isExactlyInstanceOf(RuntimeException.class); @@ -93,6 +95,7 @@ class ExternalEventServiceTest { // given ArgumentCaptor externalEventArgumentCaptor = ArgumentCaptor.forClass(ExternalEvent.class); + String eventSchema = "org.apache.fineract.avro.loan.v1.LoanAccountDataV1"; String eventType = "TestType"; String idempotencyKey = "key"; BusinessEvent event = mock(BusinessEvent.class); @@ -102,6 +105,7 @@ class ExternalEventServiceTest { given(event.getType()).willReturn(eventType); given(idempotencyKeyGenerator.generate(event)).willReturn(idempotencyKey); given(serializerFactory.create(event)).willReturn(eventSerializer); + given(eventSerializer.getSupportedSchema()).will(invocation -> LoanAccountDataV1.class); given(eventSerializer.serialize(event)).willReturn(data); // when underTest.postEvent(event); @@ -111,5 +115,6 @@ class ExternalEventServiceTest { assertThat(externalEvent.getIdempotencyKey()).isEqualTo(idempotencyKey); assertThat(externalEvent.getData()).isEqualTo(data); assertThat(externalEvent.getType()).isEqualTo(eventType); + assertThat(externalEvent.getSchema()).isEqualTo(eventSchema); } } diff --git a/integration-tests/build.gradle b/integration-tests/build.gradle index c256c2495..8e737ae6a 100644 --- a/integration-tests/build.gradle +++ b/integration-tests/build.gradle @@ -51,11 +51,11 @@ cargo { local { logLevel = 'low' - outputFile = file("$buildDir/cargo/output.log") + outputFile = file("$buildDir/cargo/integration-tests-output.log") installer { installConfiguration = configurations.tomcat downloadDir = file("$buildDir/download") - extractDir = file("$buildDir/tomcat") + extractDir = file("$buildDir/tomcat-integration-tests") } startStopTimeout = 240000 sharedClasspath = configurations.driver diff --git a/oauth2-tests/build.gradle b/oauth2-tests/build.gradle index 20220e460..678975a46 100644 --- a/oauth2-tests/build.gradle +++ b/oauth2-tests/build.gradle @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -description = 'Fineract Integration Tests for Oauth2' +description = 'Fineract Integration Tests for OAuth2' apply plugin: 'com.bmuschko.cargo' @@ -31,6 +31,15 @@ apply from: 'dependencies.gradle' // enable when all tests are migrated tasks.cucumber.onlyIf {false} +// Allow external drivers to be used for the tests without packaging it +// mainly due to license incompatibilities +configurations { + driver +} +dependencies { + driver 'mysql:mysql-connector-java:8.0.30' +} + cargo { containerId "tomcat9x" @@ -41,21 +50,29 @@ cargo { } local { - // logLevel = 'medium' - // outputFile = file('build/output.log') + logLevel = 'low' + outputFile = file("$buildDir/cargo/oauth2-tests-output.log") installer { installConfiguration = configurations.tomcat downloadDir = file("$buildDir/download") - extractDir = file("$buildDir/tomcat") + extractDir = file("$buildDir/tomcat-oauth2-tests") } startStopTimeout = 240000 + sharedClasspath = configurations.driver containerProperties { def jvmArgs = '--add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED -Dfineract.security.basicauth.enabled=false -Dfineract.security.oauth.enabled=true -Dfineract.security.2fa.enabled=false ' - if (project.hasProperty('dbType') && 'postgresql'.equalsIgnoreCase(dbType)) { - jvmArgs += '-Dspring.datasource.hikari.driverClassName=org.postgresql.Driver -Dspring.datasource.hikari.jdbcUrl=jdbc:postgresql://localhost:5432/fineract_tenants -Dspring.datasource.hikari.username=root -Dspring.datasource.hikari.password=postgres -Dfineract.tenant.host=localhost -Dfineract.tenant.port=5432 -Dfineract.tenant.username=root -Dfineract.tenant.password=postgres' + if (project.hasProperty('dbType')) { + if ('postgresql'.equalsIgnoreCase(dbType)) { + jvmArgs += '-Dspring.datasource.hikari.driverClassName=org.postgresql.Driver -Dspring.datasource.hikari.jdbcUrl=jdbc:postgresql://localhost:5432/fineract_tenants -Dspring.datasource.hikari.username=root -Dspring.datasource.hikari.password=postgres -Dfineract.tenant.host=localhost -Dfineract.tenant.port=5432 -Dfineract.tenant.username=root -Dfineract.tenant.password=postgres' + } else if ('mysql'.equalsIgnoreCase(dbType)) { + jvmArgs += '-Dspring.datasource.hikari.driverClassName=com.mysql.cj.jdbc.Driver -Dspring.datasource.hikari.jdbcUrl=jdbc:mysql://localhost:3306/fineract_tenants -Dspring.datasource.hikari.username=root -Dspring.datasource.hikari.password=mysql -Dfineract.tenant.host=localhost -Dfineract.tenant.port=3306 -Dfineract.tenant.username=root -Dfineract.tenant.password=mysql' + } else { + throw new GradleException('Provided dbType is not supported') + } } else { jvmArgs += '-Dspring.datasource.hikari.driverClassName=org.mariadb.jdbc.Driver -Dspring.datasource.hikari.jdbcUrl=jdbc:mariadb://localhost:3306/fineract_tenants -Dspring.datasource.hikari.username=root -Dspring.datasource.hikari.password=mysql -Dfineract.tenant.host=localhost -Dfineract.tenant.port=3306 -Dfineract.tenant.username=root -Dfineract.tenant.password=mysql' } + jvmArgs += ' -Dspring.profiles.active=test -Dfineract.events.external.enabled=true' property 'cargo.start.jvmargs', jvmArgs property 'cargo.tomcat.connector.keystoreFile', file("$rootDir/fineract-provider/src/main/resources/keystore.jks") property 'cargo.tomcat.connector.keystorePass', 'openmf' @@ -73,7 +90,7 @@ cargoStartLocal.dependsOn ':fineract-war:war' cargoStartLocal.mustRunAfter 'testClasses' test { - dependsOn (cargoStartLocal) + dependsOn(cargoStartLocal) finalizedBy cargoStopLocal } diff --git a/twofactor-tests/build.gradle b/twofactor-tests/build.gradle index 464d73c22..22ee0e3b2 100644 --- a/twofactor-tests/build.gradle +++ b/twofactor-tests/build.gradle @@ -31,6 +31,15 @@ apply from: 'dependencies.gradle' // enable when all tests are migrated tasks.cucumber.onlyIf {false} +// Allow external drivers to be used for the tests without packaging it +// mainly due to license incompatibilities +configurations { + driver +} +dependencies { + driver 'mysql:mysql-connector-java:8.0.30' +} + cargo { containerId "tomcat9x" @@ -41,21 +50,29 @@ cargo { } local { - // logLevel = 'medium' - // outputFile = file('build/output.log') + logLevel = 'low' + outputFile = file("$buildDir/cargo/twofactor-tests-output.log") installer { installConfiguration = configurations.tomcat downloadDir = file("$buildDir/download") - extractDir = file("$buildDir/tomcat") + extractDir = file("$buildDir/tomcat-twofactor-tests") } startStopTimeout = 240000 + sharedClasspath = configurations.driver containerProperties { def jvmArgs = '--add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED -Dfineract.security.basicauth.enabled=true -Dfineract.security.oauth.enabled=false -Dfineract.security.2fa.enabled=true ' - if (project.hasProperty('dbType') && 'postgresql'.equalsIgnoreCase(dbType)) { - jvmArgs += '-Dspring.datasource.hikari.driverClassName=org.postgresql.Driver -Dspring.datasource.hikari.jdbcUrl=jdbc:postgresql://localhost:5432/fineract_tenants -Dspring.datasource.hikari.username=root -Dspring.datasource.hikari.password=postgres -Dfineract.tenant.host=localhost -Dfineract.tenant.port=5432 -Dfineract.tenant.username=root -Dfineract.tenant.password=postgres' + if (project.hasProperty('dbType')) { + if ('postgresql'.equalsIgnoreCase(dbType)) { + jvmArgs += '-Dspring.datasource.hikari.driverClassName=org.postgresql.Driver -Dspring.datasource.hikari.jdbcUrl=jdbc:postgresql://localhost:5432/fineract_tenants -Dspring.datasource.hikari.username=root -Dspring.datasource.hikari.password=postgres -Dfineract.tenant.host=localhost -Dfineract.tenant.port=5432 -Dfineract.tenant.username=root -Dfineract.tenant.password=postgres' + } else if ('mysql'.equalsIgnoreCase(dbType)) { + jvmArgs += '-Dspring.datasource.hikari.driverClassName=com.mysql.cj.jdbc.Driver -Dspring.datasource.hikari.jdbcUrl=jdbc:mysql://localhost:3306/fineract_tenants -Dspring.datasource.hikari.username=root -Dspring.datasource.hikari.password=mysql -Dfineract.tenant.host=localhost -Dfineract.tenant.port=3306 -Dfineract.tenant.username=root -Dfineract.tenant.password=mysql' + } else { + throw new GradleException('Provided dbType is not supported') + } } else { jvmArgs += '-Dspring.datasource.hikari.driverClassName=org.mariadb.jdbc.Driver -Dspring.datasource.hikari.jdbcUrl=jdbc:mariadb://localhost:3306/fineract_tenants -Dspring.datasource.hikari.username=root -Dspring.datasource.hikari.password=mysql -Dfineract.tenant.host=localhost -Dfineract.tenant.port=3306 -Dfineract.tenant.username=root -Dfineract.tenant.password=mysql' } + jvmArgs += ' -Dspring.profiles.active=test -Dfineract.events.external.enabled=true' property 'cargo.start.jvmargs', jvmArgs property 'cargo.tomcat.connector.keystoreFile', file("$rootDir/fineract-provider/src/main/resources/keystore.jks") property 'cargo.tomcat.connector.keystorePass', 'openmf' @@ -73,7 +90,7 @@ cargoStartLocal.dependsOn ':fineract-war:war' cargoStartLocal.mustRunAfter 'testClasses' test { - dependsOn (cargoStartLocal) + dependsOn(cargoStartLocal) finalizedBy cargoStopLocal }