diff --git a/pom.xml b/pom.xml index 539f55d7..7462c4aa 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ info - 1.12.4 + 1.14.3 diff --git a/src/test/java/org/jboss/xavier/integrations/EndToEndTest.java b/src/test/java/org/jboss/xavier/integrations/EndToEndTest.java index af1cf40e..f85a2d71 100644 --- a/src/test/java/org/jboss/xavier/integrations/EndToEndTest.java +++ b/src/test/java/org/jboss/xavier/integrations/EndToEndTest.java @@ -1,9 +1,29 @@ package org.jboss.xavier.integrations; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.awaitility.Awaitility.await; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.inject.Inject; +import javax.inject.Named; + import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.ListObjectsV2Request; import com.amazonaws.util.Base64; import com.fasterxml.jackson.databind.ObjectMapper; + import org.apache.camel.CamelContext; import org.apache.camel.Exchange; import org.apache.camel.builder.AdviceWithRouteBuilder; @@ -17,7 +37,16 @@ import org.jboss.xavier.analytics.pojo.output.AnalysisModel; import org.jboss.xavier.analytics.pojo.output.InitialSavingsEstimationReportModel; import org.jboss.xavier.analytics.pojo.output.workload.inventory.WorkloadInventoryReportModel; -import org.jboss.xavier.analytics.pojo.output.workload.summary.*; +import org.jboss.xavier.analytics.pojo.output.workload.summary.AppIdentifierModel; +import org.jboss.xavier.analytics.pojo.output.workload.summary.FlagAssessmentIdentityModel; +import org.jboss.xavier.analytics.pojo.output.workload.summary.FlagAssessmentModel; +import org.jboss.xavier.analytics.pojo.output.workload.summary.OSInformationModel; +import org.jboss.xavier.analytics.pojo.output.workload.summary.ScanRunModel; +import org.jboss.xavier.analytics.pojo.output.workload.summary.SummaryModel; +import org.jboss.xavier.analytics.pojo.output.workload.summary.WorkloadSummaryReportModel; +import org.jboss.xavier.analytics.pojo.output.workload.summary.WorkloadsApplicationPlatformsDetectedModel; +import org.jboss.xavier.analytics.pojo.output.workload.summary.WorkloadsDetectedOSTypeModel; +import org.jboss.xavier.analytics.pojo.output.workload.summary.WorkloadsJavaRuntimeDetectedModel; import org.jboss.xavier.integrations.jpa.repository.AppIdentifierRepository; import org.jboss.xavier.integrations.jpa.repository.FlagAssessmentRepository; import org.jboss.xavier.integrations.jpa.repository.InitialSavingsEstimationReportRepository; @@ -30,8 +59,6 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; @@ -39,12 +66,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.util.EnvironmentTestUtils; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Import; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.hateoas.PagedResources; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -56,84 +79,17 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.KafkaContainer; -import org.testcontainers.containers.Network; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.containers.localstack.LocalStackContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; -import org.testcontainers.images.builder.ImageFromDockerfile; -import org.testcontainers.utility.MountableFile; - -import javax.inject.Inject; -import javax.inject.Named; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Enumeration; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.awaitility.Awaitility.await; -import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3; @RunWith(CamelSpringBootRunner.class) -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) @UseAdviceWith // Disables automatic start of Camel context @SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) -@ContextConfiguration(initializers = EndToEndTest.Initializer.class) +@ContextConfiguration(initializers = TestContainersInfrastructure.SpringBootInitializerTestContainers.class) @Import(TestConfigurationS3.class) @ActiveProfiles("test") -public class EndToEndTest { - private static Logger logger = LoggerFactory.getLogger(EndToEndTest.class); - - @ClassRule - public static GenericContainer kie_server = new GenericContainer<>("jboss/kie-server-showcase:7.18.0.Final") - .withNetworkAliases("kie-server") - .withExposedPorts(8080) - .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("KIE-LOG")) - .withEnv("KIE_SERVER_ID", "analytics-kieserver") - .withEnv("KIE_ADMIN_USER", "kieserver") - .withEnv("KIE_ADMIN_PWD", "kieserver1!") - .withEnv("KIE_SERVER_MODE", "DEVELOPMENT") - .withEnv("KIE_MAVEN_REPO", "https://oss.sonatype.org/content/repositories/snapshots") - .withEnv("KIE_REPOSITORY","https://repository.jboss.org/nexus/content/groups/public-jboss") - .withEnv("KIE_SERVER_CONTROLLER_PWD","admin") - .withEnv("KIE_SERVER_CONTROLLER_USER","admin") - .withEnv("KIE_SERVER_LOCATION","http://kie-server:8080/kie-server/services/rest/server") - .withEnv("KIE_SERVER_PWD","kieserver1!") - .withEnv("KIE_SERVER_USER","kieserver"); - - @ClassRule - public static PostgreSQLContainer postgreSQL = new PostgreSQLContainer() - .withDatabaseName("sampledb") - .withUsername("admin") - .withPassword("redhat"); - - @ClassRule - public static LocalStackContainer localstack = new LocalStackContainer() - .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("AWS-LOG")) - .withServices(S3); - - private static String ingressCommitHash = "3ea33a8d793c2154f7cfa12057ca005c5f6031fa"; // 2019-11-11 - private static String insightsRbacCommitHash = "a55b610a1385f0f6d3188b08710ec6a5890a97f6"; // 2020-02-05 +@DirtiesContext +public class EndToEndTest extends TestContainersInfrastructure { + private Logger logger = LoggerFactory.getLogger(EndToEndTest.class); @Inject private InitialSavingsEstimationReportService initialSavingsEstimationReportService; @@ -178,299 +134,98 @@ public class EndToEndTest { @Inject CamelContext camelContext; + @Inject + AmazonS3 amazonS3; + @Inject private ObjectMapper objectMapper; @Value("${camel.component.servlet.mapping.context-path}") private String basePath; - public static class Initializer implements ApplicationContextInitializer { - - @Override - public void initialize(ConfigurableApplicationContext configurableApplicationContext) { - try { - cloneIngressRepoAndUnzip(); - cloneInsightsRbacRepo_UnzipAndConfigure(); - - Network network = Network.newNetwork(); - - GenericContainer minio = new GenericContainer<>("minio/minio") - .withCommand("server /data") - .withExposedPorts(9000) - .withNetworkAliases("minio") - .withNetwork(network) - .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("MINIO-LOG")) - .withEnv("MINIO_ACCESS_KEY", "BQA2GEXO711FVBVXDWKM") - .withEnv("MINIO_SECRET_KEY", "uvgz3LCwWM3e400cDkQIH/y1Y4xgU4iV91CwFSPC"); - minio.start(); - - Thread.sleep(5000); - GenericContainer createbuckets = new GenericContainer<>("minio/mc") - .dependsOn(minio) - .withNetwork(network) - .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("MINIO-MC-LOG")) - .withCopyFileToContainer(MountableFile.forClasspathResource("minio-bucket-creation-commands.sh"), "/") - .withCreateContainerCmdModifier(createContainerCmd -> createContainerCmd.withEntrypoint("sh", "/minio-bucket-creation-commands.sh", "minio:9000")); - createbuckets.start(); - - KafkaContainer kafka = new KafkaContainer() - .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("KAFKA-LOG")) - .withNetworkAliases("kafka") - .withNetwork(network); - kafka.start(); - - GenericContainer ingress = new GenericContainer(new ImageFromDockerfile() - .withDockerfile(Paths.get("src/test/resources/insights-ingress-go/Dockerfile"))) - .withExposedPorts(3000) - .withNetwork(network) - .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("INGRESS-LOG")) - .withEnv("AWS_ACCESS_KEY_ID","BQA2GEXO711FVBVXDWKM") - .withEnv("AWS_SECRET_ACCESS_KEY","uvgz3LCwWM3e400cDkQIH/y1Y4xgU4iV91CwFSPC") - .withEnv("AWS_REGION","us-east-1") - .withEnv("INGRESS_STAGEBUCKET","insights-upload-perma") - .withEnv("INGRESS_REJECTBUCKET","insights-upload-rejected") - .withEnv("INGRESS_INVENTORYURL","http://inventory:8080/api/inventory/v1/hosts") - .withEnv("INGRESS_VALIDTOPICS","xavier,testareno,advisortestareno,advisor") - .withEnv("OPENSHIFT_BUILD_COMMIT","woopwoop") - .withEnv("INGRESS_MINIODEV","true") - .withEnv("INGRESS_MINIOACCESSKEY","BQA2GEXO711FVBVXDWKM") - .withEnv("INGRESS_MINIOSECRETKEY","uvgz3LCwWM3e400cDkQIH/y1Y4xgU4iV91CwFSPC") - .withEnv("INGRESS_MINIOENDPOINT", "minio:9000") - .withEnv("INGRESS_KAFKABROKERS", "kafka:9092"); - ingress.start(); - - Network rbacNetwork = Network.newNetwork(); - GenericContainer rbacPostgreSQL = new PostgreSQLContainer() - .withDatabaseName("rb_database") - .withUsername("rbac_username") - .withPassword("rbac_password") - .withNetwork(rbacNetwork) - .withNetworkAliases("rbac_db"); - rbacPostgreSQL.start(); - GenericContainer rbacServer = new GenericContainer<>(new ImageFromDockerfile() - .withDockerfile(Paths.get("src/test/resources/insights-rbac/insightsRbac_Dockerfile"))) - .withNetwork(rbacNetwork) - .withNetworkAliases("rbac") - .withExposedPorts(8000) - .withEnv("DATABASE_SERVICE_NAME", "POSTGRES_SQL") - .withEnv("DATABASE_ENGINE", "postgresql") - .withEnv("DATABASE_NAME", "rb_database") - .withEnv("DATABASE_USER", "rbac_username") - .withEnv("DATABASE_PASSWORD", "rbac_password") - .withEnv("POSTGRES_SQL_SERVICE_HOST", "rbac_db") - .withEnv("POSTGRES_SQL_SERVICE_PORT", "5432"); - rbacServer.start(); - - importProjectIntoKIE(); - - EnvironmentTestUtils.addEnvironment("environment", configurableApplicationContext.getEnvironment(), - "minio.host=" + getContainerHost(minio, 9000), - "insights.upload.host=" + getContainerHost(ingress), - "insights.properties=yearOverYearGrowthRatePercentage,percentageOfHypervisorsMigratedOnYear1,percentageOfHypervisorsMigratedOnYear2,percentageOfHypervisorsMigratedOnYear3,reportName,reportDescription", - "camel.component.servlet.mapping.context-path=/*", - "insights.kafka.host=" + kafka.getBootstrapServers(), - "postgresql.service.name=" + postgreSQL.getContainerIpAddress(), - "postgresql.service.port=" + postgreSQL.getFirstMappedPort(), - "spring.datasource.username=" + postgreSQL.getUsername(), - "spring.datasource.password=" + postgreSQL.getPassword(), - "S3_HOST=" + localstack.getEndpointConfiguration(S3).getServiceEndpoint(), - "S3_REGION="+ localstack.getEndpointConfiguration(S3).getSigningRegion(), - "kieserver.devel-service=" + getHostForKie() + "/kie-server", - "spring.datasource.url = jdbc:postgresql://" + getContainerHost(postgreSQL) + "/sampledb" , - "spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect" , - "thread.concurrentConsumers=3", - "insights.rbac.path=/api/v1/access/", - "insights.rbac.host=" + "http://" + getContainerHost(rbacServer, 8000)); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @NotNull - private String getContainerHost(GenericContainer container, Integer port) { - return container.getContainerIpAddress() + ":" + container.getMappedPort(port); - } - - @NotNull - private static String getContainerHost(GenericContainer container) { - return container.getContainerIpAddress() + ":" + container.getFirstMappedPort(); - } - } - - - - private static void cloneIngressRepoAndUnzip() throws IOException { - // downloading, unzipping, renaming - String ingressRepoZipURL = "https://github.com/RedHatInsights/insights-ingress-go/archive/" + ingressCommitHash + ".zip"; - File compressedFile = new File("src/test/resources/ingressRepo.zip"); - FileUtils.copyURLToFile(new URL(ingressRepoZipURL), compressedFile, 1000, 10000); - unzipFile(compressedFile, "src/test/resources"); - - // we rename the directory because we had issues with Docker and the long folder - FileUtils.moveDirectory(new File("src/test/resources/insights-ingress-go-" + ingressCommitHash), new File("src/test/resources/insights-ingress-go")); - } + private static int analysisNum; - private static void cloneInsightsRbacRepo_UnzipAndConfigure() throws IOException { - // downloading, unzipping, renaming - String insightsRbacRepoZipURL = "https://github.com/RedHatInsights/insights-rbac/archive/" + insightsRbacCommitHash + ".zip"; - File compressedFile = new File("src/test/resources/insightsRbacRepo.zip"); - FileUtils.copyURLToFile(new URL(insightsRbacRepoZipURL), compressedFile, 1000, 10000); - unzipFile(compressedFile, "src/test/resources"); - - // we rename the directory because we had issues with Docker and the long folder - FileUtils.moveDirectory(new File("src/test/resources/insights-rbac-" + insightsRbacCommitHash), new File("src/test/resources/insights-rbac")); - - // Use custom Dockerfile - FileUtils.copyFile( - new File("src/test/resources/insightsRbac_Dockerfile"), - new File("src/test/resources/insights-rbac/insightsRbac_Dockerfile") - ); - - // Configure default system roles for application=migration-analytics - FileUtils.copyFile( - new File("src/test/resources/insightsRbac_roleDefinitions.json"), - new File("src/test/resources/insights-rbac/rbac/management/role/definitions/migration-analytics.json") - ); - } - - private static void unzipFile(File file, String outputDir) throws IOException { - java.util.zip.ZipFile zipFile = new ZipFile(file); - try { - Enumeration entries = zipFile.entries(); - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - File entryDestination = new File(outputDir, entry.getName()); - if (entry.isDirectory()) { - entryDestination.mkdirs(); - } else { - entryDestination.getParentFile().mkdirs(); - InputStream in = zipFile.getInputStream(entry); - OutputStream out = new FileOutputStream(entryDestination); - IOUtils.copy(in, out); - in.close(); - out.close(); - } - } - } finally { - zipFile.close(); - } - } - - private static String getHostForKie() { - return kie_server.getContainerIpAddress() + ":" + kie_server.getFirstMappedPort(); - } - - private static void importProjectIntoKIE() throws InterruptedException, IOException { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - headers.setCacheControl("no-cache"); - headers.set("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin - - String kieRestURL = "http://" + getHostForKie() + "/kie-server/services/rest/"; - - // KIE Container Creation - HttpHeaders kieheaders = new HttpHeaders(); - kieheaders.setContentType(MediaType.APPLICATION_JSON); - kieheaders.set("Authorization", "Basic a2llc2VydmVyOmtpZXNlcnZlcjEh"); - kieheaders.setCacheControl("no-cache"); - String kieContainerBody = "{\"container-id\" : \"xavier-analytics_0.0.1-SNAPSHOT\",\"release-id\" : {\"group-id\" : \"org.jboss.xavier\",\"artifact-id\" : \"xavier-analytics\",\"version\" : \"0.0.1-SNAPSHOT\" } }"; - try { - new RestTemplate().exchange(kieRestURL + "server/containers/xavier-analytics_0.0.1-SNAPSHOT", HttpMethod.PUT, new HttpEntity<>(kieContainerBody, kieheaders), String.class); - } catch (RestClientException e) { - e.printStackTrace(); - } - } + private static boolean firstTime = true; + private static int testsExecuted = 0; - @Before public void setDefaults() { long id = 0L; // OSInformation - AppIdentifierModel osFamily1 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(OSInformationModel.APP_IDENTIFIER) - .withName("RHEL") - .withIdentifier("RHEL") // osFamily field - .withPriority(100) - .build(); - AppIdentifierModel osFamily2 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(OSInformationModel.APP_IDENTIFIER) - .withName("Windows Server") + AppIdentifierModel osFamily1 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(OSInformationModel.APP_IDENTIFIER).withName("RHEL").withIdentifier("RHEL") // osFamily + // field + .withPriority(100).build(); + AppIdentifierModel osFamily2 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(OSInformationModel.APP_IDENTIFIER).withName("Windows Server") .withIdentifier("Windows Server") // osFamily field - .withPriority(90) - .build(); - AppIdentifierModel osFamily3 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(OSInformationModel.APP_IDENTIFIER) - .withName("Windows Other") + .withPriority(90).build(); + AppIdentifierModel osFamily3 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(OSInformationModel.APP_IDENTIFIER).withName("Windows Other") .withIdentifier("Windows Other") // osFamily field - .withPriority(80) - .build(); - AppIdentifierModel osFamily4 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(OSInformationModel.APP_IDENTIFIER) - .withName("SUSE") - .withIdentifier("SUSE") // osFamily field - .withPriority(70) - .build(); - AppIdentifierModel osFamily5 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(OSInformationModel.APP_IDENTIFIER) - .withName("CentOS") - .withIdentifier("CentOS") // osFamily field - .withPriority(60) - .build(); - AppIdentifierModel osFamily6 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(OSInformationModel.APP_IDENTIFIER) - .withName("Oracle Linux") + .withPriority(80).build(); + AppIdentifierModel osFamily4 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(OSInformationModel.APP_IDENTIFIER).withName("SUSE").withIdentifier("SUSE") // osFamily + // field + .withPriority(70).build(); + AppIdentifierModel osFamily5 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(OSInformationModel.APP_IDENTIFIER).withName("CentOS").withIdentifier("CentOS") // osFamily + // field + .withPriority(60).build(); + AppIdentifierModel osFamily6 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(OSInformationModel.APP_IDENTIFIER).withName("Oracle Linux") .withIdentifier("Oracle Linux") // osFamily field - .withPriority(50) - .build(); - AppIdentifierModel osFamily7 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(OSInformationModel.APP_IDENTIFIER) - .withName("Ubuntu") - .withIdentifier("Ubuntu") // osFamily field - .withPriority(40) - .build(); - AppIdentifierModel osFamily8 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(OSInformationModel.APP_IDENTIFIER) - .withName("Debian") - .withIdentifier("Debian") // osFamily field - .withPriority(30) - .build(); - AppIdentifierModel osFamily9 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(OSInformationModel.APP_IDENTIFIER) - .withName("Other") - .withIdentifier("Other") // osFamily field - .withPriority(20) - .build(); - appIdentifierRepository.save(Arrays.asList(osFamily1, osFamily2, osFamily3, osFamily4, osFamily5, osFamily6, osFamily7, osFamily8, osFamily9)); + .withPriority(50).build(); + AppIdentifierModel osFamily7 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(OSInformationModel.APP_IDENTIFIER).withName("Ubuntu").withIdentifier("Ubuntu") // osFamily + // field + .withPriority(40).build(); + AppIdentifierModel osFamily8 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(OSInformationModel.APP_IDENTIFIER).withName("Debian").withIdentifier("Debian") // osFamily + // field + .withPriority(30).build(); + AppIdentifierModel osFamily9 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(OSInformationModel.APP_IDENTIFIER).withName("Other").withIdentifier("Other") // osFamily + // field + .withPriority(20).build(); + appIdentifierRepository.save(Arrays.asList(osFamily1, osFamily2, osFamily3, osFamily4, osFamily5, osFamily6, + osFamily7, osFamily8, osFamily9)); // JDK Runtimes String oracleVendorName = "Oracle"; - AppIdentifierModel jdkRuntime1 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(WorkloadsJavaRuntimeDetectedModel.APP_IDENTIFIER) - .withName(oracleVendorName) - .withVersion("8") - .withIdentifier("Oracle JDK 8") // Workload name + AppIdentifierModel jdkRuntime1 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(WorkloadsJavaRuntimeDetectedModel.APP_IDENTIFIER).withName(oracleVendorName) + .withVersion("8").withIdentifier("Oracle JDK 8") // Workload name .build(); - AppIdentifierModel jdkRuntime2 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(WorkloadsJavaRuntimeDetectedModel.APP_IDENTIFIER) - .withName(oracleVendorName) - .withVersion("11") - .withIdentifier("Oracle JDK 11") // Workload name + AppIdentifierModel jdkRuntime2 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(WorkloadsJavaRuntimeDetectedModel.APP_IDENTIFIER).withName(oracleVendorName) + .withVersion("11").withIdentifier("Oracle JDK 11") // Workload name .build(); - AppIdentifierModel jdkRuntime3 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(WorkloadsJavaRuntimeDetectedModel.APP_IDENTIFIER) - .withName(oracleVendorName) - .withVersion("13") - .withIdentifier("Oracle JDK 13") // Workload name + AppIdentifierModel jdkRuntime3 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(WorkloadsJavaRuntimeDetectedModel.APP_IDENTIFIER).withName(oracleVendorName) + .withVersion("13").withIdentifier("Oracle JDK 13") // Workload name .build(); appIdentifierRepository.save(Arrays.asList(jdkRuntime1, jdkRuntime2, jdkRuntime3)); // ApplicationPlatforms - AppIdentifierModel applicationPlatform1 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(WorkloadsApplicationPlatformsDetectedModel.APP_IDENTIFIER) - .withName("JBoss EAP") + AppIdentifierModel applicationPlatform1 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(WorkloadsApplicationPlatformsDetectedModel.APP_IDENTIFIER).withName("JBoss EAP") .withIdentifier("Red Hat JBoss EAP") // Workload name .build(); - AppIdentifierModel applicationPlatform2 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(WorkloadsApplicationPlatformsDetectedModel.APP_IDENTIFIER) - .withName("Tomcat") + AppIdentifierModel applicationPlatform2 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(WorkloadsApplicationPlatformsDetectedModel.APP_IDENTIFIER).withName("Tomcat") .withIdentifier("Tomcat") // Workload name .build(); - AppIdentifierModel applicationPlatform3 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(WorkloadsApplicationPlatformsDetectedModel.APP_IDENTIFIER) - .withName("Oracle Weblogic") + AppIdentifierModel applicationPlatform3 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(WorkloadsApplicationPlatformsDetectedModel.APP_IDENTIFIER).withName("Oracle Weblogic") .withIdentifier("Oracle Weblogic") // Workload name .build(); - AppIdentifierModel applicationPlatform4 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id).withGroupName(WorkloadsApplicationPlatformsDetectedModel.APP_IDENTIFIER) - .withName("IBM WebSphere") + AppIdentifierModel applicationPlatform4 = AppIdentifierModel.Builder.anAppIdentifierModel().withId(++id) + .withGroupName(WorkloadsApplicationPlatformsDetectedModel.APP_IDENTIFIER).withName("IBM WebSphere") .withIdentifier("IBM Websphere App Server") // Workload name .build(); - appIdentifierRepository.save(Arrays.asList(applicationPlatform1, applicationPlatform2, applicationPlatform3, applicationPlatform4)); - + appIdentifierRepository.save( + Arrays.asList(applicationPlatform1, applicationPlatform2, applicationPlatform3, applicationPlatform4)); // FLag assessments FlagAssessmentModel flagAssessmentModel1 = new FlagAssessmentModel(); @@ -482,7 +237,6 @@ public void setDefaults() { fgId1.setFlag("flag"); fgId1.setOsName("osName"); flagAssessmentModel1.setId(fgId1); - FlagAssessmentModel flagAssessmentModel2 = new FlagAssessmentModel(); flagAssessmentModel2.setAssessment("assessment2"); flagAssessmentModel2.setFlag("flag2"); @@ -512,8 +266,9 @@ public void setDefaults() { fgId4.setFlag("flag4"); fgId4.setOsName("osName4"); flagAssessmentModel4.setId(fgId4); + flagAssessmentRepository.save( + Arrays.asList(flagAssessmentModel1, flagAssessmentModel2, flagAssessmentModel3, flagAssessmentModel4)); - flagAssessmentRepository.save(Arrays.asList(flagAssessmentModel1, flagAssessmentModel2, flagAssessmentModel3, flagAssessmentModel4)); } @BeforeClass @@ -527,6 +282,17 @@ public static void cleanUp() throws IOException { FileUtils.deleteQuietly(new File("src/test/resources/insightsRbacRepo.zip")); } + @BeforeClass + public static void startContainers() throws IOException, InterruptedException { + createAndStartDockerContainers(); + Thread.sleep(15000); + } + + @AfterClass + public static void stopContainers() { + stopAndDestroyDockerContainers(); + } + private int getStorageObjectsSize() { int s3Size = storageClient.listObjectsV2(new ListObjectsV2Request().withBucketName(bucket)).getKeyCount(); logger.info("S3 Objects : " + s3Size); @@ -534,316 +300,589 @@ private int getStorageObjectsSize() { } private void assertHttpClientError(String url, HttpMethod method, HttpStatus status) { - assertThatExceptionOfType(org.springframework.web.client.HttpClientErrorException.class) - .isThrownBy(() -> new RestTemplate().exchange(getBaseURLAPIPath() + url, method, getRequestEntity(), String.class)) - .matches(e -> e.getStatusCode().equals(status)); + assertThatExceptionOfType(org.springframework.web.client.HttpClientErrorException.class).isThrownBy( + () -> new RestTemplate().exchange(getBaseURLAPIPath() + url, method, getRequestEntity(), String.class)) + .matches(e -> e.getStatusCode().equals(status)); } - @Test - public void end2endTest() throws Exception { - Thread.sleep(2000); - - // given - camelContext.getGlobalOptions().put(Exchange.LOG_DEBUG_BODY_MAX_CHARS, "5000"); - camelContext.start(); - - camelContext.getRouteDefinition("download-file").adviceWith(camelContext, new AdviceWithRouteBuilder() { - @Override - public void configure() { - weaveById("setHttpUri") - .replace() - .process(e -> { - String url = e.getIn().getBody(FilePersistedNotification.class).getUrl(); - url = url.replace("minio:9000", minio_host); - e.getIn().setHeader("httpUriReplaced", url); - }) - .setHeader("Exchange.HTTP_URI", header("httpUriReplaced")) - .setHeader("Host", constant("minio:9000")); - - weaveById("toOldHost") - .replace() - .to("http4:oldhost?preserveHostHeader=true"); - } - }); - - // Checking errors are correctly treated - assertHttpClientError("/report/99999", HttpMethod.GET,HttpStatus.NOT_FOUND); - assertHttpClientError("/report/99999", HttpMethod.DELETE, HttpStatus.NOT_FOUND); - assertHttpClientError("/report/99999/payload-link", HttpMethod.GET,HttpStatus.NOT_FOUND); - assertHttpClientError("/report/99999/payload", HttpMethod.GET,HttpStatus.NOT_FOUND); - assertHttpClientError("/report/99999/initial-savings-estimation", HttpMethod.GET, HttpStatus.NOT_FOUND); + @Before + public void initCamel() throws Exception { + if (firstTime) { + logger.info("STARTING CAMEL >>>>>>>>"); + firstTime = false; + Thread.sleep(2000); // TODO use Awaitility to check a particular container + + // given + camelContext.getGlobalOptions().put(Exchange.LOG_DEBUG_BODY_MAX_CHARS, "5000"); + camelContext.start(); + camelContext.getRouteDefinition("download-file").adviceWith(camelContext, new AdviceWithRouteBuilder() { + @Override + public void configure() { + weaveById("setHttpUri").replace().process(e -> { + String url = e.getIn().getBody(FilePersistedNotification.class).getUrl(); + url = url.replace("minio:9000", minio_host); + e.getIn().setHeader("httpUriReplaced", url); + }).setHeader("Exchange.HTTP_URI", header("httpUriReplaced")).setHeader("Host", + constant("minio:9000")); + + weaveById("toOldHost").replace().to("http4:oldhost?preserveHostHeader=true"); + } + }); - // this one should give 2 pages - ResponseEntity> responseFlaggAssessment = new RestTemplate().exchange(getBaseURLAPIPath() + "/mappings/flag-assessment?limit=2&offset=0", HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); - assertThat(responseFlaggAssessment.getBody().getData().size()).isEqualTo(2); + setDefaults(); - ResponseEntity> responseFlaggAssessmentHighLimit = new RestTemplate().exchange(getBaseURLAPIPath() + "/mappings/flag-assessment?limit=1000&offset=0", HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); - assertThat(responseFlaggAssessmentHighLimit.getBody().getData().size()).isEqualTo(4); + ResponseEntity> responseAnalysisModel = new RestTemplate().exchange( + getBaseURLAPIPath() + "/report?limit=1000&offset=0", HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); + analysisNum = responseAnalysisModel.getBody().getData().size(); + logger.info("***** Number of reports upload until now : " + analysisNum); + + // Checking errors are correctly treated + assertHttpClientError("/report/99999", HttpMethod.GET, HttpStatus.NOT_FOUND); + assertHttpClientError("/report/99999", HttpMethod.DELETE, HttpStatus.NOT_FOUND); + assertHttpClientError("/report/99999/payload-link", HttpMethod.GET, HttpStatus.NOT_FOUND); + assertHttpClientError("/report/99999/payload", HttpMethod.GET, HttpStatus.NOT_FOUND); + assertHttpClientError("/report/99999/initial-savings-estimation", HttpMethod.GET, HttpStatus.NOT_FOUND); + + // this one should give 2 pages + ResponseEntity> responseFlaggAssessment = new RestTemplate().exchange( + getBaseURLAPIPath() + "/mappings/flag-assessment?limit=2&offset=0", HttpMethod.GET, + getRequestEntity(), new ParameterizedTypeReference>() { + }); + assertThat(responseFlaggAssessment.getBody().getData().size()).isEqualTo(2); + + ResponseEntity> responseFlaggAssessmentHighLimit = new RestTemplate() + .exchange(getBaseURLAPIPath() + "/mappings/flag-assessment?limit=1000&offset=0", HttpMethod.GET, + getRequestEntity(), new ParameterizedTypeReference>() { + }); + assertThat(responseFlaggAssessmentHighLimit.getBody().getData().size()).isEqualTo(4); + + // 1. Check user has firstTime + logger.info("****** Checking First Time User **********"); + ResponseEntity userEntity = new RestTemplate().exchange(getBaseURLAPIPath() + "/user", HttpMethod.GET, + getRequestEntity(), new ParameterizedTypeReference() { + }); + assertThat(userEntity.getBody().isFirstTimeCreatingReports()).isTrue(); + } + } - // 1. Check user has firstTime - ResponseEntity userEntity = new RestTemplate().exchange(getBaseURLAPIPath() + "/user", HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() {}); - assertThat(userEntity.getBody().isFirstTimeCreatingReports()).isTrue(); + @After + public void closeCamel() throws Exception { + testsExecuted++; + logger.info("After test method ..."); - // Start the camel route as if the UI was sending the file to the Camel Rest Upload route - int analysisNum = 0; - assertThat(getStorageObjectsSize()).isEqualTo(0); + if (testsExecuted == 10) { + logger.info("CLOSING CAMEL CONTEXT >>>>>>>>"); + camelContext.stop(); + } + } + @Test + public void whenRegularTestShouldAnswerInTime() throws Exception { logger.info("+++++++ Regular Test ++++++"); + // Start the camel route as if the UI was sending the file to the Camel Rest + // Upload route + int s3Objects = getStorageObjectsSize(); + assertThat(s3Objects).isEqualTo(analysisNum); + analysisNum++; - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cfme_inventory-20190912-demolab_withSSA.tar.gz", "application/zip"), String.class); + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", + getRequestEntityForUploadRESTCall("cfme_inventory-20190912-demolab_withSSA.tar.gz", "application/zip"), + String.class); // then - await() - .atMost(timeoutMilliseconds_InitialCostSavingsReport, TimeUnit.MILLISECONDS) - .with().pollInterval(Duration.ONE_HUNDRED_MILLISECONDS) - .until( () -> { - // Check database for the ICSR to be created - List all = initialSavingsEstimationReportRepository.findAll(); - return all != null && !all.isEmpty(); - }); + await().atMost(timeoutMilliseconds_InitialCostSavingsReport, TimeUnit.MILLISECONDS).with() + .pollInterval(Duration.ONE_HUNDRED_MILLISECONDS).until(() -> { + // Check database for the ICSR to be created + List all = initialSavingsEstimationReportRepository.findAll(); + return all != null && all.size() == analysisNum; + }); // Check S3 - assertThat(getStorageObjectsSize()).isEqualTo(1); + await().atMost(5000, TimeUnit.MILLISECONDS).with().pollInterval(Duration.ONE_HUNDRED_MILLISECONDS).until(() -> { + return (getStorageObjectsSize() == s3Objects + 1); + }); // Check DB for initialCostSavingsReport with concrete values - InitialSavingsEstimationReportModel initialCostSavingsReportDB = initialSavingsEstimationReportService.findByAnalysisOwnerAndAnalysisId("dummy@redhat.com", 1L); + InitialSavingsEstimationReportModel initialCostSavingsReportDB = initialSavingsEstimationReportService + .findByAnalysisOwnerAndAnalysisId("dummy@redhat.com", 1L); assertThat(initialCostSavingsReportDB.getEnvironmentModel().getHypervisors() == 2); assertThat(initialCostSavingsReportDB.getSourceCostsModel().getYear1Server() == 42); // Call initialCostSavingsReport - ResponseEntity initialCostSavingsReport = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() {}); + ResponseEntity initialCostSavingsReport = new RestTemplate().exchange( + getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference() { + }); // Call workloadInventoryReport - ResponseEntity> workloadInventoryReport = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); + ResponseEntity> workloadInventoryReport = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); // Call workloadSummaryReport - ResponseEntity workloadSummaryReport = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-summary", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() {}); + ResponseEntity workloadSummaryReport = new RestTemplate().exchange( + getBaseURLAPIPath() + String.format("/report/%d/workload-summary", analysisNum), HttpMethod.GET, + getRequestEntity(), new ParameterizedTypeReference() { + }); // Checks on Initial Savings Report - InitialSavingsEstimationReportModel initialSavingsEstimationReport_Expected = objectMapper.readValue(IOUtils.resourceToString("cfme_inventory-20190912-demolab-withssa-initial-cost-savings-report.json", StandardCharsets.UTF_8, EndToEndTest.class.getClassLoader()), InitialSavingsEstimationReportModel.class); + InitialSavingsEstimationReportModel initialSavingsEstimationReport_Expected = objectMapper.readValue( + IOUtils.resourceToString("cfme_inventory-20190912-demolab-withssa-initial-cost-savings-report.json", + StandardCharsets.UTF_8, EndToEndTest.class.getClassLoader()), + InitialSavingsEstimationReportModel.class); SoftAssertions.assertSoftly(softly -> softly.assertThat(initialCostSavingsReport.getBody()) - .usingRecursiveComparison() - .ignoringFieldsMatchingRegexes(".*id.*", ".*creationDate.*", ".*report.*") + .usingRecursiveComparison().ignoringFieldsMatchingRegexes(".*id.*", ".*creationDate.*", ".*report.*") .isEqualTo(initialSavingsEstimationReport_Expected)); // Checks on Workload Inventory Report SoftAssertions.assertSoftly(softly -> { softly.assertThat(workloadInventoryReport.getBody().getData().size()).isEqualTo(14); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().flatMap(e -> e.getWorkloads().stream()).distinct().count()).isEqualTo(7); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().filter(e -> e.getWorkloads().contains("Red Hat JBoss EAP")).count()).isEqualTo(2); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().map(WorkloadInventoryReportModel::getOsName).distinct().count()).isEqualTo(4); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().filter(e -> e.getOsName().contains("CentOS 7 (64-bit)")).count()).isEqualTo(2); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().map(WorkloadInventoryReportModel::getComplexity).distinct().count()).isEqualTo(4); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().filter(e -> e.getComplexity().contains("Unknown")).count()).isEqualTo(0); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().filter(e -> e.getComplexity().contains("Unsupported")).count()).isEqualTo(1); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().flatMap(e -> e.getRecommendedTargetsIMS().stream()).distinct().count()).isEqualTo(6); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().filter(e -> e.getRecommendedTargetsIMS().contains("OSP")).count()).isEqualTo(11); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().filter(e -> e.getRecommendedTargetsIMS().contains("RHEL")).count()).isEqualTo(4); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().filter(e -> e.getRecommendedTargetsIMS().contains("None")).count()).isEqualTo(1); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().flatMap(e -> e.getFlagsIMS().stream()).distinct().count()).isEqualTo(2); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().filter(e -> e.getFlagsIMS().contains("Shared Disk")).count()).isEqualTo(2); - softly.assertThat(workloadInventoryReport.getBody().getData().stream().filter(e -> e.getOsName().contains("ServerNT") && e.getWorkloads().contains("Microsoft SQL Server")).count()).isEqualTo(1); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .flatMap(e -> e.getWorkloads().stream()).distinct().count()).isEqualTo(7); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .filter(e -> e.getWorkloads().contains("Red Hat JBoss EAP")).count()).isEqualTo(2); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .map(WorkloadInventoryReportModel::getOsName).distinct().count()).isEqualTo(4); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .filter(e -> e.getOsName().contains("CentOS 7 (64-bit)")).count()).isEqualTo(2); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .map(WorkloadInventoryReportModel::getComplexity).distinct().count()).isEqualTo(4); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .filter(e -> e.getComplexity().contains("Unknown")).count()).isEqualTo(0); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .filter(e -> e.getComplexity().contains("Unsupported")).count()).isEqualTo(1); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .flatMap(e -> e.getRecommendedTargetsIMS().stream()).distinct().count()).isEqualTo(6); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .filter(e -> e.getRecommendedTargetsIMS().contains("OSP")).count()).isEqualTo(11); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .filter(e -> e.getRecommendedTargetsIMS().contains("RHEL")).count()).isEqualTo(4); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .filter(e -> e.getRecommendedTargetsIMS().contains("None")).count()).isEqualTo(1); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .flatMap(e -> e.getFlagsIMS().stream()).distinct().count()).isEqualTo(2); + softly.assertThat(workloadInventoryReport.getBody().getData().stream() + .filter(e -> e.getFlagsIMS().contains("Shared Disk")).count()).isEqualTo(2); + softly.assertThat(workloadInventoryReport.getBody().getData().stream().filter( + e -> e.getOsName().contains("ServerNT") && e.getWorkloads().contains("Microsoft SQL Server")) + .count()).isEqualTo(1); }); - WorkloadInventoryReportModel[] workloadInventoryReportModelExpected = objectMapper.readValue(IOUtils.resourceToString("cfme_inventory-20190912-demolab-withssa-workload-inventory-report.json", StandardCharsets.UTF_8, EndToEndTest.class.getClassLoader()), WorkloadInventoryReportModel[].class); - assertThat(workloadInventoryReport.getBody().getData().toArray()) - .usingRecursiveComparison() + WorkloadInventoryReportModel[] workloadInventoryReportModelExpected = objectMapper.readValue( + IOUtils.resourceToString("cfme_inventory-20190912-demolab-withssa-workload-inventory-report.json", + StandardCharsets.UTF_8, EndToEndTest.class.getClassLoader()), + WorkloadInventoryReportModel[].class); + assertThat(workloadInventoryReport.getBody().getData().toArray()).usingRecursiveComparison() .ignoringFieldsMatchingRegexes(".*id.*", ".*creationDate.*") .isEqualTo(workloadInventoryReportModelExpected); // Checks on Workload Summary Report - WorkloadSummaryReportModel workloadSummaryReport_Expected = objectMapper.readValue(IOUtils.resourceToString("cfme_inventory-20190912-demolab-withssa-workload-summary-report.json", StandardCharsets.UTF_8, EndToEndTest.class.getClassLoader()), WorkloadSummaryReportModel.class); - - assertThat(workloadSummaryReport.getBody()) - .usingRecursiveComparison() - .ignoringFieldsMatchingRegexes(".*id.*", ".*creationDate.*", ".*report.*", ".*workloadsDetectedOSTypeModels.*", ".*scanRunModels.*") + WorkloadSummaryReportModel workloadSummaryReport_Expected = objectMapper + .readValue( + IOUtils.resourceToString("cfme_inventory-20190912-demolab-withssa-workload-summary-report.json", + StandardCharsets.UTF_8, EndToEndTest.class.getClassLoader()), + WorkloadSummaryReportModel.class); + + assertThat(workloadSummaryReport.getBody()).usingRecursiveComparison() + .ignoringFieldsMatchingRegexes(".*id.*", ".*creationDate.*", ".*report.*", + ".*workloadsDetectedOSTypeModels.*", ".*scanRunModels.*") .isEqualTo(workloadSummaryReport_Expected); // WLSR.ScanRunModels - TreeSet wks_scanrunmodel_expected = getWks_scanrunmodel(workloadSummaryReport_Expected.getScanRunModels()); - TreeSet wks_scanrunmodel_actual = getWks_scanrunmodel(workloadSummaryReport.getBody().getScanRunModels()); + TreeSet wks_scanrunmodel_expected = getWks_scanrunmodel( + workloadSummaryReport_Expected.getScanRunModels()); + TreeSet wks_scanrunmodel_actual = getWks_scanrunmodel( + workloadSummaryReport.getBody().getScanRunModels()); // WLSR.WorkloadsDetectedOSTypeModel - TreeSet wks_ostypemodel_expected = getWks_ostypemodel(workloadSummaryReport_Expected.getWorkloadsDetectedOSTypeModels()); - TreeSet wks_ostypemodel_actual = getWks_ostypemodel(workloadSummaryReport.getBody().getWorkloadsDetectedOSTypeModels()); + TreeSet wks_ostypemodel_expected = getWks_ostypemodel( + workloadSummaryReport_Expected.getWorkloadsDetectedOSTypeModels()); + TreeSet wks_ostypemodel_actual = getWks_ostypemodel( + workloadSummaryReport.getBody().getWorkloadsDetectedOSTypeModels()); SoftAssertions.assertSoftly(softly -> { - softly.assertThat(wks_scanrunmodel_actual).isEqualTo(wks_scanrunmodel_expected); - softly.assertThat(wks_ostypemodel_actual).isEqualTo(wks_ostypemodel_expected); + softly.assertThat(wks_scanrunmodel_actual).isEqualTo(wks_scanrunmodel_expected); + softly.assertThat(wks_ostypemodel_actual).isEqualTo(wks_ostypemodel_expected); }); // Checking that the JSON file for Cost Savings Report has ISO Format Dates - ResponseEntity initialCostSavingsReportJSON = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", 1), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() {}); - assertThat(initialCostSavingsReportJSON.getBody().matches(".*creationDate\"\\:\"\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}.*")).isTrue(); + ResponseEntity initialCostSavingsReportJSON = new RestTemplate().exchange( + getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", analysisNum), + HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() { + }); + assertThat(initialCostSavingsReportJSON.getBody() + .matches(".*creationDate\"\\:\"\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}.*")).isTrue(); - // Checking that a NOT FOUND status code is returned when asking for a Initial Savings Report that doesnt exist + // Checking that a NOT FOUND status code is returned when asking for a Initial + // Savings Report that doesnt exist assertThatExceptionOfType(org.springframework.web.client.HttpClientErrorException.class) - .isThrownBy(() -> new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", 9999), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() {})) - .matches(e -> e.getStatusCode().equals(HttpStatus.NOT_FOUND)) - .matches(e -> e.getResponseBodyAsString().equalsIgnoreCase("Report not found")); + .isThrownBy(() -> new RestTemplate().exchange( + getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", 9999), + HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() { + })) + .matches(e -> e.getStatusCode().equals(HttpStatus.NOT_FOUND)) + .matches(e -> e.getResponseBodyAsString().equalsIgnoreCase("Report not found")); // OpenAPI Pagination Response test - ResponseEntity> workloadInventoryReportPagination = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); + ResponseEntity> workloadInventoryReportPagination = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); assertThat(workloadInventoryReportPagination.getBody().getMeta().getCount()).isEqualTo(14); assertThat(workloadInventoryReportPagination.getBody().getMeta().getOffset()).isEqualTo(0); assertThat(workloadInventoryReportPagination.getBody().getMeta().getLimit()).isEqualTo(100); - assertThat(workloadInventoryReportPagination.getBody().getLinks().getFirst()).isEqualTo(getBaseURLAPIPathWithoutHost() + String.format("/report/%d/workload-inventory?limit=100&offset=0", analysisNum)); - assertThat(workloadInventoryReportPagination.getBody().getLinks().getLast()).isEqualTo(getBaseURLAPIPathWithoutHost() + String.format("/report/%d/workload-inventory?limit=100&offset=0", analysisNum)); + assertThat(workloadInventoryReportPagination.getBody().getLinks().getFirst()) + .isEqualTo(getBaseURLAPIPathWithoutHost() + + String.format("/report/%d/workload-inventory?limit=100&offset=0", analysisNum)); + assertThat(workloadInventoryReportPagination.getBody().getLinks().getLast()) + .isEqualTo(getBaseURLAPIPathWithoutHost() + + String.format("/report/%d/workload-inventory?limit=100&offset=0", analysisNum)); assertThat(workloadInventoryReportPagination.getBody().getLinks().getPrev()).isNull(); assertThat(workloadInventoryReportPagination.getBody().getLinks().getNext()).isNull(); - workloadInventoryReportPagination = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?datacenter=Datacenter&cluster=VMCluster&limit=4&offset=8", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); + workloadInventoryReportPagination = new RestTemplate().exchange( + getBaseURLAPIPath() + String.format( + "/report/%d/workload-inventory?datacenter=Datacenter&cluster=VMCluster&limit=4&offset=8", + analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); assertThat(workloadInventoryReportPagination.getBody().getMeta().getCount()).isEqualTo(14); assertThat(workloadInventoryReportPagination.getBody().getMeta().getOffset()).isEqualTo(8); assertThat(workloadInventoryReportPagination.getBody().getMeta().getLimit()).isEqualTo(4); - assertThat(workloadInventoryReportPagination.getBody().getLinks().getFirst()).isEqualTo(getBaseURLAPIPathWithoutHost() + String.format("/report/%d/workload-inventory?datacenter=Datacenter&cluster=VMCluster&limit=4&offset=0", analysisNum)); - assertThat(workloadInventoryReportPagination.getBody().getLinks().getLast()).isEqualTo(getBaseURLAPIPathWithoutHost() + String.format("/report/%d/workload-inventory?datacenter=Datacenter&cluster=VMCluster&limit=4&offset=12", analysisNum)); - assertThat(workloadInventoryReportPagination.getBody().getLinks().getPrev()).isEqualTo(getBaseURLAPIPathWithoutHost() + String.format("/report/%d/workload-inventory?datacenter=Datacenter&cluster=VMCluster&limit=4&offset=4", analysisNum)); - assertThat(workloadInventoryReportPagination.getBody().getLinks().getNext()).isEqualTo(getBaseURLAPIPathWithoutHost() + String.format("/report/%d/workload-inventory?datacenter=Datacenter&cluster=VMCluster&limit=4&offset=12", analysisNum)); + assertThat(workloadInventoryReportPagination.getBody().getLinks().getFirst()) + .isEqualTo(getBaseURLAPIPathWithoutHost() + String.format( + "/report/%d/workload-inventory?datacenter=Datacenter&cluster=VMCluster&limit=4&offset=0", + analysisNum)); + assertThat(workloadInventoryReportPagination.getBody().getLinks().getLast()) + .isEqualTo(getBaseURLAPIPathWithoutHost() + String.format( + "/report/%d/workload-inventory?datacenter=Datacenter&cluster=VMCluster&limit=4&offset=12", + analysisNum)); + assertThat(workloadInventoryReportPagination.getBody().getLinks().getPrev()) + .isEqualTo(getBaseURLAPIPathWithoutHost() + String.format( + "/report/%d/workload-inventory?datacenter=Datacenter&cluster=VMCluster&limit=4&offset=4", + analysisNum)); + assertThat(workloadInventoryReportPagination.getBody().getLinks().getNext()) + .isEqualTo(getBaseURLAPIPathWithoutHost() + String.format( + "/report/%d/workload-inventory?datacenter=Datacenter&cluster=VMCluster&limit=4&offset=12", + analysisNum)); + + // Testing that limit and offset params are really taken into consideration + ResponseEntity> responseAnalysisModel = new RestTemplate().exchange( + getBaseURLAPIPath() + "/report?limit=2&offset=0", HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); + assertThat(responseAnalysisModel.getBody().getData().size()).isLessThanOrEqualTo(2); + logger.info("------- End Regular Test -------"); + + } + + @Test + public void whenPerformanceTestShouldAnswerInTime() throws Exception { + analysisNum++; // Performance test logger.info("+++++++ Performance Test ++++++"); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cfme_inventory-20190829-16128-uq17dx.tar.gz", "application/zip"), String.class); - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", ++analysisNum), timeoutMilliseconds_PerformaceTest)).isEqualTo(142); + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", + getRequestEntityForUploadRESTCall("cfme_inventory-20190829-16128-uq17dx.tar.gz", "application/zip"), + String.class); + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum), + timeoutMilliseconds_PerformaceTest)).isEqualTo(142); + logger.info("------- End Performance Test ------"); + } + + @Test + public void whenFileWithVMWithoutHostShouldAddVMToWorkloadInventory() throws Exception { + analysisNum++; // Test with a file with VM without Host logger.info("+++++++ Test with a file with VM without Host ++++++"); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0-vm_without_host.json", "application/json"), String.class); - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", ++analysisNum), timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(8); - - ResponseEntity> workloadInventoryReport_file_vm_without_host = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", + getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0-vm_without_host.json", "application/json"), + String.class); + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum), + timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(8); + + ResponseEntity> workloadInventoryReport_file_vm_without_host = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?size=100", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); assertThat(workloadInventoryReport_file_vm_without_host.getBody().getData().size()).isEqualTo(8); - assertThat(workloadInventoryReport_file_vm_without_host.getBody().getData().stream().filter(e -> e.getDatacenter().equalsIgnoreCase("No datacenter defined") && e.getCluster().equalsIgnoreCase("No cluster defined")).count()).isEqualTo(2); - assertThat(workloadInventoryReport_file_vm_without_host.getBody().getData().stream().filter(e -> !e.getDatacenter().equalsIgnoreCase("No datacenter defined") && !e.getCluster().equalsIgnoreCase("No cluster defined")).count()).isEqualTo(6); + assertThat(workloadInventoryReport_file_vm_without_host.getBody().getData().stream() + .filter(e -> e.getDatacenter().equalsIgnoreCase("No datacenter defined") + && e.getCluster().equalsIgnoreCase("No cluster defined")) + .count()).isEqualTo(2); + assertThat(workloadInventoryReport_file_vm_without_host.getBody().getData().stream() + .filter(e -> !e.getDatacenter().equalsIgnoreCase("No datacenter defined") + && !e.getCluster().equalsIgnoreCase("No cluster defined")) + .count()).isEqualTo(6); + logger.info("------- End file with VM without Host Test ------"); + } + + @Test + public void whenFileWithHostWithoutClusterShouldAddVMToWorkloadInventory() throws Exception { + analysisNum++; // Test with a file with Host without Cluster logger.info("+++++++ Test with a file with Host without Cluster ++++++"); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0-host_without_cluster.json", "application/json"), String.class); - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", ++analysisNum), timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(8); - - ResponseEntity> workloadInventoryReport_file_host_without_cluster = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall( + "cloudforms-export-v1_0_0-host_without_cluster.json", "application/json"), String.class); + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum), + timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(8); + + ResponseEntity> workloadInventoryReport_file_host_without_cluster = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); // Total VMs assertThat(workloadInventoryReport_file_host_without_cluster.getBody().getData().size()).isEqualTo(8); // Wrong VMs - assertThat(workloadInventoryReport_file_host_without_cluster.getBody().getData().stream().filter(e -> e.getDatacenter().equalsIgnoreCase("No datacenter defined") && e.getCluster().equalsIgnoreCase("No cluster defined")).count()).isEqualTo(3); + assertThat(workloadInventoryReport_file_host_without_cluster.getBody().getData().stream() + .filter(e -> e.getDatacenter().equalsIgnoreCase("No datacenter defined") + && e.getCluster().equalsIgnoreCase("No cluster defined")) + .count()).isEqualTo(3); // Right VMs - assertThat(workloadInventoryReport_file_host_without_cluster.getBody().getData().stream().filter(e -> !e.getDatacenter().equalsIgnoreCase("No datacenter defined") && !e.getCluster().equalsIgnoreCase("No cluster defined")).count()).isEqualTo(5); + assertThat(workloadInventoryReport_file_host_without_cluster.getBody().getData().stream() + .filter(e -> !e.getDatacenter().equalsIgnoreCase("No datacenter defined") + && !e.getCluster().equalsIgnoreCase("No cluster defined")) + .count()).isEqualTo(5); + logger.info("------- End file with Host without Cluster Test ------"); + } + + @Test + public void whenFileWithWrongCPUCoresPerSocketShouldNotFailAndFallbackTheValue() throws Exception { + analysisNum++; // Test with a file with Wrong CPU cores per socket logger.info("+++++++ Test with a file with Wrong CPU cores per socket ++++++"); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0-wrong_cpu_cores_per_socket.json", "application/json"), String.class); - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", ++analysisNum), timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(5); - - ResponseEntity initialCostSavingsReport_wrong_cpu_cores = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() {}); - assertThat(initialCostSavingsReport_wrong_cpu_cores.getBody().getEnvironmentModel().getHypervisors()).isEqualTo(2); - - ResponseEntity> workloadInventoryReport_file_wrong_cpu_cores = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); - assertThat(workloadInventoryReport_file_wrong_cpu_cores.getBody().getData().stream().filter(e -> e.getCpuCores() == null).count()).isEqualTo(0); - assertThat(workloadInventoryReport_file_wrong_cpu_cores.getBody().getData().stream().filter(e -> e.getCpuCores() != null).count()).isEqualTo(5); + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall( + "cloudforms-export-v1_0_0-wrong_cpu_cores_per_socket.json", "application/json"), String.class); + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum), + timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(5); + + ResponseEntity initialCostSavingsReport_wrong_cpu_cores = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference() { + }); + assertThat(initialCostSavingsReport_wrong_cpu_cores.getBody().getEnvironmentModel().getHypervisors()) + .isEqualTo(2); + + ResponseEntity> workloadInventoryReport_file_wrong_cpu_cores = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); + assertThat(workloadInventoryReport_file_wrong_cpu_cores.getBody().getData().stream() + .filter(e -> e.getCpuCores() == null).count()).isEqualTo(0); + assertThat(workloadInventoryReport_file_wrong_cpu_cores.getBody().getData().stream() + .filter(e -> e.getCpuCores() != null).count()).isEqualTo(5); assertThat(workloadInventoryReport_file_wrong_cpu_cores.getBody().getData().size()).isEqualTo(5); + logger.info("------- End Wrong CPU cores per socket Test ------"); + } + + @Test + public void whenFileWith0CPUCoresPerSocketShouldNotFailAndFallbackTheValue() throws Exception { + analysisNum++; // Test with a file with 0 CPU cores per socket logger.info("+++++++ Test with a file with 0 CPU cores per socket ++++++"); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0-vm_with_0_cores.json", "application/json"), String.class); - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", ++analysisNum), timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(8); - - ResponseEntity initialCostSavingsReport_zero_cpu_cores = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() {}); - assertThat(initialCostSavingsReport_zero_cpu_cores.getBody().getEnvironmentModel().getHypervisors()).isEqualTo(2); - - ResponseEntity> workloadInventoryReport_file_zero_cpu_cores = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); - assertThat(workloadInventoryReport_file_zero_cpu_cores.getBody().getData().stream().filter(e -> e.getCpuCores() == null).count()).isEqualTo(0); - assertThat(workloadInventoryReport_file_zero_cpu_cores.getBody().getData().stream().filter(e -> e.getCpuCores() != null).count()).isEqualTo(8); + ResponseEntity response = new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", + getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0-vm_with_0_cores.json", "application/json"), + String.class); + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum), + timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(8); + + ResponseEntity initialCostSavingsReport_zero_cpu_cores = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference() { + }); + assertThat(initialCostSavingsReport_zero_cpu_cores.getBody().getEnvironmentModel().getHypervisors()) + .isEqualTo(2); + + ResponseEntity> workloadInventoryReport_file_zero_cpu_cores = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); + assertThat(workloadInventoryReport_file_zero_cpu_cores.getBody().getData().stream() + .filter(e -> e.getCpuCores() == null).count()).isEqualTo(0); + assertThat(workloadInventoryReport_file_zero_cpu_cores.getBody().getData().stream() + .filter(e -> e.getCpuCores() != null).count()).isEqualTo(8); assertThat(workloadInventoryReport_file_zero_cpu_cores.getBody().getData().size()).isEqualTo(8); + logger.info("------- End 0 CPU cores per socket Test ------"); + + } + @Test + public void whenFileWithUsedDiskStorageShouldNotFailAndFallbackTheValue() throws Exception { + analysisNum++; // Test with a file with VM.used_disk_storage logger.info("+++++++ Test with a file with VM.used_disk_storage ++++++"); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0-vm_with_used_disk_storage.json", "application/json"), String.class); - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", ++analysisNum), timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(8); - - ResponseEntity initialCostSavingsReport_vm_with_used_disk = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() {}); - assertThat(initialCostSavingsReport_vm_with_used_disk.getBody().getEnvironmentModel().getHypervisors()).isEqualTo(4); - - ResponseEntity> workloadInventoryReport_vm_with_used_disk = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall( + "cloudforms-export-v1_0_0-vm_with_used_disk_storage.json", "application/json"), String.class); + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum), + timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(8); + + ResponseEntity initialCostSavingsReport_vm_with_used_disk = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/initial-saving-estimation", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference() { + }); + assertThat(initialCostSavingsReport_vm_with_used_disk.getBody().getEnvironmentModel().getHypervisors()) + .isEqualTo(4); + + ResponseEntity> workloadInventoryReport_vm_with_used_disk = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); assertThat(workloadInventoryReport_vm_with_used_disk.getBody().getData().size()).isEqualTo(8); assertThat(workloadInventoryReport_vm_with_used_disk.getBody().getData().stream() - .filter(e -> ("tomcat".equalsIgnoreCase(e.getVmName())) && (e.getDiskSpace() == 2159550464L)).count()).isEqualTo(1); + .filter(e -> ("tomcat".equalsIgnoreCase(e.getVmName())) && (e.getDiskSpace() == 2159550464L)).count()) + .isEqualTo(1); assertThat(workloadInventoryReport_vm_with_used_disk.getBody().getData().stream() - .filter(e -> ("lb".equalsIgnoreCase(e.getVmName())) && (e.getDiskSpace() == 2620260352L + 5000L)).count()).isEqualTo(1); - //NICs flag test + .filter(e -> ("lb".equalsIgnoreCase(e.getVmName())) && (e.getDiskSpace() == 2620260352L + 5000L)) + .count()).isEqualTo(1); + // NICs flag test assertThat(workloadInventoryReport_vm_with_used_disk.getBody().getData().stream() .filter(e -> e.getFlagsIMS().contains(">4 vNICs")).count()).isEqualTo(0); // Test Insights Enabled - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cfme_inventory-20200318-Insights.tar.gz", "application/zip"), String.class); - - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", ++analysisNum), timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(14); - - ResponseEntity> workloadInventoryReport_with_insights_enabled = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); + analysisNum++; + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", + getRequestEntityForUploadRESTCall("cfme_inventory-20200318-Insights.tar.gz", "application/zip"), + String.class); + + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum), + timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(14); + + ResponseEntity> workloadInventoryReport_with_insights_enabled = new RestTemplate() + .exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-inventory?limit=100", analysisNum), + HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference>() { + }); assertThat(workloadInventoryReport_with_insights_enabled.getBody().getData().size()).isEqualTo(14); - assertThat(workloadInventoryReport_with_insights_enabled.getBody().getData().stream().filter(e -> e.getInsightsEnabled()).count()).isEqualTo(2); + assertThat(workloadInventoryReport_with_insights_enabled.getBody().getData().stream() + .filter(e -> e.getInsightsEnabled()).count()).isEqualTo(2); // Test OSInformation, JavaRuntimes, and ApplicationPlatforms in WMS - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cfme_inventory-20200304-Linux_JDK.tar.gz", "application/zip"), String.class); - - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", ++analysisNum), timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(14); - - ResponseEntity workloadSummaryReportJavaRuntimes = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d/workload-summary", analysisNum), HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() {}); - WorkloadSummaryReportModel workloadSummaryReport_JavaRuntimesExpected = new ObjectMapper().readValue(IOUtils.resourceToString("cfme_inventory-20200304-Linux_JDK-summary-report.json", StandardCharsets.UTF_8, EndToEndTest.class.getClassLoader()), WorkloadSummaryReportModel.class); - - assertThat(workloadSummaryReportJavaRuntimes.getBody()) - .usingRecursiveComparison() - .ignoringFieldsMatchingRegexes(".*id.*", ".*creationDate.*", ".*report.*", ".*workloadsDetectedOSTypeModels.*", ".*scanRunModels.*") + analysisNum++; + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", + getRequestEntityForUploadRESTCall("cfme_inventory-20200304-Linux_JDK.tar.gz", "application/zip"), + String.class); + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum), + timeoutMilliseconds_InitialCostSavingsReport)).isEqualTo(14); + + ResponseEntity workloadSummaryReportJavaRuntimes = new RestTemplate().exchange( + getBaseURLAPIPath() + String.format("/report/%d/workload-summary", analysisNum), HttpMethod.GET, + getRequestEntity(), new ParameterizedTypeReference() { + }); + WorkloadSummaryReportModel workloadSummaryReport_JavaRuntimesExpected = new ObjectMapper() + .readValue( + IOUtils.resourceToString("cfme_inventory-20200304-Linux_JDK-summary-report.json", + StandardCharsets.UTF_8, EndToEndTest.class.getClassLoader()), + WorkloadSummaryReportModel.class); + + assertThat(workloadSummaryReportJavaRuntimes.getBody()).usingRecursiveComparison() + .ignoringFieldsMatchingRegexes(".*id.*", ".*creationDate.*", ".*report.*", + ".*workloadsDetectedOSTypeModels.*", ".*scanRunModels.*") .isEqualTo(workloadSummaryReport_JavaRuntimesExpected); + logger.info("------- End file with VM.used_disk_storage Test ------"); - // Ultra Performance test - logger.info("+++++++ Ultra Performance Test ++++++"); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cfme_inventory20190807-32152-jimd0q_large_dataset_5254_vms.tar.gz", "application/zip"), String.class); - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", ++analysisNum), timeoutMilliseconds_UltraPerformaceTest)).isEqualTo(numberVMsExpected_InBigFile); + } + @Test + public void whenSeveralAnalysisRunningLargerShouldNotAffectSmaller() throws Exception { // Stress test // We load 2 times a BIG file ( 8 Mb ) and 2 times a small file ( 316 Kb ) // More or less 7 minutes each bunch of threads of Big Files - // 1 bunch of threads for 2 big files and 1 small file, while 1 big file and 1 small file wait in the queue + // 1 bunch of threads for 2 big files and 1 small file, while 1 big file and 1 + // small file wait in the queue // We have 3 consumers // To process the first small file it should take 10 seconds - // To process the second small file it should take 7 minutes of the first bunch of big files plus 10 seconds of the small file + // To process the second small file it should take 7 minutes of the first bunch + // of big files plus 10 seconds of the small file logger.info("+++++++ Stress Test ++++++"); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cfme_inventory20190807-32152-jimd0q_large_dataset_5254_vms.tar.gz", "application/zip"), String.class); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0.json", "application/json"), String.class); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cfme_inventory-20190829-16128-uq17dx.tar.gz", "application/zip"), String.class); - new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0.json", "application/json"), String.class); - - // We will check for time we retrieve the third file uploaded to see previous ones are not affecting - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum + 2), timeoutMilliseconds_SmallFileSummaryReport)).isEqualTo(8); - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum + 1), timeoutMilliseconds_UltraPerformaceTest)).isEqualTo(numberVMsExpected_InBigFile); - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum + 3), timeoutMilliseconds_UltraPerformaceTest)).isEqualTo( 142); - - int timeoutMilliseconds_secondSmallFile = timeoutMilliseconds_UltraPerformaceTest + timeoutMilliseconds_SmallFileSummaryReport; - assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum + 4), timeoutMilliseconds_secondSmallFile)).isEqualTo( 8); + int firstupload = ++analysisNum; + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall( + "cfme_inventory20190807-32152-jimd0q_large_dataset_5254_vms.tar.gz", "application/zip"), String.class); + analysisNum++; + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", + getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0.json", "application/json"), String.class); + analysisNum++; + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall( + "cfme_inventory20190807-32152-jimd0q_large_dataset_5254_vms.tar.gz", "application/zip"), String.class); + analysisNum++; + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", + getRequestEntityForUploadRESTCall("cloudforms-export-v1_0_0.json", "application/json"), String.class); + // We will check for time we retrieve the third file uploaded to see previous + // ones are not affecting + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", firstupload + 1), + timeoutMilliseconds_SmallFileSummaryReport)).isEqualTo(8); + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", firstupload), + timeoutMilliseconds_UltraPerformaceTest)).isEqualTo(numberVMsExpected_InBigFile); + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", firstupload + 2), + timeoutMilliseconds_UltraPerformaceTest)).isEqualTo(numberVMsExpected_InBigFile); + + int timeoutMilliseconds_secondSmallFile = timeoutMilliseconds_UltraPerformaceTest + + timeoutMilliseconds_SmallFileSummaryReport; + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", firstupload + 3), + timeoutMilliseconds_secondSmallFile)).isEqualTo(8); + logger.info("------- End Stress Test ------"); + } + @Test + public void whenDeleteReportShouldRemoveFileInS3() throws Exception { // Testing the deletion of a file in S3 logger.info("++++++++ Delete report test +++++"); int s3ObjectsBefore = getStorageObjectsSize(); - ResponseEntity stringEntity = new RestTemplate().exchange(getBaseURLAPIPath() + String.format("/report/%d", 3), HttpMethod.DELETE, getRequestEntity(), new ParameterizedTypeReference() {}); - assertThat(stringEntity.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); + // we upload a file to be sure there's one report to delete, as it could be that + // this test is executed the first + new RestTemplate().postForEntity(getBaseURLAPIPath() + "/upload", getRequestEntityForUploadRESTCall( + "cloudforms-export-v1_0_0.json", "application/json"), String.class); + analysisNum++; + logger.info("... after upload"); - assertThat(initialSavingsEstimationReportService.findByAnalysisOwnerAndAnalysisId("dummy@redhat.com", 3L)).isNull(); - assertThat(getStorageObjectsSize()).isEqualTo(s3ObjectsBefore - 1); + await().atMost(20000, TimeUnit.MILLISECONDS).with().pollInterval(Duration.ONE_HUNDRED_MILLISECONDS).until(() -> { + return getStorageObjectsSize() == s3ObjectsBefore + 1; + }); + logger.info("... after S3 check"); - // Testing that limit and offset params are really taken into consideration - ResponseEntity> responseAnalysisModel = new RestTemplate().exchange(getBaseURLAPIPath() + "/report?limit=2&offset=0", HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference>() {}); - assertThat(responseAnalysisModel.getBody().getData().size()).isEqualTo(2); + assertThat(callSummaryReportAndCheckVMs(String.format("/report/%d/workload-summary", analysisNum), + timeoutMilliseconds_SmallFileSummaryReport)).isEqualTo(8); + + ResponseEntity stringEntity = new RestTemplate().exchange( + getBaseURLAPIPath() + String.format("/report/%d", analysisNum), HttpMethod.DELETE, getRequestEntity(), + new ParameterizedTypeReference() { + }); + logger.info("... after report"); + + assertThat(stringEntity.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); + assertThat(initialSavingsEstimationReportService.findByAnalysisOwnerAndAnalysisId("dummy@redhat.com", + Long.valueOf(analysisNum))).isNull(); + assertThat(getStorageObjectsSize()).isEqualTo(s3ObjectsBefore); + logger.info("--------- End Delete report test -------"); - camelContext.stop(); } private String getBaseURLAPIPath() { - return "http://localhost:" + serverPort + basePath.substring(0, basePath.length() - 1); // to remove the last * char + return "http://localhost:" + serverPort + basePath.substring(0, basePath.length() - 1); // to remove the last * + // char } private String getBaseURLAPIPathWithoutHost() { @@ -852,18 +891,19 @@ private String getBaseURLAPIPathWithoutHost() { private Integer callSummaryReportAndCheckVMs(final String reportUrl, int timeoutMilliseconds) { AtomicInteger numberVMsReceived = new AtomicInteger(0); - await() - .atMost(timeoutMilliseconds, TimeUnit.MILLISECONDS) - .with().pollInterval(Duration.ONE_SECOND) + await().atMost(timeoutMilliseconds, TimeUnit.MILLISECONDS).with().pollInterval(Duration.ONE_SECOND) .until(() -> { - ResponseEntity workloadSummaryReport_stress_checkVMs = new RestTemplate().exchange(getBaseURLAPIPath() + reportUrl, HttpMethod.GET, getRequestEntity(), new ParameterizedTypeReference() { - }); - boolean success = (workloadSummaryReport_stress_checkVMs != null && - workloadSummaryReport_stress_checkVMs.getStatusCodeValue() == 200 && - workloadSummaryReport_stress_checkVMs.getBody() != null && - workloadSummaryReport_stress_checkVMs.getBody().getSummaryModels() != null ); + ResponseEntity workloadSummaryReport_stress_checkVMs = new RestTemplate() + .exchange(getBaseURLAPIPath() + reportUrl, HttpMethod.GET, getRequestEntity(), + new ParameterizedTypeReference() { + }); + boolean success = (workloadSummaryReport_stress_checkVMs != null + && workloadSummaryReport_stress_checkVMs.getStatusCodeValue() == 200 + && workloadSummaryReport_stress_checkVMs.getBody() != null + && workloadSummaryReport_stress_checkVMs.getBody().getSummaryModels() != null); if (success) { - numberVMsReceived.set(workloadSummaryReport_stress_checkVMs.getBody().getSummaryModels().stream().mapToInt(SummaryModel::getVms).sum()); + numberVMsReceived.set(workloadSummaryReport_stress_checkVMs.getBody().getSummaryModels() + .stream().mapToInt(SummaryModel::getVms).sum()); } return success; }); @@ -889,7 +929,8 @@ private HttpEntity getRequestEntity() { } @NotNull - private HttpEntity> getRequestEntityForUploadRESTCall(String filename, String content_type_header) throws IOException { + private HttpEntity> getRequestEntityForUploadRESTCall(String filename, + String content_type_header) throws IOException { // Headers HttpHeaders headers = getHttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); @@ -901,7 +942,8 @@ private HttpEntity> getRequestEntityForUploadRESTC LinkedMultiValueMap fileMap = new LinkedMultiValueMap<>(); fileMap.add(HttpHeaders.CONTENT_DISPOSITION, "form-data; name=filex; filename=" + filename); fileMap.add("Content-type", content_type_header); - body.add("file", new HttpEntity<>(IOUtils.resourceToByteArray(filename, EndToEndTest.class.getClassLoader()), fileMap)); + body.add("file", + new HttpEntity<>(IOUtils.resourceToByteArray(filename, EndToEndTest.class.getClassLoader()), fileMap)); // params Body parts body.add("percentageOfHypervisorsMigratedOnYear1", "50"); @@ -921,13 +963,13 @@ private HttpHeaders getHttpHeaders() { // Headers HttpHeaders headers = new HttpHeaders(); headers.set("x-rh-insights-request-id", UUID.randomUUID().toString()); - String rhIdentityJson = "{\"entitlements\":{\"insights\":{\"is_entitled\":true},\"openshift\":{\"is_entitled\":true},\"smart_management\":{\"is_entitled\":false},\"hybrid_cloud\":{\"is_entitled\":true}}," + - "\"identity\":{\"internal\":{\"auth_time\":0,\"auth_type\":\"jwt-auth\",\"org_id\":\"6340056\", " + - //"\"filename\":\"" + filename + "\"," + + String rhIdentityJson = "{\"entitlements\":{\"insights\":{\"is_entitled\":true},\"openshift\":{\"is_entitled\":true},\"smart_management\":{\"is_entitled\":false},\"hybrid_cloud\":{\"is_entitled\":true}}," + + "\"identity\":{\"internal\":{\"auth_time\":0,\"auth_type\":\"jwt-auth\",\"org_id\":\"6340056\", " + + // "\"filename\":\"" + filename + "\"," + "\"origin\":\"xavier\",\"customerid\":\"CID888\"}," + // \"analysisId\":\"" + analysisId + "\"}," + "\"account_number\":\"1460290\", \"user\":{\"first_name\":\"User\",\"is_active\":true,\"is_internal\":true,\"last_name\":\"Dumy\",\"locale\":\"en_US\",\"is_org_admin\":false,\"username\":\"dummy@redhat.com\",\"email\":\"dummy+qa@redhat.com\"},\"type\":\"User\"}}"; - headers.set("x-rh-identity", Base64.encodeAsString(rhIdentityJson.getBytes()) ); + headers.set("x-rh-identity", Base64.encodeAsString(rhIdentityJson.getBytes())); headers.set("username", "dummy@redhat.com"); return headers; } diff --git a/src/test/java/org/jboss/xavier/integrations/TestContainersInfrastructure.java b/src/test/java/org/jboss/xavier/integrations/TestContainersInfrastructure.java new file mode 100644 index 00000000..485c36b0 --- /dev/null +++ b/src/test/java/org/jboss/xavier/integrations/TestContainersInfrastructure.java @@ -0,0 +1,307 @@ +package org.jboss.xavier.integrations; + +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.nio.file.Paths; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import javax.validation.constraints.NotNull; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.containers.Network; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.containers.localstack.LocalStackContainer; +import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.utility.MountableFile; + +public class TestContainersInfrastructure { + private static Logger logger = LoggerFactory.getLogger(TestContainersInfrastructure.class); + + private static String ingressCommitHash = "3ea33a8d793c2154f7cfa12057ca005c5f6031fa"; // 2019-11-11 + private static String insightsRbacCommitHash = "a55b610a1385f0f6d3188b08710ec6a5890a97f6"; // 2020-02-05 + + protected static GenericContainer kie_serverContainer = new GenericContainer<>("jboss/kie-server-showcase:7.18.0.Final").withNetworkAliases("kie-server") + .withExposedPorts(8080).withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("KIE-LOG")) + .withEnv("KIE_SERVER_ID", "analytics-kieserver").withEnv("KIE_ADMIN_USER", "kieserver") + .withEnv("KIE_ADMIN_PWD", "kieserver1!").withEnv("KIE_SERVER_MODE", "DEVELOPMENT") + .withEnv("KIE_MAVEN_REPO", "https://oss.sonatype.org/content/repositories/snapshots") + .withEnv("KIE_REPOSITORY", "https://repository.jboss.org/nexus/content/groups/public-jboss") + .withEnv("KIE_SERVER_CONTROLLER_PWD", "admin").withEnv("KIE_SERVER_CONTROLLER_USER", "admin") + .withEnv("KIE_SERVER_LOCATION", "http://kie-server:8080/kie-server/services/rest/server") + .withEnv("KIE_SERVER_PWD", "kieserver1!").withEnv("KIE_SERVER_USER", "kieserver"); + + protected static PostgreSQLContainer postgreSQLContainer=new PostgreSQLContainer().withDatabaseName("sampledb").withUsername("admin").withPassword("redhat"); + + protected static LocalStackContainer localstackContainer = new LocalStackContainer().withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("AWS-LOG")) + .withServices(S3); + + // INGRESS + private static Network ingressNetwork = Network.newNetwork(); + + protected static GenericContainer minioContainer = new GenericContainer<>("minio/minio").withCommand("server /data").withExposedPorts(9000) + .withNetworkAliases("minio").withNetwork(ingressNetwork) + .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("MINIO-LOG")) + .withEnv("MINIO_ACCESS_KEY", "BQA2GEXO711FVBVXDWKM") + .withEnv("MINIO_SECRET_KEY", "uvgz3LCwWM3e400cDkQIH/y1Y4xgU4iV91CwFSPC"); + + protected static GenericContainer createbucketsContainer=new GenericContainer<>("minio/mc").dependsOn(minioContainer) + .withNetwork(ingressNetwork) + .withStartupTimeout(java.time.Duration.ofSeconds(60)) + .withStartupAttempts(20) + .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("MINIO-MC-LOG")) + .withCopyFileToContainer(MountableFile.forClasspathResource("minio-bucket-creation-commands.sh"), "/") + .withCreateContainerCmdModifier(createContainerCmd -> createContainerCmd.withEntrypoint("sh", + "/minio-bucket-creation-commands.sh", "minio:9000")); + + protected static KafkaContainer kafkaContainer=new KafkaContainer().withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("KAFKA-LOG")) + .withNetworkAliases("kafka").withNetwork(ingressNetwork); + + protected static GenericContainer ingressContainer=new GenericContainer(new ImageFromDockerfile() + .withDockerfile(Paths.get("src/test/resources/insights-ingress-go/Dockerfile"))) + .withExposedPorts(3000) + .withNetwork(ingressNetwork) + .withLogConsumer(new Slf4jLogConsumer(logger) + .withPrefix("INGRESS-LOG")) + .withEnv("AWS_ACCESS_KEY_ID", "BQA2GEXO711FVBVXDWKM") + .withEnv("AWS_SECRET_ACCESS_KEY", "uvgz3LCwWM3e400cDkQIH/y1Y4xgU4iV91CwFSPC") + .withEnv("AWS_REGION", "us-east-1") + .withEnv("INGRESS_STAGEBUCKET", "insights-upload-perma") + .withEnv("INGRESS_REJECTBUCKET", "insights-upload-rejected") + .withEnv("INGRESS_INVENTORYURL", "http://inventory:8080/api/inventory/v1/hosts") + .withEnv("INGRESS_VALIDTOPICS", "xavier,testareno,advisortestareno,advisor") + .withEnv("OPENSHIFT_BUILD_COMMIT", "woopwoop") + .withEnv("INGRESS_MINIODEV", "true") + .withEnv("INGRESS_MINIOACCESSKEY", "BQA2GEXO711FVBVXDWKM") + .withEnv("INGRESS_MINIOSECRETKEY", "uvgz3LCwWM3e400cDkQIH/y1Y4xgU4iV91CwFSPC") + .withEnv("INGRESS_MINIOENDPOINT", "minio:9000") + .withEnv("INGRESS_KAFKABROKERS", "kafka:9092") + .dependsOn(kafkaContainer,localstackContainer, minioContainer,createbucketsContainer); + + + // RBAC + private static Network rbacNetwork = Network.newNetwork(); + + protected static GenericContainer rbacPostgreSQLContainer=new PostgreSQLContainer().withDatabaseName("rb_database").withUsername("rbac_username") + .withPassword("rbac_password").withNetwork(rbacNetwork).withNetworkAliases("rbac_db"); + + + protected static GenericContainer rbacServerContainer=new GenericContainer<>(new ImageFromDockerfile() + .withDockerfile(Paths.get("src/test/resources/insights-rbac/insightsRbac_Dockerfile"))) + .withNetwork(rbacNetwork).withNetworkAliases("rbac").withExposedPorts(8000) + .withEnv("DATABASE_SERVICE_NAME", "POSTGRES_SQL").withEnv("DATABASE_ENGINE", "postgresql") + .withEnv("DATABASE_NAME", "rb_database").withEnv("DATABASE_USER", "rbac_username") + .withEnv("DATABASE_PASSWORD", "rbac_password").withEnv("POSTGRES_SQL_SERVICE_HOST", "rbac_db") + .withEnv("POSTGRES_SQL_SERVICE_PORT", "5432") + .dependsOn(rbacPostgreSQLContainer); + + + @NotNull + public static String getContainerHost(GenericContainer container, Integer port) { + return container.getContainerIpAddress() + ":" + container.getMappedPort(port); + } + + @NotNull + public static String getContainerHost(GenericContainer container) { + return container.getContainerIpAddress() + ":" + container.getFirstMappedPort(); + } + + public static void stopAndDestroyDockerContainers() { + logger.info(">>> Stopping Docker Containers"); + kie_serverContainer.stop(); + postgreSQLContainer.stop(); + localstackContainer.stop(); + minioContainer.stop(); + createbucketsContainer.stop(); + kafkaContainer.stop(); + ingressContainer.stop(); + rbacPostgreSQLContainer.stop(); + rbacServerContainer.stop(); + } + + public static void createAndStartDockerContainers() throws IOException, InterruptedException { + cloneIngressRepoAndUnzip(); + cloneInsightsRbacRepo_UnzipAndConfigure(); + + logger.info(">>> Starting Docker Containers"); + minioContainer.start(); + postgreSQLContainer.start(); + localstackContainer.start(); + createbucketsContainer.start(); + kie_serverContainer.start(); + kafkaContainer.start(); + ingressContainer.start(); + rbacPostgreSQLContainer.start(); + rbacServerContainer.start(); + + importProjectIntoKIE(); + } + + private static void cloneIngressRepoAndUnzip() throws IOException { + // downloading, unzipping, renaming + String ingressRepoZipURL = "https://github.com/RedHatInsights/insights-ingress-go/archive/" + ingressCommitHash + + ".zip"; + File compressedFile = new File("src/test/resources/ingressRepo.zip"); + logger.info(">> downloading Ingress repo from " + ingressRepoZipURL); + FileUtils.copyURLToFile(new URL(ingressRepoZipURL), compressedFile, 1000, 10000); + unzipFile(compressedFile, "src/test/resources"); + + // we rename the directory because we had issues with Docker and the long folder + FileUtils.moveDirectory(new File("src/test/resources/insights-ingress-go-" + ingressCommitHash), + new File("src/test/resources/insights-ingress-go")); + } + + private static void cloneInsightsRbacRepo_UnzipAndConfigure() throws IOException { + // downloading, unzipping, renaming + String insightsRbacRepoZipURL = "https://github.com/RedHatInsights/insights-rbac/archive/" + + insightsRbacCommitHash + ".zip"; + File compressedFile = new File("src/test/resources/insightsRbacRepo.zip"); + logger.info(">> downloading RBAC repo from " + insightsRbacRepoZipURL); + FileUtils.copyURLToFile(new URL(insightsRbacRepoZipURL), compressedFile, 1000, 10000); + unzipFile(compressedFile, "src/test/resources"); + + // we rename the directory because we had issues with Docker and the long folder + FileUtils.moveDirectory(new File("src/test/resources/insights-rbac-" + insightsRbacCommitHash), + new File("src/test/resources/insights-rbac")); + + // Use custom Dockerfile + FileUtils.copyFile(new File("src/test/resources/insightsRbac_Dockerfile"), + new File("src/test/resources/insights-rbac/insightsRbac_Dockerfile")); + + // Configure default system roles for application=migration-analytics + FileUtils.copyFile(new File("src/test/resources/insightsRbac_roleDefinitions.json"), + new File("src/test/resources/insights-rbac/rbac/management/role/definitions/migration-analytics.json")); + } + + private static void unzipFile(File file, String outputDir) throws IOException { + java.util.zip.ZipFile zipFile = new ZipFile(file); + try { + Enumeration entries = zipFile.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + File entryDestination = new File(outputDir, entry.getName()); + if (entry.isDirectory()) { + entryDestination.mkdirs(); + } else { + entryDestination.getParentFile().mkdirs(); + InputStream in = zipFile.getInputStream(entry); + OutputStream out = new FileOutputStream(entryDestination); + IOUtils.copy(in, out); + in.close(); + out.close(); + } + } + } finally { + zipFile.close(); + } + } + + public static String getHostForKie() { + return kie_serverContainer.getContainerIpAddress() + ":" + kie_serverContainer.getFirstMappedPort(); + } + + private static void importProjectIntoKIE() throws InterruptedException, IOException { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.setCacheControl("no-cache"); + headers.set("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin + + String kieRestURL = "http://" + getHostForKie() + "/kie-server/services/rest/"; + + // KIE Container Creation + HttpHeaders kieheaders = new HttpHeaders(); + kieheaders.setContentType(MediaType.APPLICATION_JSON); + kieheaders.set("Authorization", "Basic a2llc2VydmVyOmtpZXNlcnZlcjEh"); + kieheaders.setCacheControl("no-cache"); + String kieContainerBody = "{\"container-id\" : \"xavier-analytics_0.0.1-SNAPSHOT\",\"release-id\" : {\"group-id\" : \"org.jboss.xavier\",\"artifact-id\" : \"xavier-analytics\",\"version\" : \"0.0.1-SNAPSHOT\" } }"; + try { + new RestTemplate().exchange(kieRestURL + "server/containers/xavier-analytics_0.0.1-SNAPSHOT", + HttpMethod.PUT, new HttpEntity<>(kieContainerBody, kieheaders), String.class); + } catch (RestClientException e) { + e.printStackTrace(); + } + } + + public static GenericContainer getKie_server() { + return kie_serverContainer; + } + + public static PostgreSQLContainer getPostgreSQL() { + return postgreSQLContainer; + } + + public static LocalStackContainer getLocalstack() { + return localstackContainer; + } + + public static GenericContainer getMinio() { + return minioContainer; + } + + public static GenericContainer getCreatebuckets() { + return createbucketsContainer; + } + + public static KafkaContainer getKafka() { + return kafkaContainer; + } + + public static GenericContainer getIngress() { + return ingressContainer; + } + + public static GenericContainer getRbacPostgreSQL() { + return rbacPostgreSQLContainer; + } + + public static GenericContainer getRbacServer() { + return rbacServerContainer; + } + + public static class SpringBootInitializerTestContainers implements ApplicationContextInitializer { + + @Override + public void initialize(ConfigurableApplicationContext configurableApplicationContext) { + + EnvironmentTestUtils.addEnvironment("test", configurableApplicationContext.getEnvironment(), + "minio.host=" + getContainerHost(getMinio(), 9000), + "insights.upload.host=" + getContainerHost(getIngress()), + "insights.properties=yearOverYearGrowthRatePercentage,percentageOfHypervisorsMigratedOnYear1,percentageOfHypervisorsMigratedOnYear2,percentageOfHypervisorsMigratedOnYear3,reportName,reportDescription", + "insights.kafka.host=" + getKafka().getBootstrapServers(), + "postgresql.service.name=" + getPostgreSQL().getContainerIpAddress(), + "postgresql.service.port=" + getPostgreSQL().getFirstMappedPort(), + "spring.datasource.username=" + getPostgreSQL().getUsername(), + "spring.datasource.password=" + getPostgreSQL().getPassword(), + "S3_HOST=" + getLocalstack().getEndpointConfiguration(S3).getServiceEndpoint(), + "S3_REGION="+ getLocalstack().getEndpointConfiguration(S3).getSigningRegion(), + "kieserver.devel-service=" + getHostForKie() + "/kie-server", + "spring.datasource.url = jdbc:postgresql://" + getContainerHost(getPostgreSQL()) + "/sampledb" , + "spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect" , + "thread.concurrentConsumers=3", + "insights.rbac.path=/api/v1/access/", + "insights.rbac.host=" + "http://" + getContainerHost(getRbacServer(), 8000)); + } + } +}