DATAES-654 - Add Junit5 support.

Original PR: #329
This commit is contained in:
Peter-Josef Meisch 2019-10-20 20:05:33 +02:00 committed by GitHub
parent 4682636333
commit 58920af37a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 716 additions and 23 deletions

View File

@ -22,6 +22,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
import org.springframework.data.elasticsearch.junit.junit4.TestNodeResource;
/**
* configuration class for the classic ElasticsearchTemplate. Needs a {@link TestNodeResource} bean that should be set up in

View File

@ -0,0 +1,41 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.data.elasticsearch.junit.jupiter.ClusterConnectionInfo;
import org.springframework.data.elasticsearch.junit.jupiter.IntegrationTest;
import org.springframework.data.elasticsearch.junit.jupiter.SpringDataElasticsearchExtension;
/**
* Testing the setup and parameter injection of the CusterConnectionInfo.
*
* @author Peter-Josef Meisch
*/
@IntegrationTest
@DisplayName("a sample JUnit 5 test with a bare cluster connection")
public class JUnit5ClusterConnectionTests {
@Test
@DisplayName("should have the connection info injected")
void shouldHaveTheConnectionInfoInjected(ClusterConnectionInfo clusterConnectionInfo) {
assertThat(clusterConnectionInfo).isNotNull();
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.test.context.ContextConfiguration;
/**
* class demonstrating the setup of a JUnit 5 test in Spring Data Elasticsearch that uses the rest client. The
* ContextConfiguration must include the {@link ElasticsearchRestTemplateConfiguration} class.
*
* @author Peter-Josef Meisch
*/
@SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class})
@DisplayName("a sample JUnit 5 test with rest client")
public class JUnit5SampleRestClientBasedTests {
@Autowired private ElasticsearchOperations elasticsearchOperations;
@Test
@DisplayName("should have a ElasticsearchRestTemplate")
void shouldHaveARestTemplate() {
assertThat(elasticsearchOperations).isNotNull().isInstanceOf(ElasticsearchRestTemplate.class);
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.test.context.ContextConfiguration;
/**
* class demonstrating the setup of a JUnit 5 test in Spring Data Elasticsearch that uses the transport client. The
* ContextConfiguration must include the {@link ElasticsearchTemplateConfiguration} class
*
* @author Peter-Josef Meisch
*/
@SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class })
@DisplayName("a sample JUnit 5 test with transport client")
public class JUnit5SampleTransportClientBasedTests {
@Autowired private ElasticsearchOperations elasticsearchOperations;
@Test
@DisplayName("should have a ElasticsearchTemplate")
void shouldHaveATemplate() {
assertThat(elasticsearchOperations).isNotNull().isInstanceOf(ElasticsearchTemplate.class);
}
}

View File

@ -53,8 +53,8 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.elasticsearch.ElasticsearchVersion;
import org.springframework.data.elasticsearch.ElasticsearchVersionRule;
import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion;
import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersionRule;
import org.springframework.data.elasticsearch.TestUtils;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.http.HttpHeaders;

View File

@ -53,8 +53,8 @@ import org.springframework.data.annotation.Version;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.ElasticsearchVersion;
import org.springframework.data.elasticsearch.ElasticsearchVersionRule;
import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion;
import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersionRule;
import org.springframework.data.elasticsearch.TestUtils;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch;
package org.springframework.data.elasticsearch.junit.junit4;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch;
package org.springframework.data.elasticsearch.junit.junit4;
import java.util.concurrent.atomic.AtomicReference;
@ -23,6 +23,7 @@ import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.elasticsearch.TestUtils;
import org.springframework.data.util.Version;
/**

View File

@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch;
package org.springframework.data.elasticsearch.junit.junit4;
import java.io.IOException;
import org.elasticsearch.client.Client;
import org.elasticsearch.node.Node;
import org.junit.rules.ExternalResource;
import org.springframework.data.elasticsearch.Utils;
import org.springframework.util.Assert;
/**
@ -29,7 +30,7 @@ import org.springframework.util.Assert;
*/
public class TestNodeResource extends ExternalResource {
private static Node node;
private Node node;
@Override
protected void before() throws Throwable {

View File

@ -0,0 +1,5 @@
/**
* interfaces, annotations and classes related to JUnit 4 test handling.
*/
@org.springframework.lang.NonNullApi
package org.springframework.data.elasticsearch.junit.junit4;

View File

@ -0,0 +1,125 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch.junit.jupiter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.elasticsearch.node.Node;
import org.elasticsearch.node.NodeValidationException;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.elasticsearch.Utils;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
* This class manages the connection to an Elasticsearch Cluster, starting a local one if necessary. The information
* about the ClusterConnection is stored botha s a varaible in the instance for direct aaces from JUnit 5 and in a
* static ThreadLocal<ClusterConnectionInfo> acessible with the {@link ClusterConnection#clusterConnectionInfo()} method
* to be integrated in the Spring setup
*
* @author Peter-Josef Meisch
*/
class ClusterConnection implements ExtensionContext.Store.CloseableResource {
private static final Logger LOGGER = LoggerFactory.getLogger(ClusterConnection.class);
private static final ThreadLocal<ClusterConnectionInfo> clusterConnectionInfoThreadLocal = new ThreadLocal<>();
private Node node;
private final ClusterConnectionInfo clusterConnectionInfo;
/**
* creates the ClusterConnection, starting a local node if necessary.
*
* @param clusterUrl if null or empty a local cluster is tarted
*/
public ClusterConnection(@Nullable String clusterUrl) {
clusterConnectionInfo = StringUtils.isEmpty(clusterUrl) ? startLocalNode() : parseUrl(clusterUrl);
if (clusterConnectionInfo != null) {
LOGGER.debug(clusterConnectionInfo.toString());
clusterConnectionInfoThreadLocal.set(clusterConnectionInfo);
} else {
LOGGER.error("could not create ClusterConnectionInfo");
}
}
/**
* @return the {@link ClusterConnectionInfo} from the ThreadLocal storage.
*/
@Nullable
public static ClusterConnectionInfo clusterConnectionInfo() {
return clusterConnectionInfoThreadLocal.get();
}
public ClusterConnectionInfo getClusterConnectionInfo() {
return clusterConnectionInfo;
}
/**
* @param clusterUrl the URL to parse
* @return the connection information
*/
private ClusterConnectionInfo parseUrl(String clusterUrl) {
try {
URL url = new URL(clusterUrl);
if (!url.getProtocol().startsWith("http") || url.getPort() <= 0) {
throw new ClusterConnectionException("invalid url " + clusterUrl);
}
return ClusterConnectionInfo.builder() //
.withHostAndPort(url.getHost(), url.getPort()) //
.useSsl(url.getProtocol().equals("https")) //
.build();
} catch (MalformedURLException e) {
throw new ClusterConnectionException(e);
}
}
private @Nullable ClusterConnectionInfo startLocalNode() {
LOGGER.debug("starting local node");
try {
node = Utils.getNode();
node.start();
return ClusterConnectionInfo.builder() //
.withHostAndPort("localhost", 9200) //
.withClient(node.client()) //
.build();
} catch (NodeValidationException e) {
LOGGER.error("could not start local node", e);
}
return null;
}
@Override
public void close() throws Exception {
if (node != null) {
LOGGER.debug("closing node");
try {
node.close();
} catch (IOException ignored) {}
}
LOGGER.debug("closed");
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch.junit.jupiter;
/**
* @author Peter-Josef Meisch
*/
public class ClusterConnectionException extends RuntimeException {
public ClusterConnectionException(String message) {
super(message);
}
public ClusterConnectionException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch.junit.jupiter;
import org.elasticsearch.client.Client;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* The information about the ClusterConnection. the {@link #client} field is only set if a local node is started,
* otherwise it is null. <br/>
* The {@link #host}, {@link #httpPort} and {@link #useSsl} values specify the values needed to connect to the cluster
* with a rest client for both a local started cluster and for one defined by the cluster URL when creating the
* {@link ClusterConnection}. <br/>
* The object must be created by using a {@link ClusterConnectionInfo.Builder}.
*
* @author Peter-Josef Meisch
*/
public final class ClusterConnectionInfo {
private final boolean useSsl;
private final String host;
private final int httpPort;
private final Client client;
public static Builder builder() {
return new Builder();
}
private ClusterConnectionInfo(String host, int httpPort, boolean useSsl, Client client) {
this.host = host;
this.httpPort = httpPort;
this.useSsl = useSsl;
this.client = client;
}
@Override
public String toString() {
return "ClusterConnectionInfo{" + "useSsl=" + useSsl + ", host='" + host + '\'' + ", httpPort=" + httpPort
+ ", client=" + client + '}';
}
public String getHost() {
return host;
}
public int getHttpPort() {
return httpPort;
}
public boolean isUseSsl() {
return useSsl;
}
@Nullable
public Client getClient() {
return client;
}
public static class Builder {
boolean useSsl = false;
private String host;
private int httpPort;
private Client client = null;
public Builder withHostAndPort(String host, int httpPort) {
Assert.hasLength(host, "host must not be empty");
this.host = host;
this.httpPort = httpPort;
return this;
}
public Builder useSsl(boolean useSsl) {
this.useSsl = useSsl;
return this;
}
public Builder withClient(Client client) {
this.client = client;
return this;
}
public ClusterConnectionInfo build() {
return new ClusterConnectionInfo(host, httpPort, useSsl, client);
}
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch.junit.jupiter;
import java.time.Duration;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.util.Assert;
/**
* Configuration for Spring Data Elasticsearch using
* {@link org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate}. The required
* {@link ClusterConnectionInfo} bean must be provided by the testclass.
*
* @author Peter-Josef Meisch
*/
@Configuration
public class ElasticsearchRestTemplateConfiguration extends AbstractElasticsearchConfiguration {
@Autowired
private ClusterConnectionInfo clusterConnectionInfo;
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
String elasticsearchHostPort = clusterConnectionInfo.getHost() + ':' + clusterConnectionInfo.getHttpPort();
ClientConfiguration.TerminalClientConfigurationBuilder configurationBuilder = ClientConfiguration.builder()
.connectedTo(elasticsearchHostPort);
if (clusterConnectionInfo.isUseSsl()) {
configurationBuilder = ((ClientConfiguration.MaybeSecureClientConfigurationBuilder) configurationBuilder)
.usingSsl();
}
return RestClients.create(configurationBuilder //
.withConnectTimeout(Duration.ofSeconds(5)) //
.withSocketTimeout(Duration.ofSeconds(3)) //
.build()) //
.rest();
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch.junit.jupiter;
import org.elasticsearch.client.Client;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
import org.springframework.util.Assert;
/**
* Configuration for Spring Data Elasticsearch using
* {@link org.springframework.data.elasticsearch.core.ElasticsearchTemplate}.
*
* @author Peter-Josef Meisch
*/
@Configuration
public class ElasticsearchTemplateConfiguration extends ElasticsearchConfigurationSupport {
@Bean
public Client elasticsearchClient(ClusterConnectionInfo clusterConnectionInfo) {
return clusterConnectionInfo.getClient();
}
@Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
public ElasticsearchTemplate elasticsearchTemplate(Client elasticsearchClient,
MappingElasticsearchConverter entityMapper) {
return new ElasticsearchTemplate(elasticsearchClient, entityMapper);
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch.junit.jupiter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* Wraps the {@link SpringDataElasticsearchExtension}.
*
* @author Peter-Josef Meisch
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ExtendWith(SpringDataElasticsearchExtension.class)
public @interface IntegrationTest {
}

View File

@ -0,0 +1,112 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch.junit.jupiter;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory;
import org.springframework.test.context.MergedContextConfiguration;
/**
* This extension class check in the {@link #beforeAll(ExtensionContext)} call if there is already a Elasticsearch
* cluster connection defined in the root store. If no, the connection to the cluster is defined according to the
* configuration, starting a local node if necessary. The connection is stored and will be closed when the store is
* shutdown at the end of all tests.
* <p/>
* A ParameterResolver is implemented which enables resolving the ClusterConnectionInfo to test methods, and if a Spring
* context is used, the ClusterConnectionInfo can be autowired.
*
* @author Peter-Josef Meisch
*/
public class SpringDataElasticsearchExtension
implements BeforeAllCallback, ParameterResolver, ContextCustomizerFactory {
public static final String SPRING_DATA_ELASTICSEARCH_TEST_CLUSTER_URL = "SPRING_DATA_ELASTICSEARCH_TEST_CLUSTER_URL";
private static final Logger LOGGER = LoggerFactory.getLogger(SpringDataElasticsearchExtension.class);
private static final ExtensionContext.Namespace NAMESPACE = ExtensionContext.Namespace
.create(SpringDataElasticsearchExtension.class.getName());
private static final String STORE_KEY_CLUSTER_CONNECTION = ClusterConnection.class.getSimpleName();
private static final String STORE_KEY_CLUSTER_CONNECTION_INFO = ClusterConnectionInfo.class.getSimpleName();
private static final Lock initLock = new ReentrantLock();
@Override
public void beforeAll(ExtensionContext extensionContext) throws Exception {
initLock.lock();
try {
ExtensionContext.Store store = getStore(extensionContext);
ClusterConnection clusterConnection = store.getOrComputeIfAbsent(STORE_KEY_CLUSTER_CONNECTION, key -> {
LOGGER.debug("creating ClusterConnection");
return createClusterConnection();
}, ClusterConnection.class);
store.getOrComputeIfAbsent(STORE_KEY_CLUSTER_CONNECTION_INFO,
key -> clusterConnection.getClusterConnectionInfo());
} finally {
initLock.unlock();
}
}
private ExtensionContext.Store getStore(ExtensionContext extensionContext) {
return extensionContext.getRoot().getStore(NAMESPACE);
}
private ClusterConnection createClusterConnection() {
return new ClusterConnection(System.getenv(SPRING_DATA_ELASTICSEARCH_TEST_CLUSTER_URL));
}
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
Class<?> parameterType = parameterContext.getParameter().getType();
return parameterType.isAssignableFrom(ClusterConnectionInfo.class);
}
/*
* (non javadoc)
* no need to check the paramaterContext and extensionContext here, this was done before in supportsParameter.
*/
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
return getStore(extensionContext).get(STORE_KEY_CLUSTER_CONNECTION_INFO, ClusterConnectionInfo.class);
}
@Override
public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) {
return this::customizeContext;
}
private void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
context.getBeanFactory().registerResolvableDependency(ClusterConnectionInfo.class,
ClusterConnection.clusterConnectionInfo());
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2019 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 org.springframework.data.elasticsearch.junit.jupiter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* Combines the {@link SpringDataElasticsearchExtension} and the {@link SpringExtension}.
*
* @author Peter-Josef Meisch
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ExtendWith(SpringDataElasticsearchExtension.class)
@ExtendWith(SpringExtension.class)
public @interface SpringIntegrationTest {
}

View File

@ -0,0 +1,5 @@
/**
* interfaces, annotations and classes related to JUnit 5 test handling.
*/
@org.springframework.lang.NonNullApi
package org.springframework.data.elasticsearch.junit.jupiter;

View File

@ -19,7 +19,7 @@ import org.junit.ClassRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.ElasticsearchTestConfiguration;
import org.springframework.data.elasticsearch.TestNodeResource;
import org.springframework.data.elasticsearch.junit.junit4.TestNodeResource;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.test.context.ContextConfiguration;

View File

@ -16,13 +16,11 @@
package org.springframework.data.elasticsearch.repository.query.keywords;
import org.junit.ClassRule;
import org.junit.runner.RunWith;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.RestElasticsearchTestConfiguration;
import org.springframework.data.elasticsearch.TestNodeResource;
import org.springframework.data.elasticsearch.junit.junit4.TestNodeResource;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* {@link QueryKeywordsTests} using a Repository backed by an ElasticsearchRestTemplate.

View File

@ -52,7 +52,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.elasticsearch.TestNodeResource;
import org.springframework.data.elasticsearch.junit.junit4.TestNodeResource;
import org.springframework.data.elasticsearch.TestUtils;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;

View File

@ -45,7 +45,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.elasticsearch.RestElasticsearchTestConfiguration;
import org.springframework.data.elasticsearch.TestNodeResource;
import org.springframework.data.elasticsearch.junit.junit4.TestNodeResource;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;

View File

@ -0,0 +1 @@
org.springframework.test.context.ContextCustomizerFactory=org.springframework.data.elasticsearch.junit.jupiter.SpringDataElasticsearchExtension

View File

@ -1,17 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
</encoder>
</appender>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
</encoder>
</appender>
<logger name="org.springframework.data.elasticsearch.ElasticsearchVersionRule" level="info" />
<logger name="org.springframework.data.elasticsearch.junit" level="debug"/>
<logger name="org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersionRule" level="info"/>
<logger name="org.springframework.data.elasticsearch.client.WIRE" level="info"/>
<root level="error">
<appender-ref ref="console"/>
</root>
<root level="error">
<appender-ref ref="console"/>
</root>
</configuration>