16
16
*/
17
17
package org .graylog .testing .elasticsearch ;
18
18
19
+ import com .fasterxml .jackson .databind .JsonNode ;
20
+ import com .github .joschi .jadconfig .util .Duration ;
19
21
import com .github .zafarkhaja .semver .Version ;
20
- import com .google .common .io .Resources ;
22
+ import com .google .common .base .Stopwatch ;
23
+ import com .google .common .collect .ImmutableList ;
24
+ import io .searchbox .client .JestClient ;
25
+ import io .searchbox .cluster .State ;
26
+ import org .graylog .testing .PropertyLoader ;
27
+ import org .graylog2 .bindings .providers .JestClientProvider ;
28
+ import org .graylog2 .indexer .cluster .jest .JestUtils ;
29
+ import org .graylog2 .shared .bindings .providers .ObjectMapperProvider ;
21
30
import org .junit .rules .ExternalResource ;
22
- import org .testcontainers .containers .Network ;
31
+ import org .slf4j .Logger ;
32
+ import org .slf4j .LoggerFactory ;
23
33
import org .testcontainers .containers .wait .strategy .Wait ;
24
34
import org .testcontainers .elasticsearch .ElasticsearchContainer ;
25
- import org .testcontainers .utility .DockerImageName ;
26
35
27
- import java .net .URL ;
28
- import java .nio .file .Paths ;
36
+ import java .net .URI ;
29
37
import java .util .HashMap ;
30
- import java .util .Locale ;
31
38
import java .util .Map ;
39
+ import java .util .Properties ;
40
+ import java .util .concurrent .TimeUnit ;
41
+
42
+ import static com .google .common .collect .Iterators .toArray ;
32
43
33
44
/**
34
- * This rule starts an Elasticsearch instance and provides a configured {@link Client }.
45
+ * This rule starts an Elasticsearch instance and provides a configured {@link JestClient }.
35
46
*/
36
- public abstract class ElasticsearchInstance extends ExternalResource {
47
+ public class ElasticsearchInstance extends ExternalResource {
48
+
49
+ private static final Logger LOG = LoggerFactory .getLogger (ElasticsearchInstance .class );
50
+
37
51
private static final Map <Version , ElasticsearchContainer > containersByVersion = new HashMap <>();
38
52
53
+ private static final String PROPERTIES_RESOURCE_NAME = "elasticsearch.properties" ;
54
+
39
55
private static final String DEFAULT_IMAGE_OSS = "docker.elastic.co/elasticsearch/elasticsearch-oss" ;
40
56
private static final String DEFAULT_IMAGE = "elasticsearch" ;
57
+ private static final String DEFAULT_VERSION = "6.8.4" ;
41
58
42
- private static final int ES_PORT = 9200 ;
43
- private static final String NETWORK_ALIAS = "elasticsearch" ;
44
-
59
+ private final ElasticsearchContainer container ;
60
+ private JestClient jestClient ;
61
+ private Client client ;
62
+ private FixtureImporter fixtureImporter = new FixtureImporter ();
45
63
private final Version version ;
46
- protected final ElasticsearchContainer container ;
47
64
48
- protected abstract Client client ();
49
- protected abstract FixtureImporter fixtureImporter ();
65
+ public static ElasticsearchInstance create () {
66
+ final Properties properties = PropertyLoader .loadProperties (PROPERTIES_RESOURCE_NAME );
67
+
68
+ return create (properties .getProperty ("version" , DEFAULT_VERSION ));
69
+ }
70
+
71
+ public static ElasticsearchInstance create (String versionString ) {
72
+ final Version version = Version .valueOf (versionString );
73
+ final String image = imageNameFrom (version );
74
+
75
+ LOG .debug ("Creating instance {}" , image );
76
+
77
+ return new ElasticsearchInstance (image , version );
78
+ }
50
79
51
- protected static String imageNameFrom (Version version ) {
80
+ private static String imageNameFrom (Version version ) {
52
81
final String defaultImage = version .satisfies ("^6.0.0" )
53
82
// The OSS image only exists for 6.0.0 and later
54
83
? DEFAULT_IMAGE_OSS
@@ -57,60 +86,82 @@ protected static String imageNameFrom(Version version) {
57
86
return defaultImage + ":" + version .toString ();
58
87
}
59
88
60
- protected ElasticsearchInstance (String image , Version version , Network network ) {
89
+ private ElasticsearchInstance (String image , Version version ) {
61
90
this .version = version ;
62
-
63
- this .container = createContainer (image , version , network );
91
+ this .container = createContainer (image , version );
64
92
}
65
93
66
- private ElasticsearchContainer createContainer (String image , Version version , Network network ) {
94
+ private static ElasticsearchContainer createContainer (String image , Version version ) {
67
95
if (!containersByVersion .containsKey (version )) {
68
- ElasticsearchContainer container = buildContainer (image , network );
69
- container .start ();
70
- containersByVersion .put (version , container );
96
+ containersByVersion .put (version , startNewContainerInstance (image ));
71
97
}
72
98
return containersByVersion .get (version );
73
99
}
74
100
75
- private ElasticsearchContainer buildContainer (String image , Network network ) {
76
- return new ElasticsearchContainer (DockerImageName .parse (image ).asCompatibleSubstituteFor ("docker.elastic.co/elasticsearch/elasticsearch" ))
101
+ private static ElasticsearchContainer startNewContainerInstance (String image ) {
102
+ final Stopwatch sw = Stopwatch .createStarted ();
103
+
104
+ final ElasticsearchContainer container = new ElasticsearchContainer (image )
77
105
.withReuse (true )
78
- .withEnv ("ES_JAVA_OPTS" , "-Xms2g -Xmx2g " )
106
+ .withEnv ("ES_JAVA_OPTS" , "-Xms512m -Xmx512m " )
79
107
.withEnv ("discovery.type" , "single-node" )
80
- .withEnv ("action.auto_create_index" , ".watches,.triggered_watches,.watcher-history-*" )
81
- .withEnv ("cluster.info.update.interval" , "10s" )
82
- .withNetwork (network )
83
- .withNetworkAliases (NETWORK_ALIAS )
84
- .waitingFor (Wait .forHttp ("/" ).forPort (ES_PORT ));
108
+ .withEnv ("action.auto_create_index" , "false" )
109
+ .waitingFor (Wait .forHttp ("/" ).forPort (9200 ));
110
+ container .start ();
111
+ LOG .debug ("Started container {} in {}ms" , container .getContainerInfo ().getName (), sw .elapsed (TimeUnit .MILLISECONDS ));
112
+ return container ;
113
+ }
114
+
115
+ @ Override
116
+ protected void before () {
117
+ jestClient = new JestClientProvider (
118
+ ImmutableList .of (URI .create ("http://" + container .getHttpHostAddress ())),
119
+ Duration .seconds (60 ),
120
+ Duration .seconds (60 ),
121
+ Duration .seconds (60 ),
122
+ 1 ,
123
+ 1 ,
124
+ 1 ,
125
+ false ,
126
+ null ,
127
+ Duration .seconds (60 ),
128
+ false ,
129
+ new ObjectMapperProvider ().get ()
130
+ ).get ();
131
+
132
+ client = new Client (jestClient );
85
133
}
86
134
87
135
@ Override
88
136
protected void after () {
89
137
cleanUp ();
90
138
}
91
139
92
- public void cleanUp () {
93
- client ().cleanUp ();
140
+ private void cleanUp () {
141
+ final State request = new State .Builder ().withMetadata ().build ();
142
+ final JsonNode result = JestUtils .execute (jestClient , request , () -> "failed to read state" ).getJsonObject ();
143
+
144
+ client .deleteTemplates (metadataFieldNamesFor (result , "templates" ));
145
+ client .deleteIndices (metadataFieldNamesFor (result , "indices" ));
94
146
}
95
147
96
- public static String internalUri ( ) {
97
- return String . format ( Locale . US , "http://%s:%d" , NETWORK_ALIAS , ES_PORT );
148
+ private String [] metadataFieldNamesFor ( JsonNode result , String templates ) {
149
+ return toArray ( result . get ( "metadata" ). get ( templates ). fieldNames (), String . class );
98
150
}
99
151
100
152
public Version version () {
101
153
return version ;
102
154
}
103
155
104
- public void importFixtureResource (String resourcePath , Class <?> testClass ) {
105
- boolean isFullResourcePath = Paths .get (resourcePath ).getNameCount () > 1 ;
106
-
107
- @ SuppressWarnings ("UnstableApiUsage" ) final URL fixtureResource = isFullResourcePath
108
- ? Resources .getResource (resourcePath )
109
- : Resources .getResource (testClass , resourcePath );
156
+ public JestClient jestClient () {
157
+ return jestClient ;
158
+ }
110
159
111
- fixtureImporter ().importResource (fixtureResource );
160
+ public Client client () {
161
+ return client ;
162
+ }
112
163
113
- // Make sure the data we just imported is visible
114
- client (). refreshNode () ;
164
+ FixtureImporter fixtureImporter () {
165
+ return fixtureImporter ;
115
166
}
116
167
}
0 commit comments