Skip to content

Commit

Permalink
chore: Merge pull request #225 from pagopa/release-uat
Browse files Browse the repository at this point in the history
chore: Release uat
  • Loading branch information
antonioT90 authored Nov 7, 2023
2 parents ff16831 + 7f5c5ff commit 4dd57c8
Show file tree
Hide file tree
Showing 18 changed files with 315 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# see https://help.github.com/en/articles/about-code-owners#example-of-a-codeowners-file

* @pagopa/idpay-app-maintainer-team @dariopelliccioli @antonioT90 @GiovanaSolorzano @pelliccm
* @pagopa/idpay-app-maintainer-team @dariopelliccioli @antonioT90 @frtrinca @Benedetta-fabbri @FrancescoGraziano @stedelia
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# Build
#
FROM maven:3.9.5-amazoncorretto-17-al2023@sha256:b7f94a5f1b6582a045692e31c2c97ef6f0ed867961669a0adbc2d5f0bbf8bc85 AS buildtime
FROM maven:3.9.5-amazoncorretto-17-al2023@sha256:eeaa7ab572d931f7273fc5cf31429923f172091ae388969e11f42ec6dd817d74 AS buildtime

WORKDIR /build
COPY . .
Expand All @@ -13,15 +13,15 @@ RUN mvn clean package -DskipTests
#
FROM amazoncorretto:17.0.9-alpine3.18@sha256:df48bf2e183230040890460ddb4359a10aa6c7aad24bd88899482c52053c7e17 AS runtime

RUN apk add shadow
RUN apk --no-cache add shadow
RUN useradd --uid 10000 runner

VOLUME /tmp
WORKDIR /app

COPY --from=buildtime /build/target/*.jar /app/app.jar
# The agent is enabled at runtime via JAVA_TOOL_OPTIONS.
ADD https://github.com/microsoft/ApplicationInsights-Java/releases/download/3.4.17/applicationinsights-agent-3.4.17.jar /app/applicationinsights-agent.jar
ADD https://github.com/microsoft/ApplicationInsights-Java/releases/download/3.4.18/applicationinsights-agent-3.4.18.jar /app/applicationinsights-agent.jar

RUN chown -R runner:runner /app

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import it.gov.pagopa.admissibility.model.IseeTypologyEnum;
import it.gov.pagopa.common.kafka.KafkaTestUtilitiesService;
import it.gov.pagopa.common.mongo.MongoTestUtilitiesService;
import it.gov.pagopa.common.mongo.singleinstance.AutoConfigureSingleInstanceMongodb;
import it.gov.pagopa.common.rest.utils.WireMockUtils;
import it.gov.pagopa.common.stream.StreamsHealthIndicator;
import it.gov.pagopa.common.utils.JUnitExtensionContextHolder;
Expand All @@ -27,7 +28,6 @@
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContextInitializer;
Expand Down Expand Up @@ -95,15 +95,15 @@
//region mongodb
"logging.level.org.mongodb.driver=WARN",
"logging.level.de.flapdoodle.embed.mongo.spring.autoconfigure=WARN",
"de.flapdoodle.mongodb.embedded.version=4.0.21",
"de.flapdoodle.mongodb.embedded.version=4.2.24",
//endregion

//region pdv
"app.pdv.retry.delay-millis=5000",
"app.pdv.retry.max-attempts=3",
//endregion
})
@AutoConfigureDataMongo
@AutoConfigureSingleInstanceMongodb
@AutoConfigureWebTestClient
@ContextConfiguration(initializers = {BaseIntegrationTest.WireMockInitializer.class})
public abstract class BaseIntegrationTest {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package it.gov.pagopa.admissibility.connector.repository;

import org.springframework.test.context.TestPropertySource;
import it.gov.pagopa.common.mongo.MongoTestIntegrated;

/**
* See confluence page: <a href="https://pagopa.atlassian.net/wiki/spaces/IDPAY/pages/615974424/Secrets+UnitTests">Secrets for UnitTests</a>
*/
@SuppressWarnings({"squid:S3577", "NewClassNamingConvention"}) // suppressing class name not match alert: we are not using the Test suffix in order to let not execute this test by default maven configuration because it depends on properties not pushable. See
@TestPropertySource(locations = {
"classpath:/mongodbEmbeddedDisabled.properties",
"classpath:/secrets/mongodbConnectionString.properties"
})
@MongoTestIntegrated
public class CustomSequenceGeneratorOpsRepositoryImplTestIntegrated extends CustomSequenceGeneratorOpsRepositoryImplTest{
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import it.gov.pagopa.common.kafka.utils.KafkaConstants;
import it.gov.pagopa.common.mongo.singleinstance.AutoConfigureSingleInstanceMongodb;
import it.gov.pagopa.common.reactive.kafka.consumer.BaseKafkaConsumer;
import it.gov.pagopa.common.utils.MemoryAppender;
import it.gov.pagopa.common.utils.TestUtils;
Expand Down Expand Up @@ -69,6 +70,7 @@ public class KafkaTestUtilitiesService {
private ObjectMapper objectMapper;

@TestConfiguration
@AutoConfigureSingleInstanceMongodb
static class TestKafkaConfiguration {
@Bean
public KafkaTemplate<byte[], byte[]> testPublisher(ProducerFactory<byte[], byte[]> producerFactory) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package it.gov.pagopa.common.mongo;

public interface EmbeddedMongodbTestClient {
void dropDatabase();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@TestPropertySource(locations = {
"classpath:/mongodbEmbeddedDisabled.properties",
"classpath:/secrets/mongodbConnectionString.properties"
})
@TestPropertySource(
properties = {
"spring.autoconfigure.exclude=" +
" de.flapdoodle.embed.mongo.spring.autoconfigure.EmbeddedMongoAutoConfiguration," +
" it.gov.pagopa.common.mongo.singleinstance.SingleEmbeddedMongodbAutoConfiguration"
},
locations = {
"classpath:/secrets/mongodbConnectionString.properties"
})
public @interface MongoTestIntegrated {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package it.gov.pagopa.common.mongo.singleinstance;

import de.flapdoodle.embed.mongo.spring.autoconfigure.EmbeddedMongoAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo;

import java.lang.annotation.*;

/** It will enable the usage of a single instance of {@link EmbeddedMongoAutoConfiguration}, dropping the database at each new Spring Context */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@AutoConfigureDataMongo
@ImportAutoConfiguration(exclude = EmbeddedMongoAutoConfiguration.class)
public @interface AutoConfigureSingleInstanceMongodb {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package it.gov.pagopa.common.mongo.singleinstance;

import de.flapdoodle.embed.mongo.commands.MongodArguments;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.IFeatureAwareVersion;
import de.flapdoodle.embed.mongo.spring.autoconfigure.*;
import de.flapdoodle.embed.mongo.transitions.Mongod;
import it.gov.pagopa.common.mongo.EmbeddedMongodbTestClient;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.test.context.event.annotation.AfterTestClass;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Objects;

/**
* Used to start just once Mongodb instance for the entire duration of the test, dropping the database at each new Spring Context
*/
@AutoConfiguration(
before = {MongoAutoConfiguration.class, MongoReactiveAutoConfiguration.class, EmbeddedMongoAutoConfiguration.class}
)
public class SingleEmbeddedMongodbAutoConfiguration extends EmbeddedMongoAutoConfiguration {

private static MongodWrapper singleMongodWrapperInstance;

private final EmbeddedMongodbTestClient embeddedMongodbTestClient;

public SingleEmbeddedMongodbAutoConfiguration(EmbeddedMongodbTestClient embeddedMongodbTestClient) {
this.embeddedMongodbTestClient = embeddedMongodbTestClient;
}

@Bean
@Override
public Net net(ConfigurableApplicationContext context) throws IOException {
if(SingleInstanceMongodWrapper.singleMongodNet!=null){
ConfigurableEnvironment env = context.getEnvironment();
env.getPropertySources().addFirst(new MapPropertySource("embeddedMongoReusedProperties",
Map.of("spring.data.mongodb.port", SingleInstanceMongodWrapper.singleMongodNet.getPort())));
super.net(context);

return SingleInstanceMongodWrapper.singleMongodNet;
}else {
return SingleInstanceMongodWrapper.singleMongodNet = super.net(context);
}
}

@AfterTestClass
void clearData(){
embeddedMongodbTestClient.dropDatabase();
}

@ConditionalOnClass(name = {
"com.mongodb.reactivestreams.client.MongoClient",
"org.springframework.data.mongodb.core.ReactiveMongoClientFactoryBean"
})
static class ReactiveClientServerWrapperConfig {

private final Constructor<ReactiveClientServerFactory> unprotectedReactiveClientServerFactoryConstructor;

ReactiveClientServerWrapperConfig() {
try {
unprotectedReactiveClientServerFactoryConstructor = ReactiveClientServerFactory.class.getDeclaredConstructor(MongoProperties.class);
unprotectedReactiveClientServerFactoryConstructor.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("Cannot unprotect AbstractServerFactory constructor", e);
}
}

@Bean(
initMethod = "start",
destroyMethod = "stop"
)
@ConditionalOnMissingBean
public MongodWrapper reactiveClientServerWrapper(IFeatureAwareVersion version, MongoProperties properties, Mongod mongod, MongodArguments mongodArguments) {
return Objects.requireNonNullElseGet(
singleMongodWrapperInstance,
() -> createMongodWrapper(unprotectedReactiveClientServerFactoryConstructor, version, properties, mongod, mongodArguments));
}

@Bean
@ConditionalOnMissingBean
public EmbeddedMongodbTestClient embeddedMongodbTestClient(Environment env) {
return createEmbeddedMongodbTestClient("it.gov.pagopa.common.reactive.mongo.EmbeddedMongodbTestReactiveClient", env);
}
}

@ConditionalOnClass(name = {
"com.mongodb.client.MongoClient",
"org.springframework.data.mongodb.core.MongoClientFactoryBean"
})
static class SyncClientServerWrapperConfig {

private final Constructor<SyncClientServerFactory> unprotectedSyncClientServerFactoryConstructor;

SyncClientServerWrapperConfig() {
try {
unprotectedSyncClientServerFactoryConstructor = SyncClientServerFactory.class.getDeclaredConstructor(MongoProperties.class);
unprotectedSyncClientServerFactoryConstructor.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("Cannot unprotect AbstractServerFactory constructor", e);
}
}

@Bean(
initMethod = "start",
destroyMethod = "stop"
)
@ConditionalOnMissingBean
public MongodWrapper syncClientServerWrapper(IFeatureAwareVersion version, MongoProperties properties, Mongod mongod, MongodArguments mongodArguments) {
return Objects.requireNonNullElseGet(
singleMongodWrapperInstance,
() -> createMongodWrapper(unprotectedSyncClientServerFactoryConstructor, version, properties, mongod, mongodArguments));
}

@Bean
@ConditionalOnMissingBean
public EmbeddedMongodbTestClient embeddedMongodbTestClient(Environment env) {
return createEmbeddedMongodbTestClient("it.gov.pagopa.common.mongo.EmbeddedMongodbTestSyncClient", env);
}
}

private static MongodWrapper createMongodWrapper(Constructor<? extends AbstractServerFactory<?>> unprotectedSyncClientServerFactoryConstructor, IFeatureAwareVersion version, MongoProperties properties, Mongod mongod, MongodArguments mongodArguments) {
try {
return singleMongodWrapperInstance = new SingleInstanceMongodWrapper(unprotectedSyncClientServerFactoryConstructor.newInstance(properties).createWrapper(version, mongod, mongodArguments));
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("Cannot call protected constructor", e);
}
}

private static EmbeddedMongodbTestClient createEmbeddedMongodbTestClient(String embeddedMongodbTestClientClassName, Environment env) {
try {
return (EmbeddedMongodbTestClient) Class.forName(embeddedMongodbTestClientClassName).getConstructor(Environment.class).newInstance(env);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | InvocationTargetException | NoSuchMethodException e) {
throw new IllegalStateException("Cannot create EmbeddedMongodbTestClient", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package it.gov.pagopa.common.mongo.singleinstance;

import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.spring.autoconfigure.MongodWrapper;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicInteger;

public class SingleInstanceMongodWrapper extends MongodWrapper {

private final Runnable unprotectedStart;
private final Runnable unprotectedStop;

private final AtomicInteger counter = new AtomicInteger(0);
public static Net singleMongodNet;

public SingleInstanceMongodWrapper(MongodWrapper mongodWrapper) {
super(null);

unprotectedStart = unprotectMongodWrapperMethod("start", mongodWrapper);
unprotectedStop = unprotectMongodWrapperMethod("stop", mongodWrapper);
}

private Runnable unprotectMongodWrapperMethod(String methodName, MongodWrapper mongodWrapper) {
try {
Method method = MongodWrapper.class.getDeclaredMethod(methodName);
method.setAccessible(true);
return () -> {
try {
method.invoke(mongodWrapper);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("Cannot invoke protected %s mongodWrapper method".formatted(methodName), e);
}
};
} catch (NoSuchMethodException e) {
throw new IllegalStateException("Cannot unprotect mongodWrapper methods", e);
}
}

@SuppressWarnings("unused") // called by Spring
private void start() {
synchronized (counter) {
if (counter.getAndIncrement() == 0) {
unprotectedStart.run();
}
}
}

@SuppressWarnings("unused") // called by Spring
private void stop() {
if (counter.decrementAndGet() == 0) {
unprotectedStop.run();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import it.gov.pagopa.common.mongo.MongoTestUtilitiesService;
import it.gov.pagopa.common.mongo.config.MongoConfig;
import it.gov.pagopa.common.mongo.singleinstance.AutoConfigureSingleInstanceMongodb;
import it.gov.pagopa.common.reactive.mongo.config.ReactiveMongoConfig;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
Expand All @@ -15,7 +16,6 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer;
import org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
Expand All @@ -25,7 +25,7 @@
import java.util.Map;

@TestPropertySource(properties = {
"de.flapdoodle.mongodb.embedded.version=4.0.21",
"de.flapdoodle.mongodb.embedded.version=4.2.24",

"spring.data.mongodb.database=idpay",
"spring.data.mongodb.config.connectionPool.maxSize: 100",
Expand All @@ -36,7 +36,7 @@
"spring.data.mongodb.config.connectionPool.maxConnecting: 2",
})
@ExtendWith(SpringExtension.class)
@AutoConfigureDataMongo
@AutoConfigureSingleInstanceMongodb
@ContextConfiguration(classes = {BaseReactiveMongoRepositoryIntegrationTest.TestMongoRepositoryConfig.class, ReactiveMongoConfig.class, MongoTestUtilitiesService.TestMongoConfiguration.class, SimpleMeterRegistry.class})
class BaseReactiveMongoRepositoryIntegrationTest {

Expand All @@ -45,6 +45,7 @@ class BaseReactiveMongoRepositoryIntegrationTest {
}

@TestConfiguration
@AutoConfigureSingleInstanceMongodb
static class TestMongoRepositoryConfig extends MongoConfig {
@Autowired
private MongoMetricsCommandListener mongoMetricsCommandListener;
Expand Down
Loading

0 comments on commit 4dd57c8

Please sign in to comment.