FINERACT-1724: Further upgrades
This commit is contained in:
committed by
Arnold Gálovics
parent
bc4b707646
commit
abb5d4abb5
@@ -28,6 +28,7 @@ dependencies {
|
||||
implementation(
|
||||
'org.springframework.boot:spring-boot-starter-web',
|
||||
'org.springframework.boot:spring-boot-starter-security',
|
||||
'org.springframework.boot:spring-boot-starter-validation',
|
||||
'jakarta.ws.rs:jakarta.ws.rs-api',
|
||||
'org.glassfish.jersey.media:jersey-media-multipart',
|
||||
|
||||
|
||||
@@ -155,10 +155,10 @@ dependencies {
|
||||
driver 'mysql:mysql-connector-java:8.0.32'
|
||||
}
|
||||
|
||||
//URLClassLoader loader = GroovyObject.class.classLoader
|
||||
//configurations.driver.each {File file ->
|
||||
// loader.addURL(file.toURL())
|
||||
//}
|
||||
URLClassLoader loader = GroovyObject.class.classLoader
|
||||
configurations.driver.each {File file ->
|
||||
loader.addURL(file.toURL())
|
||||
}
|
||||
|
||||
task createDB {
|
||||
description= "Creates the MariaDB Database. Needs database name to be passed (like: -PdbName=someDBname)"
|
||||
|
||||
+6
-5
@@ -37,6 +37,7 @@ import org.springframework.batch.core.annotation.OnSkipInProcess;
|
||||
import org.springframework.batch.core.annotation.OnSkipInRead;
|
||||
import org.springframework.batch.core.annotation.OnSkipInWrite;
|
||||
import org.springframework.batch.core.annotation.OnWriteError;
|
||||
import org.springframework.batch.item.Chunk;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
@@ -79,25 +80,25 @@ public abstract class AbstractLoanItemListener {
|
||||
}
|
||||
|
||||
@OnWriteError
|
||||
public void onWriteError(Exception e, @NotNull List<? extends Loan> items) {
|
||||
List<Long> loanIds = items.stream().map(AbstractPersistableCustom::getId).toList();
|
||||
public void onWriteError(Exception e, @NotNull Chunk<? extends Loan> items) {
|
||||
List<Long> loanIds = items.getItems().stream().map(AbstractPersistableCustom::getId).toList();
|
||||
log.warn("Error was triggered during writing of Loans (ids={}) due to: {}", loanIds, ThrowableSerialization.serialize(e));
|
||||
|
||||
updateAccountLockWithError(loanIds, "Loan (id: %d) writing is failed", e);
|
||||
}
|
||||
|
||||
@OnSkipInRead
|
||||
public void onSkipInRead(@NotNull Exception e) {
|
||||
public void onSkipInRead(@NotNull Throwable e) {
|
||||
log.warn("Skipping was triggered during read!");
|
||||
}
|
||||
|
||||
@OnSkipInProcess
|
||||
public void onSkipInProcess(@NotNull Loan item, @NotNull Exception e) {
|
||||
public void onSkipInProcess(@NotNull Loan item, @NotNull Throwable e) {
|
||||
log.warn("Skipping was triggered during processing of Loan (id={})", item.getId());
|
||||
}
|
||||
|
||||
@OnSkipInWrite
|
||||
public void onSkipInWrite(@NotNull Loan item, @NotNull Exception e) {
|
||||
public void onSkipInWrite(@NotNull Loan item, @NotNull Throwable e) {
|
||||
log.warn("Skipping was triggered during writing of Loan (id={})", item.getId());
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -22,14 +22,13 @@ import org.apache.fineract.infrastructure.cache.service.RuntimeDelegatingCacheMa
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CachingConfigurer;
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class PlatformCacheConfiguration extends CachingConfigurerSupport implements CachingConfigurer {
|
||||
public class PlatformCacheConfiguration implements CachingConfigurer {
|
||||
|
||||
@Autowired
|
||||
private RuntimeDelegatingCacheManager delegatingCacheManager;
|
||||
|
||||
+11
-5
@@ -38,7 +38,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
@@ -57,7 +57,7 @@ import org.springframework.security.web.context.SecurityContextHolderFilter;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty("fineract.security.oauth.enabled")
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@EnableMethodSecurity
|
||||
public class OAuth2SecurityConfig {
|
||||
|
||||
@Autowired
|
||||
@@ -76,9 +76,8 @@ public class OAuth2SecurityConfig {
|
||||
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
public SecurityFilterChain authorizationFilterChain(HttpSecurity http) throws Exception {
|
||||
http //
|
||||
.csrf((csrf) -> csrf.disable()) // NOSONAR only creating a service that is used by non-browser clients
|
||||
.securityMatcher("/api/**").authorizeHttpRequests((auth) -> {
|
||||
auth
|
||||
.requestMatchers(HttpMethod.OPTIONS, "/api/**").permitAll() //
|
||||
@@ -90,7 +89,14 @@ public class OAuth2SecurityConfig {
|
||||
.requestMatchers(HttpMethod.POST, "/api/*/twofactor/validate").fullyAuthenticated() //
|
||||
.requestMatchers("/api/*/twofactor").fullyAuthenticated() //
|
||||
.requestMatchers("/api/**").access(allOf(fullyAuthenticated(), hasAuthority("TWOFACTOR_AUTHENTICATED"), selfServiceUserAuthManager())); //
|
||||
}) //
|
||||
});
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain FilterChain(HttpSecurity http) throws Exception {
|
||||
http //
|
||||
.csrf((csrf) -> csrf.disable()) // NOSONAR only creating a service that is used by non-browser clients
|
||||
.exceptionHandling((ehc) -> ehc.authenticationEntryPoint(new OAuth2ExceptionEntryPoint()))
|
||||
.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(authenticationConverter()))
|
||||
.authenticationEntryPoint(new OAuth2ExceptionEntryPoint())) //
|
||||
|
||||
+13
-7
@@ -40,7 +40,7 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.ProviderManager;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
@@ -53,7 +53,7 @@ import org.springframework.security.web.context.SecurityContextHolderFilter;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty("fineract.security.basicauth.enabled")
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@EnableMethodSecurity
|
||||
public class SecurityConfig {
|
||||
|
||||
@Autowired
|
||||
@@ -78,9 +78,8 @@ public class SecurityConfig {
|
||||
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
public SecurityFilterChain authorizationFilterChain(HttpSecurity http) throws Exception {
|
||||
http //
|
||||
.csrf((csrf) -> csrf.disable()) // NOSONAR only creating a service that is used by non-browser clients
|
||||
.securityMatcher("/api/**").authorizeHttpRequests((auth) -> {
|
||||
auth
|
||||
.requestMatchers(HttpMethod.OPTIONS, "/api/**").permitAll() //
|
||||
@@ -94,13 +93,20 @@ public class SecurityConfig {
|
||||
.requestMatchers("/api/*/twofactor").fullyAuthenticated() //
|
||||
.requestMatchers("/api/**").access(allOf(fullyAuthenticated(), hasAuthority("TWOFACTOR_AUTHENTICATED"))); //
|
||||
}) //
|
||||
.httpBasic((httpBasic) -> httpBasic.authenticationEntryPoint(basicAuthenticationEntryPoint())) //
|
||||
.httpBasic((httpBasic) -> httpBasic.authenticationEntryPoint(basicAuthenticationEntryPoint())); //
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http //
|
||||
.csrf((csrf) -> csrf.disable()) // NOSONAR only creating a service that is used by non-browser clients
|
||||
.sessionManagement((smc) -> smc.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) //
|
||||
.addFilterAfter(fineractInstanceModeApiFilter, SecurityContextHolderFilter.class) //
|
||||
.addFilterAfter(tenantAwareBasicAuthenticationFilter(), FineractInstanceModeApiFilter.class) //
|
||||
.addFilterAfter(twoFactorAuthenticationFilter, BasicAuthenticationFilter.class) //
|
||||
.addFilterAfter(loanCOBApiFilter, InsecureTwoFactorAuthenticationFilter.class)
|
||||
.addFilterBefore(idempotencyStoreFilter, ExceptionTranslationFilter.class);
|
||||
.addFilterAfter(loanCOBApiFilter, InsecureTwoFactorAuthenticationFilter.class) //
|
||||
.addFilterBefore(idempotencyStoreFilter, ExceptionTranslationFilter.class); //
|
||||
|
||||
if (serverProperties.getSsl().isEnabled()) {
|
||||
http.requiresChannel(channel -> channel.requestMatchers("/api/**").requiresSecure());
|
||||
|
||||
+4
-3
@@ -20,8 +20,8 @@ package org.apache.fineract.infrastructure.core.diagnostics.performance.sampling
|
||||
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.infrastructure.core.diagnostics.performance.sampling.core.SamplingConfiguration;
|
||||
@@ -54,8 +54,9 @@ public class SamplingScheduler implements InitializingBean {
|
||||
log.warn("Reset period for sampling cannot be smaller than 10 seconds, setting back the minimum 10");
|
||||
resetPeriodInSec = 10;
|
||||
}
|
||||
PeriodicTrigger trigger = new PeriodicTrigger(resetPeriodInSec, TimeUnit.SECONDS);
|
||||
trigger.setInitialDelay(resetPeriodInSec);
|
||||
Duration resetPeriodInSecDuration = Duration.ofSeconds(resetPeriodInSec);
|
||||
PeriodicTrigger trigger = new PeriodicTrigger(resetPeriodInSecDuration);
|
||||
trigger.setInitialDelay(resetPeriodInSecDuration);
|
||||
taskScheduler.schedule(this::printAndResetPeriodically, trigger);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ import org.springframework.stereotype.Service;
|
||||
* The {@link RoutingDataSourceService} is responsible for returning the appropriate {@link DataSource} for the tenant
|
||||
* of this request.
|
||||
*/
|
||||
@Service(value = "routingDataSource")
|
||||
@Service(value = "dataSource")
|
||||
@Primary
|
||||
public class RoutingDataSource extends AbstractDataSource {
|
||||
|
||||
|
||||
+21
-6
@@ -25,8 +25,11 @@ import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourc
|
||||
import org.springframework.batch.core.configuration.JobRegistry;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor;
|
||||
import org.springframework.batch.core.explore.JobExplorer;
|
||||
import org.springframework.batch.core.explore.support.JobExplorerFactoryBean;
|
||||
import org.springframework.batch.core.launch.support.TaskExecutorJobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
|
||||
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
|
||||
@@ -34,7 +37,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableBatchProcessing
|
||||
public class ScheduledJobRunnerConfig {
|
||||
|
||||
@@ -49,19 +52,31 @@ public class ScheduledJobRunnerConfig {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JobRepositoryFactoryBean jobRepositoryFactoryBean(RoutingDataSource routingDataSource,
|
||||
PlatformTransactionManager transactionManager) throws Exception {
|
||||
public Jackson2ExecutionContextStringSerializer executionContextSerializer() {
|
||||
return new Jackson2ExecutionContextStringSerializer();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JobRepository jobRepository(RoutingDataSource routingDataSource,
|
||||
PlatformTransactionManager transactionManager) throws Exception {
|
||||
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
|
||||
factory.setDataSource(routingDataSource);
|
||||
factory.setTransactionManager(transactionManager);
|
||||
factory.setIsolationLevelForCreate("ISOLATION_READ_COMMITTED");
|
||||
factory.setSerializer(executionContextSerializer());
|
||||
factory.afterPropertiesSet();
|
||||
return factory;
|
||||
return factory.getObject();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JobRepository jobRepository(JobRepositoryFactoryBean factory) throws Exception {
|
||||
return factory.getObject();
|
||||
public JobExplorer jobExplorer(RoutingDataSource routingDataSource,
|
||||
PlatformTransactionManager transactionManager) throws Exception {
|
||||
JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
|
||||
jobExplorerFactoryBean.setDataSource(routingDataSource);
|
||||
jobExplorerFactoryBean.setTransactionManager(transactionManager);
|
||||
jobExplorerFactoryBean.setSerializer(executionContextSerializer());
|
||||
jobExplorerFactoryBean.afterPropertiesSet();
|
||||
return jobExplorerFactoryBean.getObject();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 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.jobs.config;
|
||||
|
||||
import org.springframework.batch.core.configuration.support.DefaultBatchConfiguration;
|
||||
import org.springframework.batch.core.repository.ExecutionContextSerializer;
|
||||
import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
|
||||
|
||||
|
||||
//@Configuration(proxyBeanMethods = false)
|
||||
public class FineractBatchConfiguration extends DefaultBatchConfiguration {
|
||||
@Override
|
||||
protected ExecutionContextSerializer getExecutionContextSerializer() {
|
||||
return new Jackson2ExecutionContextStringSerializer();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -60,7 +60,7 @@ public interface CalendarInstanceRepository extends JpaRepository<CalendarInstan
|
||||
* EntityType = 3 is for loan
|
||||
*/
|
||||
|
||||
@Query("SELECT COUNT(ci.id) FROM CalendarInstance ci, Loan ln WHERE ln.id = ci.entityId AND ci.entityTypeId = 3 AND ci.calendar.id = :calendarId AND ln.loanStatus IN :loanStatuses ")
|
||||
@Query("SELECT COUNT(ci.id) FROM CalendarInstance ci, Loan loan WHERE loan.id = ci.entityId AND ci.entityTypeId = 3 AND ci.calendar.id = :calendarId AND loan.loanStatus IN :loanStatuses ")
|
||||
Integer countOfLoansSyncedWithCalendar(@Param("calendarId") Long calendarId, @Param("loanStatuses") Collection<Integer> loanStatuses);
|
||||
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
<persistence-unit-metadata>
|
||||
<persistence-unit-defaults>
|
||||
<delimited-identifiers/>
|
||||
<entity-listeners>
|
||||
<entity-listener
|
||||
class="org.springframework.data.jpa.domain.support.AuditingEntityListener" />
|
||||
</entity-listeners>
|
||||
<!-- <entity-listeners>-->
|
||||
<!-- <entity-listener-->
|
||||
<!-- class="org.springframework.data.jpa.domain.support.AuditingEntityListener" />-->
|
||||
<!-- </entity-listeners>-->
|
||||
</persistence-unit-defaults>
|
||||
</persistence-unit-metadata>
|
||||
|
||||
|
||||
+53
-1
@@ -30,6 +30,40 @@
|
||||
<dropColumn tableName="BATCH_JOB_EXECUTION" columnName="JOB_CONFIGURATION_LOCATION"/>
|
||||
</changeSet>
|
||||
<changeSet author="fineract" id="2" context="postgresql">
|
||||
<sql>
|
||||
UPDATE BATCH_JOB_EXECUTION_PARAMS
|
||||
SET STRING_VAL = TO_CHAR(DATE_VAL, 'YYYY-MM-DDTHH:MM:SSZ')
|
||||
WHERE TYPE_CD = 'DATE'
|
||||
</sql>
|
||||
<sql>
|
||||
UPDATE BATCH_JOB_EXECUTION_PARAMS
|
||||
SET STRING_VAL = CAST(LONG_VAL AS CHAR)
|
||||
WHERE TYPE_CD = 'LONG'
|
||||
</sql>
|
||||
<sql>
|
||||
UPDATE BATCH_JOB_EXECUTION_PARAMS
|
||||
SET STRING_VAL = CAST(DOUBLE_VAL AS CHAR)
|
||||
WHERE TYPE_CD = 'DOUBLE'
|
||||
</sql>
|
||||
</changeSet>
|
||||
<changeSet author="fineract" id="2" context="mysql">
|
||||
<sql>
|
||||
UPDATE BATCH_JOB_EXECUTION_PARAMS
|
||||
SET STRING_VAL = DATE_FORMAT(DATE_VAL, 'YYYY-MM-DDTHH:MM:SSZ')
|
||||
WHERE TYPE_CD = 'DATE'
|
||||
</sql>
|
||||
<sql>
|
||||
UPDATE BATCH_JOB_EXECUTION_PARAMS
|
||||
SET STRING_VAL = LONG_VAL::text
|
||||
WHERE TYPE_CD = 'LONG'
|
||||
</sql>
|
||||
<sql>
|
||||
UPDATE BATCH_JOB_EXECUTION_PARAMS
|
||||
SET STRING_VAL = DOUBLE_VAL::text
|
||||
WHERE TYPE_CD = 'DOUBLE'
|
||||
</sql>
|
||||
</changeSet>
|
||||
<changeSet author="fineract" id="4" context="postgresql">
|
||||
<!--
|
||||
org/springframework/batch/core/migration/5.0/migration-postgresql.sql
|
||||
-->
|
||||
@@ -58,7 +92,7 @@
|
||||
|
||||
</sql>
|
||||
</changeSet>
|
||||
<changeSet author="fineract" id="3" context="mysql">
|
||||
<changeSet author="fineract" id="4" context="mysql">
|
||||
<!--
|
||||
org/springframework/batch/core/migration/5.0/migration-mysql.sql
|
||||
-->
|
||||
@@ -75,4 +109,22 @@
|
||||
ALTER TABLE BATCH_JOB_EXECUTION_PARAMS CHANGE COLUMN STRING_VAL PARAMETER_VALUE VARCHAR(2500);
|
||||
</sql>
|
||||
</changeSet>
|
||||
<changeSet author="fineract" id="5">
|
||||
<update tableName="BATCH_JOB_EXECUTION_PARAMS">
|
||||
<column name="PARAMETER_TYPE" value="java.lang.Long"/>
|
||||
<where>PARAMETER_TYPE='LONG'</where>
|
||||
</update>
|
||||
<update tableName="BATCH_JOB_EXECUTION_PARAMS">
|
||||
<column name="PARAMETER_TYPE" value="java.lang.String"/>
|
||||
<where>PARAMETER_TYPE='STRING'</where>
|
||||
</update>
|
||||
<update tableName="BATCH_JOB_EXECUTION_PARAMS">
|
||||
<column name="PARAMETER_TYPE" value="java.lang.Double"/>
|
||||
<where>PARAMETER_TYPE='DOUBLE'</where>
|
||||
</update>
|
||||
<update tableName="BATCH_JOB_EXECUTION_PARAMS">
|
||||
<column name="PARAMETER_TYPE" value="java.util.Date"/>
|
||||
<where>PARAMETER_TYPE='DATE'</where>
|
||||
</update>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
|
||||
+2
-1
@@ -38,6 +38,7 @@ import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.batch.item.Chunk;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
@@ -107,7 +108,7 @@ public class LoanItemListenerStepDefinitions implements En {
|
||||
});
|
||||
|
||||
When("LoanItemListener.onWriteError method executed", () -> {
|
||||
loanItemListener.onWriteError(exception, List.of(loan));
|
||||
loanItemListener.onWriteError(exception, new Chunk<>(List.of(loan)));
|
||||
});
|
||||
|
||||
Then("LoanItemListener.onWriteError result should match", () -> {
|
||||
|
||||
Reference in New Issue
Block a user