FINERACT-1694: Storing event schema along with external events

This commit is contained in:
Arnold Galovics
2022-09-07 14:45:51 +02:00
committed by Arnold Gálovics
parent 72e78df0fc
commit 90896a6467
26 changed files with 198 additions and 30 deletions
+3 -3
View File
@@ -58,13 +58,13 @@ jobs:
sudo apt-get install ghostscript graphviz -y sudo apt-get install ghostscript graphviz -y
- name: Basic Auth Build & Test - 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 - 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 - 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 - name: Archive test results
if: always() if: always()
+3 -3
View File
@@ -58,13 +58,13 @@ jobs:
sudo apt-get install ghostscript graphviz -y sudo apt-get install ghostscript graphviz -y
- name: Basic Auth Build & Test - 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 - 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 - 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 - name: Archive test results
if: always() if: always()
+3 -3
View File
@@ -59,13 +59,13 @@ jobs:
sudo apt-get install ghostscript graphviz -y sudo apt-get install ghostscript graphviz -y
- name: Basic Auth Build & Test - 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 - 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 - 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 - name: Archive test results
if: always() if: always()
@@ -15,7 +15,7 @@
}, },
{ {
"name": "type", "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" "type": "string"
}, },
{ {
@@ -44,8 +44,13 @@
"type": "string" "type": "string"
}, },
{ {
"name": "payload", "name": "dataschema",
"doc": "The payload serialized into Avro bytes", "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" "type": "bytes"
} }
] ]
@@ -42,6 +42,9 @@ public class ExternalEvent extends AbstractPersistableCustom {
@Column(name = "type", nullable = false) @Column(name = "type", nullable = false)
private String type; private String type;
@Column(name = "schema", nullable = false)
private String schema;
@Basic(fetch = FetchType.LAZY) @Basic(fetch = FetchType.LAZY)
@Column(name = "data", nullable = false) @Column(name = "data", nullable = false)
private byte[] data; private byte[] data;
@@ -64,8 +67,9 @@ public class ExternalEvent extends AbstractPersistableCustom {
@Column(name = "business_date", nullable = false) @Column(name = "business_date", nullable = false)
private LocalDate businessDate; 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.type = type;
this.schema = schema;
this.data = data; this.data = data;
this.idempotencyKey = idempotencyKey; this.idempotencyKey = idempotencyKey;
this.createdAt = DateUtils.getOffsetDateTimeOfTenant(); this.createdAt = DateUtils.getOffsetDateTimeOfTenant();
@@ -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.repository.domain.ExternalEvent;
import org.apache.fineract.infrastructure.event.external.service.idempotency.ExternalEventIdempotencyKeyGenerator; 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.BusinessEventSerializerFactory;
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.BusinessEventSerializer;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -45,8 +46,10 @@ public class ExternalEventService {
String eventType = event.getType(); String eventType = event.getType();
String idempotencyKey = idempotencyKeyGenerator.generate(event); String idempotencyKey = idempotencyKeyGenerator.generate(event);
try { try {
byte[] data = serializerFactory.create(event).serialize(event); BusinessEventSerializer serializer = serializerFactory.create(event);
ExternalEvent externalEvent = new ExternalEvent(eventType, data, idempotencyKey); String schema = serializer.getSupportedSchema().getName();
byte[] data = serializer.serialize(event);
ExternalEvent externalEvent = new ExternalEvent(eventType, schema, data, idempotencyKey);
repository.save(externalEvent); repository.save(externalEvent);
} catch (IOException e) { } catch (IOException e) {
@@ -19,6 +19,7 @@
package org.apache.fineract.infrastructure.event.external.service.serialization.serializer; package org.apache.fineract.infrastructure.event.external.service.serialization.serializer;
import java.io.IOException; import java.io.IOException;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
public interface BusinessEventSerializer { public interface BusinessEventSerializer {
@@ -26,4 +27,6 @@ public interface BusinessEventSerializer {
<T> boolean canSerialize(BusinessEvent<T> event); <T> boolean canSerialize(BusinessEvent<T> event);
<T> byte[] serialize(BusinessEvent<T> rawEvent) throws IOException; <T> byte[] serialize(BusinessEvent<T> rawEvent) throws IOException;
Class<? extends GenericContainer> getSupportedSchema();
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.client.v1.ClientDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.client.ClientBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.client.ClientBusinessEvent;
@@ -52,4 +53,9 @@ public class ClientBusinessEventSerializer implements BusinessEventSerializer {
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return ClientDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.fixeddeposit.v1.FixedDepositAccountDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.deposit.FixedDepositAccountBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.deposit.FixedDepositAccountBusinessEvent;
@@ -53,4 +54,9 @@ public class FixedDepositAccountBusinessEventSerializer implements BusinessEvent
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return FixedDepositAccountDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.generic.v1.CommandProcessingResultV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.group.GroupsBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.group.GroupsBusinessEvent;
@@ -48,4 +49,9 @@ public class GroupsBusinessEventSerializer implements BusinessEventSerializer {
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return CommandProcessingResultV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.loan.v1.LoanTransactionAdjustmentDataV1; import org.apache.fineract.avro.loan.v1.LoanTransactionAdjustmentDataV1;
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1; 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.BusinessEvent;
@@ -67,4 +68,9 @@ public class LoanAdjustTransactionBusinessEventSerializer implements BusinessEve
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return LoanTransactionAdjustmentDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.loan.v1.LoanAccountDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.LoanBusinessEvent;
@@ -52,4 +53,9 @@ public class LoanBusinessEventSerializer implements BusinessEventSerializer {
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return LoanAccountDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.loan.v1.LoanChargeDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.loan.charge.LoanChargeBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.charge.LoanChargeBusinessEvent;
@@ -52,4 +53,9 @@ public class LoanChargeBusinessEventSerializer implements BusinessEventSerialize
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return LoanChargeDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.loan.v1.LoanProductDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.loan.product.LoanProductBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.product.LoanProductBusinessEvent;
@@ -52,4 +53,9 @@ public class LoanProductBusinessEventSerializer implements BusinessEventSerializ
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return LoanProductDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent;
@@ -52,4 +53,9 @@ public class LoanTransactionBusinessEventSerializer implements BusinessEventSeri
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return LoanTransactionDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.recurringdeposit.v1.RecurringDepositAccountDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.deposit.RecurringDepositAccountBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.deposit.RecurringDepositAccountBusinessEvent;
@@ -54,4 +55,9 @@ public class RecurringDepositAccountBusinessEventSerializer implements BusinessE
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return RecurringDepositAccountDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.savings.v1.SavingsAccountDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.savings.SavingsAccountBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.savings.SavingsAccountBusinessEvent;
@@ -52,4 +53,9 @@ public class SavingsAccountBusinessEventSerializer implements BusinessEventSeria
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return SavingsAccountDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.savings.v1.SavingsAccountTransactionDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.savings.transaction.SavingsAccountTransactionBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.savings.transaction.SavingsAccountTransactionBusinessEvent;
@@ -55,4 +56,9 @@ public class SavingsAccountTransactionBusinessEventSerializer implements Busines
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return SavingsAccountTransactionDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.share.v1.ShareAccountDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.share.ShareAccountBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.share.ShareAccountBusinessEvent;
@@ -52,4 +53,9 @@ public class ShareAccountBusinessEventSerializer implements BusinessEventSeriali
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return ShareAccountDataV1.class;
}
} }
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.avro.generic.GenericContainer;
import org.apache.fineract.avro.share.v1.ShareProductDataV1; 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.BusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.share.ShareProductDividentsCreateBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.share.ShareProductDividentsCreateBusinessEvent;
@@ -52,4 +53,9 @@ public class ShareProductDividentsCreateBusinessEventSerializer implements Busin
ByteBuffer buffer = avroDto.toByteBuffer(); ByteBuffer buffer = avroDto.toByteBuffer();
return byteBufferConverter.convert(buffer); return byteBufferConverter.convert(buffer);
} }
@Override
public Class<? extends GenericContainer> getSupportedSchema() {
return ShareProductDataV1.class;
}
} }
@@ -65,4 +65,5 @@
<include file="parts/0043_add_external_event_table.xml" relativeToChangelogFile="true"/> <include file="parts/0043_add_external_event_table.xml" relativeToChangelogFile="true"/>
<include file="parts/0044_table_report_query_fix.xml" relativeToChangelogFile="true"/> <include file="parts/0044_table_report_query_fix.xml" relativeToChangelogFile="true"/>
<include file="parts/0045_external_event_table_data_binary.xml" relativeToChangelogFile="true"/> <include file="parts/0045_external_event_table_data_binary.xml" relativeToChangelogFile="true"/>
<include file="parts/0046_external_event_table_schema_info.xml" relativeToChangelogFile="true"/>
</databaseChangeLog> </databaseChangeLog>
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
<changeSet author="fineract" id="1">
<delete tableName="m_external_event"/>
</changeSet>
<changeSet author="fineract" id="2">
<addColumn tableName="m_external_event">
<column name="schema" type="VARCHAR(300)">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
</databaseChangeLog>
@@ -29,6 +29,7 @@ import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; 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.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant; import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
@@ -83,6 +84,7 @@ class ExternalEventServiceTest {
given(idempotencyKeyGenerator.generate(event)).willReturn(""); given(idempotencyKeyGenerator.generate(event)).willReturn("");
given(serializerFactory.create(event)).willReturn(eventSerializer); given(serializerFactory.create(event)).willReturn(eventSerializer);
given(eventSerializer.getSupportedSchema()).will(invocation -> LoanAccountDataV1.class);
given(eventSerializer.serialize(event)).willThrow(IOException.class); given(eventSerializer.serialize(event)).willThrow(IOException.class);
// when & then // when & then
assertThatThrownBy(() -> underTest.postEvent(event)).isExactlyInstanceOf(RuntimeException.class); assertThatThrownBy(() -> underTest.postEvent(event)).isExactlyInstanceOf(RuntimeException.class);
@@ -93,6 +95,7 @@ class ExternalEventServiceTest {
// given // given
ArgumentCaptor<ExternalEvent> externalEventArgumentCaptor = ArgumentCaptor.forClass(ExternalEvent.class); ArgumentCaptor<ExternalEvent> externalEventArgumentCaptor = ArgumentCaptor.forClass(ExternalEvent.class);
String eventSchema = "org.apache.fineract.avro.loan.v1.LoanAccountDataV1";
String eventType = "TestType"; String eventType = "TestType";
String idempotencyKey = "key"; String idempotencyKey = "key";
BusinessEvent event = mock(BusinessEvent.class); BusinessEvent event = mock(BusinessEvent.class);
@@ -102,6 +105,7 @@ class ExternalEventServiceTest {
given(event.getType()).willReturn(eventType); given(event.getType()).willReturn(eventType);
given(idempotencyKeyGenerator.generate(event)).willReturn(idempotencyKey); given(idempotencyKeyGenerator.generate(event)).willReturn(idempotencyKey);
given(serializerFactory.create(event)).willReturn(eventSerializer); given(serializerFactory.create(event)).willReturn(eventSerializer);
given(eventSerializer.getSupportedSchema()).will(invocation -> LoanAccountDataV1.class);
given(eventSerializer.serialize(event)).willReturn(data); given(eventSerializer.serialize(event)).willReturn(data);
// when // when
underTest.postEvent(event); underTest.postEvent(event);
@@ -111,5 +115,6 @@ class ExternalEventServiceTest {
assertThat(externalEvent.getIdempotencyKey()).isEqualTo(idempotencyKey); assertThat(externalEvent.getIdempotencyKey()).isEqualTo(idempotencyKey);
assertThat(externalEvent.getData()).isEqualTo(data); assertThat(externalEvent.getData()).isEqualTo(data);
assertThat(externalEvent.getType()).isEqualTo(eventType); assertThat(externalEvent.getType()).isEqualTo(eventType);
assertThat(externalEvent.getSchema()).isEqualTo(eventSchema);
} }
} }
+2 -2
View File
@@ -51,11 +51,11 @@ cargo {
local { local {
logLevel = 'low' logLevel = 'low'
outputFile = file("$buildDir/cargo/output.log") outputFile = file("$buildDir/cargo/integration-tests-output.log")
installer { installer {
installConfiguration = configurations.tomcat installConfiguration = configurations.tomcat
downloadDir = file("$buildDir/download") downloadDir = file("$buildDir/download")
extractDir = file("$buildDir/tomcat") extractDir = file("$buildDir/tomcat-integration-tests")
} }
startStopTimeout = 240000 startStopTimeout = 240000
sharedClasspath = configurations.driver sharedClasspath = configurations.driver
+24 -7
View File
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
description = 'Fineract Integration Tests for Oauth2' description = 'Fineract Integration Tests for OAuth2'
apply plugin: 'com.bmuschko.cargo' apply plugin: 'com.bmuschko.cargo'
@@ -31,6 +31,15 @@ apply from: 'dependencies.gradle'
// enable when all tests are migrated // enable when all tests are migrated
tasks.cucumber.onlyIf {false} 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 { cargo {
containerId "tomcat9x" containerId "tomcat9x"
@@ -41,21 +50,29 @@ cargo {
} }
local { local {
// logLevel = 'medium' logLevel = 'low'
// outputFile = file('build/output.log') outputFile = file("$buildDir/cargo/oauth2-tests-output.log")
installer { installer {
installConfiguration = configurations.tomcat installConfiguration = configurations.tomcat
downloadDir = file("$buildDir/download") downloadDir = file("$buildDir/download")
extractDir = file("$buildDir/tomcat") extractDir = file("$buildDir/tomcat-oauth2-tests")
} }
startStopTimeout = 240000 startStopTimeout = 240000
sharedClasspath = configurations.driver
containerProperties { 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 ' 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)) { if (project.hasProperty('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 ('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 { } 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.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.start.jvmargs', jvmArgs
property 'cargo.tomcat.connector.keystoreFile', file("$rootDir/fineract-provider/src/main/resources/keystore.jks") property 'cargo.tomcat.connector.keystoreFile', file("$rootDir/fineract-provider/src/main/resources/keystore.jks")
property 'cargo.tomcat.connector.keystorePass', 'openmf' property 'cargo.tomcat.connector.keystorePass', 'openmf'
@@ -73,7 +90,7 @@ cargoStartLocal.dependsOn ':fineract-war:war'
cargoStartLocal.mustRunAfter 'testClasses' cargoStartLocal.mustRunAfter 'testClasses'
test { test {
dependsOn (cargoStartLocal) dependsOn(cargoStartLocal)
finalizedBy cargoStopLocal finalizedBy cargoStopLocal
} }
+23 -6
View File
@@ -31,6 +31,15 @@ apply from: 'dependencies.gradle'
// enable when all tests are migrated // enable when all tests are migrated
tasks.cucumber.onlyIf {false} 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 { cargo {
containerId "tomcat9x" containerId "tomcat9x"
@@ -41,21 +50,29 @@ cargo {
} }
local { local {
// logLevel = 'medium' logLevel = 'low'
// outputFile = file('build/output.log') outputFile = file("$buildDir/cargo/twofactor-tests-output.log")
installer { installer {
installConfiguration = configurations.tomcat installConfiguration = configurations.tomcat
downloadDir = file("$buildDir/download") downloadDir = file("$buildDir/download")
extractDir = file("$buildDir/tomcat") extractDir = file("$buildDir/tomcat-twofactor-tests")
} }
startStopTimeout = 240000 startStopTimeout = 240000
sharedClasspath = configurations.driver
containerProperties { 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 ' 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)) { if (project.hasProperty('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 ('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 { } 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.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.start.jvmargs', jvmArgs
property 'cargo.tomcat.connector.keystoreFile', file("$rootDir/fineract-provider/src/main/resources/keystore.jks") property 'cargo.tomcat.connector.keystoreFile', file("$rootDir/fineract-provider/src/main/resources/keystore.jks")
property 'cargo.tomcat.connector.keystorePass', 'openmf' property 'cargo.tomcat.connector.keystorePass', 'openmf'
@@ -73,7 +90,7 @@ cargoStartLocal.dependsOn ':fineract-war:war'
cargoStartLocal.mustRunAfter 'testClasses' cargoStartLocal.mustRunAfter 'testClasses'
test { test {
dependsOn (cargoStartLocal) dependsOn(cargoStartLocal)
finalizedBy cargoStopLocal finalizedBy cargoStopLocal
} }