Skip to content

Commit a8c976b

Browse files
committed
Rebase and apply feedback
1 parent 2d852b9 commit a8c976b

File tree

3 files changed

+115
-202
lines changed

3 files changed

+115
-202
lines changed

plugins/discovery-ec2/qa/amazon-ec2/build.gradle

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,6 @@ dependencies {
2828
testCompile project(path: ':plugins:discovery-ec2', configuration: 'runtime')
2929
}
3030

31-
forbiddenApisTest {
32-
// we are using jdk-internal instead of jdk-non-portable to allow for com.sun.net.httpserver.* usage
33-
bundledSignatures -= 'jdk-non-portable'
34-
bundledSignatures += 'jdk-internal'
35-
}
36-
3731
final int ec2NumberOfNodes = 3
3832
File ec2DiscoveryFile = new File(project.buildDir, 'generated-resources/nodes.uri')
3933

@@ -69,7 +63,7 @@ integTestCluster {
6963
ec2DiscoveryFile.setText(integTest.nodes.collect { n -> "${n.transportUri()}" }.join('\n'), 'UTF-8')
7064

7165
File tmpFile = new File(node.cwd, 'wait.success')
72-
ant.get(src: "http://${node.httpUri()}/_cluster/health?wait_for_nodes=>=${ec2NumberOfNodes}&wait_for_status=yellow",
66+
ant.get(src: "http://${node.httpUri()}/",
7367
dest: tmpFile.toString(),
7468
ignoreerrors: true,
7569
retries: 10)

plugins/discovery-ec2/qa/amazon-ec2/src/test/java/org/elasticsearch/discovery/ec2/AmazonEC2Fixture.java

Lines changed: 108 additions & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -18,264 +18,177 @@
1818
*/
1919
package org.elasticsearch.discovery.ec2;
2020

21-
import com.amazonaws.util.IOUtils;
22-
import com.sun.net.httpserver.Headers;
23-
import com.sun.net.httpserver.HttpExchange;
24-
import com.sun.net.httpserver.HttpHandler;
25-
import com.sun.net.httpserver.HttpServer;
2621
import org.apache.http.NameValuePair;
2722
import org.apache.http.client.utils.URLEncodedUtils;
2823
import org.elasticsearch.common.SuppressForbidden;
29-
import org.elasticsearch.mocksocket.MockHttpServer;
3024
import org.elasticsearch.rest.RestStatus;
25+
import org.elasticsearch.test.fixture.AbstractHttpFixture;
3126

3227
import javax.xml.XMLConstants;
3328
import javax.xml.stream.XMLOutputFactory;
3429
import javax.xml.stream.XMLStreamWriter;
3530
import java.io.IOException;
3631
import java.io.StringWriter;
37-
import java.lang.management.ManagementFactory;
38-
import java.net.Inet6Address;
39-
import java.net.InetAddress;
40-
import java.net.InetSocketAddress;
41-
import java.net.SocketAddress;
42-
import java.nio.charset.StandardCharsets;
4332
import java.nio.file.Files;
4433
import java.nio.file.Path;
4534
import java.nio.file.Paths;
46-
import java.nio.file.StandardCopyOption;
47-
import java.util.List;
35+
import java.util.Objects;
4836
import java.util.UUID;
49-
import java.util.function.Predicate;
5037

51-
import static java.util.Collections.singleton;
52-
import static java.util.Collections.singletonList;
38+
import static java.nio.charset.StandardCharsets.UTF_8;
5339

5440
/**
5541
* {@link AmazonEC2Fixture} is a fixture that emulates an AWS EC2 service.
56-
* <p>
57-
* It starts an asynchronous socket server that binds to a random local port.
5842
*/
59-
public class AmazonEC2Fixture {
43+
public class AmazonEC2Fixture extends AbstractHttpFixture {
44+
45+
private final Path nodes;
46+
47+
private AmazonEC2Fixture(final String workingDir, final String nodesUriPath) {
48+
super(workingDir);
49+
this.nodes = toPath(Objects.requireNonNull(nodesUriPath));
50+
}
6051

6152
public static void main(String[] args) throws Exception {
6253
if (args == null || args.length != 2) {
6354
throw new IllegalArgumentException("AmazonEC2Fixture <working directory> <nodes transport uri file>");
6455
}
6556

66-
final InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
67-
final HttpServer httpServer = MockHttpServer.createHttp(socketAddress, 0);
68-
69-
try {
70-
final Path workingDirectory = toPath(args[0]);
71-
/// Writes the PID of the current Java process in a `pid` file located in the working directory
72-
writeFile(workingDirectory, "pid", ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
73-
74-
final String addressAndPort = addressToString(httpServer.getAddress());
75-
// Writes the address and port of the http server in a `ports` file located in the working directory
76-
writeFile(workingDirectory, "ports", addressAndPort);
77-
78-
httpServer.createContext("/", new ResponseHandler(toPath(args[1])));
79-
httpServer.start();
80-
81-
// Wait to be killed
82-
Thread.sleep(Long.MAX_VALUE);
83-
84-
} finally {
85-
httpServer.stop(0);
86-
}
87-
}
88-
89-
@SuppressForbidden(reason = "Paths#get is fine - we don't have environment here")
90-
private static Path toPath(final String dir) {
91-
return Paths.get(dir);
92-
}
93-
94-
private static void writeFile(final Path dir, final String fileName, final String content) throws IOException {
95-
final Path tempPidFile = Files.createTempFile(dir, null, null);
96-
Files.write(tempPidFile, singleton(content));
97-
Files.move(tempPidFile, dir.resolve(fileName), StandardCopyOption.ATOMIC_MOVE);
98-
}
99-
100-
private static String addressToString(final SocketAddress address) {
101-
final InetSocketAddress inetSocketAddress = (InetSocketAddress) address;
102-
if (inetSocketAddress.getAddress() instanceof Inet6Address) {
103-
return "[" + inetSocketAddress.getHostString() + "]:" + inetSocketAddress.getPort();
104-
} else {
105-
return inetSocketAddress.getHostString() + ":" + inetSocketAddress.getPort();
106-
}
57+
final AmazonEC2Fixture fixture = new AmazonEC2Fixture(args[0], args[1]);
58+
fixture.listen();
10759
}
10860

109-
static class ResponseHandler implements HttpHandler {
110-
111-
private final Path discoveryPath;
112-
113-
ResponseHandler(final Path discoveryPath) {
114-
this.discoveryPath = discoveryPath;
115-
}
116-
117-
@Override
118-
public void handle(HttpExchange exchange) throws IOException {
119-
RestStatus responseStatus = RestStatus.INTERNAL_SERVER_ERROR;
120-
String responseBody = null;
121-
String responseContentType = "text/plain";
122-
123-
final String path = exchange.getRequestURI().getRawPath();
124-
if ("/".equals(path)) {
125-
final String method = exchange.getRequestMethod();
126-
final Headers headers = exchange.getRequestHeaders();
127-
128-
if ("GET".equals(method) && matchingHeader(headers, "User-agent", v -> v.startsWith("Apache Ant"))) {
129-
// Replies to the fixture's waiting condition
130-
responseStatus = RestStatus.OK;
131-
responseBody = "AmazonEC2Fixture";
132-
133-
} else if ("POST".equals(method) && matchingHeader(headers, "User-agent", v -> v.startsWith("aws-sdk-java"))) {
134-
// Simulate an EC2 DescribeInstancesResponse
135-
responseStatus = RestStatus.OK;
136-
responseContentType = "text/xml; charset=UTF-8";
137-
138-
for (NameValuePair parse : URLEncodedUtils.parse(IOUtils.toString(exchange.getRequestBody()), StandardCharsets.UTF_8)) {
139-
if ("Action".equals(parse.getName())) {
140-
responseBody = generateDescribeInstancesResponse();
141-
break;
142-
}
143-
}
144-
}
145-
}
146-
147-
final byte[] response = responseBody != null ? responseBody.getBytes(StandardCharsets.UTF_8) : new byte[0];
148-
exchange.sendResponseHeaders(responseStatus.getStatus(), response.length);
149-
exchange.getResponseHeaders().put("Content-Type", singletonList(responseContentType));
150-
if (response.length > 0) {
151-
exchange.getResponseBody().write(response);
152-
}
153-
exchange.close();
154-
}
155-
156-
/** Checks if the given {@link Headers} contains a header with a given name which has a value that matches a predicate **/
157-
private boolean matchingHeader(final Headers headers, final String headerName, final Predicate<String> predicate) {
158-
if (headers != null && headers.isEmpty() == false) {
159-
final List<String> values = headers.get(headerName);
160-
if (values != null) {
161-
for (String value : values) {
162-
if (predicate.test(value)) {
163-
return true;
164-
}
61+
@Override
62+
protected Response handle(final Request request) throws IOException {
63+
if ("/".equals(request.getPath()) && ("POST".equals(request.getMethod()))) {
64+
final String userAgent = request.getHeader("User-Agent");
65+
if (userAgent != null && userAgent.startsWith("aws-sdk-java")) {
66+
// Simulate an EC2 DescribeInstancesResponse
67+
byte[] responseBody = EMPTY_BYTE;
68+
for (NameValuePair parse : URLEncodedUtils.parse(new String(request.getBody(), UTF_8), UTF_8)) {
69+
if ("Action".equals(parse.getName())) {
70+
responseBody = generateDescribeInstancesResponse();
71+
break;
16572
}
16673
}
74+
return new Response(RestStatus.OK.getStatus(), contentType("text/xml; charset=UTF-8"), responseBody);
16775
}
168-
return false;
16976
}
77+
return null;
78+
}
17079

171-
/**
172-
* Generates a XML response that describe the EC2 instances
173-
*/
174-
private String generateDescribeInstancesResponse() {
175-
final XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
176-
xmlOutputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
177-
178-
final StringWriter out = new StringWriter();
179-
XMLStreamWriter sw;
180-
try {
181-
sw = xmlOutputFactory.createXMLStreamWriter(out);
182-
sw.writeStartDocument();
80+
/**
81+
* Generates a XML response that describe the EC2 instances
82+
*/
83+
private byte[] generateDescribeInstancesResponse() {
84+
final XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
85+
xmlOutputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
18386

184-
String namespace = "http://ec2.amazonaws.com/doc/2013-02-01/";
185-
sw.setDefaultNamespace(namespace);
186-
sw.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, "DescribeInstancesResponse", namespace);
87+
final StringWriter out = new StringWriter();
88+
XMLStreamWriter sw;
89+
try {
90+
sw = xmlOutputFactory.createXMLStreamWriter(out);
91+
sw.writeStartDocument();
92+
93+
String namespace = "http://ec2.amazonaws.com/doc/2013-02-01/";
94+
sw.setDefaultNamespace(namespace);
95+
sw.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, "DescribeInstancesResponse", namespace);
96+
{
97+
sw.writeStartElement("requestId");
98+
sw.writeCharacters(UUID.randomUUID().toString());
99+
sw.writeEndElement();
100+
101+
sw.writeStartElement("reservationSet");
187102
{
188-
sw.writeStartElement("requestId");
189-
sw.writeCharacters(UUID.randomUUID().toString());
190-
sw.writeEndElement();
103+
if (Files.exists(nodes)) {
104+
for (String address : Files.readAllLines(nodes)) {
191105

192-
sw.writeStartElement("reservationSet");
193-
{
194-
if (Files.exists(discoveryPath)) {
195-
for (String address : Files.readAllLines(discoveryPath)) {
106+
sw.writeStartElement("item");
107+
{
108+
sw.writeStartElement("reservationId");
109+
sw.writeCharacters(UUID.randomUUID().toString());
110+
sw.writeEndElement();
196111

197-
sw.writeStartElement("item");
112+
sw.writeStartElement("instancesSet");
198113
{
199-
sw.writeStartElement("reservationId");
200-
sw.writeCharacters(UUID.randomUUID().toString());
201-
sw.writeEndElement();
202-
203-
sw.writeStartElement("instancesSet");
114+
sw.writeStartElement("item");
204115
{
205-
sw.writeStartElement("item");
206-
{
207-
sw.writeStartElement("instanceId");
208-
sw.writeCharacters(UUID.randomUUID().toString());
209-
sw.writeEndElement();
210-
211-
sw.writeStartElement("imageId");
212-
sw.writeCharacters(UUID.randomUUID().toString());
213-
sw.writeEndElement();
214-
215-
sw.writeStartElement("instanceState");
216-
{
217-
sw.writeStartElement("code");
218-
sw.writeCharacters("16");
219-
sw.writeEndElement();
116+
sw.writeStartElement("instanceId");
117+
sw.writeCharacters(UUID.randomUUID().toString());
118+
sw.writeEndElement();
220119

221-
sw.writeStartElement("name");
222-
sw.writeCharacters("running");
223-
sw.writeEndElement();
224-
}
225-
sw.writeEndElement();
120+
sw.writeStartElement("imageId");
121+
sw.writeCharacters(UUID.randomUUID().toString());
122+
sw.writeEndElement();
226123

227-
sw.writeStartElement("privateDnsName");
228-
sw.writeCharacters(address);
124+
sw.writeStartElement("instanceState");
125+
{
126+
sw.writeStartElement("code");
127+
sw.writeCharacters("16");
229128
sw.writeEndElement();
230129

231-
sw.writeStartElement("dnsName");
232-
sw.writeCharacters(address);
130+
sw.writeStartElement("name");
131+
sw.writeCharacters("running");
233132
sw.writeEndElement();
133+
}
134+
sw.writeEndElement();
234135

235-
sw.writeStartElement("instanceType");
236-
sw.writeCharacters("m1.medium");
237-
sw.writeEndElement();
136+
sw.writeStartElement("privateDnsName");
137+
sw.writeCharacters(address);
138+
sw.writeEndElement();
238139

239-
sw.writeStartElement("placement");
240-
{
241-
sw.writeStartElement("availabilityZone");
242-
sw.writeCharacters("use-east-1e");
243-
sw.writeEndElement();
140+
sw.writeStartElement("dnsName");
141+
sw.writeCharacters(address);
142+
sw.writeEndElement();
244143

245-
sw.writeEmptyElement("groupName");
144+
sw.writeStartElement("instanceType");
145+
sw.writeCharacters("m1.medium");
146+
sw.writeEndElement();
246147

247-
sw.writeStartElement("tenancy");
248-
sw.writeCharacters("default");
249-
sw.writeEndElement();
250-
}
148+
sw.writeStartElement("placement");
149+
{
150+
sw.writeStartElement("availabilityZone");
151+
sw.writeCharacters("use-east-1e");
251152
sw.writeEndElement();
252153

253-
sw.writeStartElement("privateIpAddress");
254-
sw.writeCharacters(address);
255-
sw.writeEndElement();
154+
sw.writeEmptyElement("groupName");
256155

257-
sw.writeStartElement("ipAddress");
258-
sw.writeCharacters(address);
156+
sw.writeStartElement("tenancy");
157+
sw.writeCharacters("default");
259158
sw.writeEndElement();
260159
}
261160
sw.writeEndElement();
161+
162+
sw.writeStartElement("privateIpAddress");
163+
sw.writeCharacters(address);
164+
sw.writeEndElement();
165+
166+
sw.writeStartElement("ipAddress");
167+
sw.writeCharacters(address);
168+
sw.writeEndElement();
262169
}
263170
sw.writeEndElement();
264171
}
265172
sw.writeEndElement();
266173
}
174+
sw.writeEndElement();
267175
}
268-
sw.writeEndElement();
269176
}
270177
sw.writeEndElement();
271-
272-
sw.writeEndDocument();
273-
sw.flush();
274178
}
275-
} catch (Exception e) {
276-
throw new RuntimeException(e);
179+
sw.writeEndElement();
180+
181+
sw.writeEndDocument();
182+
sw.flush();
277183
}
278-
return out.toString();
184+
} catch (Exception e) {
185+
throw new RuntimeException(e);
279186
}
187+
return out.toString().getBytes(UTF_8);
188+
}
189+
190+
@SuppressForbidden(reason = "Paths#get is fine - we don't have environment here")
191+
private static Path toPath(final String dir) {
192+
return Paths.get(dir);
280193
}
281194
}

0 commit comments

Comments
 (0)