diff --git a/spring-geode-tests/smoke-tests/locator-application/spring-geode-smoke-tests-locator-application.gradle b/spring-geode-tests/smoke-tests/locator-application/spring-geode-smoke-tests-locator-application.gradle new file mode 100644 index 00000000..97e57755 --- /dev/null +++ b/spring-geode-tests/smoke-tests/locator-application/spring-geode-smoke-tests-locator-application.gradle @@ -0,0 +1,18 @@ +apply plugin: 'io.spring.convention.spring-test' + +description = "Smoke Tests asserting the proper function of a Spring Boot configured and bootstrapped Apache Geode Locator application." + +dependencies { + + implementation "org.assertj:assertj-core" + + implementation project(':spring-geode-starter') + // implementation project(':spring-geode-starter-logging') + + testImplementation('org.springframework.boot:spring-boot-starter-test') { + exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' + } + + testImplementation project(":spring-geode-starter-test") + +} diff --git a/spring-geode-tests/smoke-tests/locator-application/src/main/java/example/app/geode/locator/SpringBootApacheGeodeLocatorApplication.java b/spring-geode-tests/smoke-tests/locator-application/src/main/java/example/app/geode/locator/SpringBootApacheGeodeLocatorApplication.java new file mode 100644 index 00000000..1cf59da6 --- /dev/null +++ b/spring-geode-tests/smoke-tests/locator-application/src/main/java/example/app/geode/locator/SpringBootApacheGeodeLocatorApplication.java @@ -0,0 +1,59 @@ +/* + * Copyright 2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package example.app.geode.locator; + +import org.apache.geode.distributed.Locator; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; +import org.springframework.data.gemfire.GemFireProperties; +import org.springframework.data.gemfire.config.annotation.LocatorApplication; +import org.springframework.data.gemfire.config.annotation.LocatorConfigurer; + +/** + * Spring Boot, Apache Geode {@link Locator} application. + * + * @author John Blum + * @see org.apache.geode.distributed.Locator + * @see org.springframework.boot.autoconfigure.SpringBootApplication + * @see org.springframework.context.annotation.Bean + * @see org.springframework.context.annotation.Profile + * @see org.springframework.data.gemfire.GemFireProperties + * @see org.springframework.data.gemfire.config.annotation.LocatorApplication + * @see org.springframework.data.gemfire.config.annotation.LocatorConfigurer + * @since 1.3.0 + */ +@SpringBootApplication +@LocatorApplication(name = "SpringBootApacheGeodeLocatorApplication", port = 0) +@SuppressWarnings("unused") +public class SpringBootApacheGeodeLocatorApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootApacheGeodeLocatorApplication.class, args); + } + + @Bean + @Profile("locator-configurer") + LocatorConfigurer clusterLocatorConfigurer( + @Value("${spring.data.gemfire.locators:localhost[10334]}") String locators) { + + return (beanName, bean) -> bean.getGemFireProperties() + .setProperty(GemFireProperties.LOCATORS.toString(), locators); + } +} diff --git a/spring-geode-tests/smoke-tests/locator-application/src/main/resources/gemfire.properties b/spring-geode-tests/smoke-tests/locator-application/src/main/resources/gemfire.properties new file mode 100644 index 00000000..03f8fd9e --- /dev/null +++ b/spring-geode-tests/smoke-tests/locator-application/src/main/resources/gemfire.properties @@ -0,0 +1,5 @@ +# Apache Geode properties + +enable-cluster-configuration=false; +http-service-port=0 +#locators=localhost[10334] diff --git a/spring-geode-tests/smoke-tests/locator-application/src/test/java/example/app/geode/locator/SpringBootApacheGeodeLocatorApplicationSmokeTests.java b/spring-geode-tests/smoke-tests/locator-application/src/test/java/example/app/geode/locator/SpringBootApacheGeodeLocatorApplicationSmokeTests.java new file mode 100644 index 00000000..864e419f --- /dev/null +++ b/spring-geode-tests/smoke-tests/locator-application/src/test/java/example/app/geode/locator/SpringBootApacheGeodeLocatorApplicationSmokeTests.java @@ -0,0 +1,149 @@ +/* + * Copyright 2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package example.app.geode.locator; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.apache.geode.distributed.DistributedMember; +import org.apache.geode.distributed.DistributedSystem; +import org.apache.geode.distributed.Locator; +import org.apache.geode.distributed.LocatorLauncher; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.gemfire.GemFireProperties; +import org.springframework.data.gemfire.config.annotation.LocatorApplicationConfiguration; +import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport; +import org.springframework.data.gemfire.util.ArrayUtils; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Smoke Tests for {@link SpringBootApacheGeodeLocatorApplication}. + * + * @author John Blum + * @see org.junit.Test + * @see org.apache.geode.distributed.DistributedSystem + * @see org.apache.geode.distributed.Locator + * @see org.apache.geode.distributed.LocatorLauncher + * @see org.springframework.boot.test.context.SpringBootTest + * @see org.springframework.data.gemfire.config.annotation.LocatorApplication + * @see org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport + * @see org.springframework.test.context.ActiveProfiles + * @see org.springframework.test.context.junit4.SpringRunner + * @since 1.3.0 + */ +@ActiveProfiles("locator-configurer") +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringBootApacheGeodeLocatorApplicationSmokeTests extends ForkingClientServerIntegrationTestsSupport { + + private static final String SPRING_DATA_GEMFIRE_LOCATORS_PROPERTY = "spring.data.gemfire.locators"; + + @Autowired + @SuppressWarnings("unused") + private Locator locator; + + @BeforeClass + public static void startGeodeLocator() throws IOException { + + int locatorPort = findAvailablePort(); + + long waitTimeout = TimeUnit.SECONDS.toMillis(10); + + startGemFireServer(ApacheGeodeLocator.class, String.valueOf(locatorPort)); + waitForServerToStart(ApacheGeodeLocator.HOSTNAME_FOR_CLIENTS, locatorPort, waitTimeout); + + System.setProperty(SPRING_DATA_GEMFIRE_LOCATORS_PROPERTY, + String.format("%1$s[%2$d]", ApacheGeodeLocator.HOSTNAME_FOR_CLIENTS, locatorPort)); + } + + @AfterClass + public static void stopGeodeLocator() { + stopGemFireServer(); + System.clearProperty(SPRING_DATA_GEMFIRE_LOCATORS_PROPERTY); + } + + @Test + public void geodeAndSpringLocatorsArePresent() { + + assertThat(this.locator).isNotNull(); + + DistributedSystem distributedSystem = this.locator.getDistributedSystem(); + + assertThat(distributedSystem).isNotNull(); + assertThat(distributedSystem.getAllOtherMembers()).hasSize(1); + + DistributedMember springLocatorMember = distributedSystem.getDistributedMember(); + + assertThat(springLocatorMember).isNotNull(); + assertThat(springLocatorMember.getName()).isEqualTo(SpringBootApacheGeodeLocatorApplication.class.getSimpleName()); + + DistributedMember geodeLocatorMember = distributedSystem.getAllOtherMembers().iterator().next(); + + assertThat(geodeLocatorMember).isNotNull(); + assertThat(geodeLocatorMember.getName()).isEqualTo(ApacheGeodeLocator.MEMBER_NAME); + } + + public static class ApacheGeodeLocator { + + private static final boolean DEBUG = false; + private static final boolean DELETE_PID_FILE_ON_STOP = true; + private static final boolean ENABLE_CLUSTER_CONFIGURATION = false; + + private static final int LOCATOR_DEFAULT_PORT = LocatorApplicationConfiguration.DEFAULT_PORT; + + private static final String HOSTNAME_FOR_CLIENTS = "localhost"; + private static final String MEMBER_NAME = ApacheGeodeLocator.class.getSimpleName(); + private static final String WORKING_DIRECTORY = "."; + + public static void main(String[] args) { + + int locatorPort = resolveLocatorPort(args); + + LocatorLauncher locatorLauncher = buildLocatorLauncher(locatorPort); + + locatorLauncher.start(); + locatorLauncher.waitOnLocator(); + } + + private static int resolveLocatorPort(String[] args) { + return ArrayUtils.isNotEmpty(args) ? Integer.parseInt(args[0]) : LOCATOR_DEFAULT_PORT; + } + + private static LocatorLauncher buildLocatorLauncher(int port) { + + return new LocatorLauncher.Builder() + .setDeletePidFileOnStop(DELETE_PID_FILE_ON_STOP) + .setDebug(DEBUG) + .setHostnameForClients(HOSTNAME_FOR_CLIENTS) + .setPort(port) + .setMemberName(MEMBER_NAME) + .setWorkingDirectory(WORKING_DIRECTORY) + .set(GemFireProperties.ENABLE_CLUSTER_CONFIGURATION.toString(), + String.valueOf(ENABLE_CLUSTER_CONFIGURATION)) + .build(); + } + } +}