From 49b35226c2dd09445bf83b738c6d1aa7fb528667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rg=20Prante?= Date: Mon, 6 May 2019 11:28:58 +0200 Subject: [PATCH] make HTTP client work --- build.gradle | 1 + .../elx/common/AbstractExtendedClient.java | 10 +- .../mapping/get/HttpGetMappingsAction.java | 61 +++++ .../org/xbib/elx/http/ExtendedHttpClient.java | 7 +- .../java/org/xbib/elx/http/HttpAction.java | 55 +++- .../health/HttpClusterHealthAction.java | 111 +------- .../health/HttpClusterHealthResponse.java | 215 +++++++++++++++ .../node/info/HttpNodesInfoAction.java | 6 +- .../HttpClusterUpdateSettingsAction.java | 5 + .../cluster/state/HttpClusterStateAction.java | 255 +++++++++++++++++- .../alias/HttpIndicesAliasesAction.java | 48 ++++ .../indices/alias/get/HttpGetAliasAction.java | 87 ++++++ .../indices/create/HttpCreateIndexAction.java | 5 + .../indices/delete/HttpDeleteIndexAction.java | 7 +- .../indices/HttpIndicesExistsAction.java | 47 ++++ .../refresh/HttpRefreshIndexAction.java | 9 +- .../settings/get/HttpGetSettingsAction.java | 91 +++++++ .../put/HttpUpdateSettingsAction.java | 10 +- .../elx/http/action/bulk/HttpBulkAction.java | 40 ++- .../elx/http/action/get/HttpExistsAction.java | 9 +- .../elx/http/action/get/HttpGetAction.java | 9 +- .../http/action/index/HttpIndexAction.java | 9 +- .../elx/http/action/main/HttpMainAction.java | 5 + .../http/action/search/HttpSearchAction.java | 10 +- .../http/action/update/HttpUpdateAction.java | 9 +- .../services/org.xbib.elx.http.HttpAction | 7 + .../org/xbib/elx/http/test/ClientTest.java | 2 - .../xbib/elx/http/test/DuplicateIDTest.java | 6 +- .../xbib/elx/http/test/IndexPruneTest.java | 2 - .../xbib/elx/http/test/IndexShiftTest.java | 5 +- .../org/xbib/elx/http/test/SmokeTest.java | 9 +- elx-http/src/test/resources/log4j2.xml | 2 +- .../xbib/elx/node/test/DuplicateIDTest.java | 2 +- .../org/xbib/elx/node/test/SmokeTest.java | 5 +- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 3 +- 36 files changed, 1000 insertions(+), 166 deletions(-) create mode 100644 elx-http/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/HttpGetMappingsAction.java create mode 100644 elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/health/HttpClusterHealthResponse.java create mode 100644 elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/alias/HttpIndicesAliasesAction.java create mode 100644 elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/alias/get/HttpGetAliasAction.java create mode 100644 elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/exists/indices/HttpIndicesExistsAction.java create mode 100644 elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/settings/get/HttpGetSettingsAction.java diff --git a/build.gradle b/build.gradle index b12951a..356bb11 100644 --- a/build.gradle +++ b/build.gradle @@ -95,6 +95,7 @@ subprojects { clean { delete "out" + delete "null" } /*javadoc { diff --git a/elx-common/src/main/java/org/xbib/elx/common/AbstractExtendedClient.java b/elx-common/src/main/java/org/xbib/elx/common/AbstractExtendedClient.java index 646e4db..54e0efa 100644 --- a/elx-common/src/main/java/org/xbib/elx/common/AbstractExtendedClient.java +++ b/elx-common/src/main/java/org/xbib/elx/common/AbstractExtendedClient.java @@ -33,9 +33,6 @@ import org.elasticsearch.action.admin.indices.get.GetIndexResponse; import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsAction; import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; -import org.elasticsearch.action.admin.indices.recovery.RecoveryAction; -import org.elasticsearch.action.admin.indices.recovery.RecoveryRequest; -import org.elasticsearch.action.admin.indices.recovery.RecoveryResponse; import org.elasticsearch.action.admin.indices.refresh.RefreshAction; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsAction; @@ -238,7 +235,8 @@ public abstract class AbstractExtendedClient implements ExtendedClient { public String getClusterName() { ensureActive(); try { - ClusterStateRequest clusterStateRequest = new ClusterStateRequest().all(); + ClusterStateRequest clusterStateRequest = new ClusterStateRequest(); + clusterStateRequest.clear(); ClusterStateResponse clusterStateResponse = client.execute(ClusterStateAction.INSTANCE, clusterStateRequest).actionGet(); return clusterStateResponse.getClusterName().value(); @@ -588,7 +586,11 @@ public abstract class AbstractExtendedClient implements ExtendedClient { public String resolveAlias(String alias) { ensureActive(); ClusterStateRequest clusterStateRequest = new ClusterStateRequest(); + clusterStateRequest.blocks(false); clusterStateRequest.metaData(true); + clusterStateRequest.nodes(false); + clusterStateRequest.routingTable(false); + clusterStateRequest.customs(false); ClusterStateResponse clusterStateResponse = client.execute(ClusterStateAction.INSTANCE, clusterStateRequest).actionGet(); SortedMap map = clusterStateResponse.getState().getMetaData().getAliasAndIndexLookup(); diff --git a/elx-http/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/HttpGetMappingsAction.java b/elx-http/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/HttpGetMappingsAction.java new file mode 100644 index 0000000..0a7afb1 --- /dev/null +++ b/elx-http/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/HttpGetMappingsAction.java @@ -0,0 +1,61 @@ +package org.elasticsearch.action.admin.indices.mapping.get; + +import org.elasticsearch.cluster.metadata.MappingMetaData; +import org.elasticsearch.common.CheckedFunction; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.xcontent.XContentParser; +import org.xbib.elx.http.HttpAction; +import org.xbib.netty.http.client.RequestBuilder; + +import java.io.IOException; +import java.util.Map; + +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; + +public class HttpGetMappingsAction extends HttpAction { + + private static final ParseField MAPPINGS = new ParseField("mappings"); + + @Override + public GetMappingsAction getActionInstance() { + return GetMappingsAction.INSTANCE; + } + + @Override + protected RequestBuilder createHttpRequest(String url, GetMappingsRequest request) { + String index = request.indices() != null ? "/" + String.join(",", request.indices()) : ""; + return newGetRequest(url, index + "/_mapping"); + } + + @Override + protected CheckedFunction entityParser() { + return this::fromXContent; + } + + @Override + protected GetMappingsResponse emptyResponse() { + return new GetMappingsResponse(); + } + + @SuppressWarnings("unchecked") + private GetMappingsResponse fromXContent(XContentParser parser) throws IOException { + XContentParser.Token token = parser.nextToken(); + ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation); + Map parts = parser.map(); + ImmutableOpenMap.Builder> builder = new ImmutableOpenMap.Builder<>(); + for (Map.Entry entry : parts.entrySet()) { + String indexName = entry.getKey(); + Map mapping = (Map) ((Map) entry.getValue()).get(MAPPINGS.getPreferredName()); + ImmutableOpenMap.Builder typeBuilder = new ImmutableOpenMap.Builder<>(); + for (Map.Entry typeEntry : mapping.entrySet()) { + String typeName = typeEntry.getKey(); + Map fieldMappings = (Map) typeEntry.getValue(); + MappingMetaData mmd = new MappingMetaData(typeName, fieldMappings); + typeBuilder.put(typeName, mmd); + } + builder.put(indexName, typeBuilder.build()); + } + return new GetMappingsResponse(builder.build()); + } +} \ No newline at end of file diff --git a/elx-http/src/main/java/org/xbib/elx/http/ExtendedHttpClient.java b/elx-http/src/main/java/org/xbib/elx/http/ExtendedHttpClient.java index 0e8241b..639ea83 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/ExtendedHttpClient.java +++ b/elx-http/src/main/java/org/xbib/elx/http/ExtendedHttpClient.java @@ -1,5 +1,6 @@ package org.xbib.elx.http; +import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.Action; @@ -79,7 +80,7 @@ public class ExtendedHttpClient extends AbstractExtendedClient implements Elasti clientBuilder.enableDebug(); } this.nettyHttpClient = clientBuilder.build(); - logger.info("extended HTTP client initialized, settings = {}, url = {}, {} actions", + logger.log(Level.DEBUG, "extended HTTP client initialized, settings = {}, url = {}, {} actions", settings, url, actionMap.size()); return this; } @@ -136,7 +137,7 @@ public class ExtendedHttpClient extends AbstractExtendedClient implements Elasti @Override public ThreadPool threadPool() { - logger.info("returning null for threadPool() request"); + logger.log(Level.DEBUG, "returning null for threadPool() request"); return null; } @@ -149,8 +150,8 @@ public class ExtendedHttpClient extends AbstractExtendedClient implements Elasti } try { HttpActionContext httpActionContext = new HttpActionContext(this, request, url); + logger.log(Level.DEBUG, "url = " + url); httpAction.execute(httpActionContext, listener); - logger.debug("submitted to URL {}", url); } catch (Exception e) { logger.error(e.getMessage(), e); } diff --git a/elx-http/src/main/java/org/xbib/elx/http/HttpAction.java b/elx-http/src/main/java/org/xbib/elx/http/HttpAction.java index 844dae3..2d647c8 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/HttpAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/HttpAction.java @@ -3,8 +3,11 @@ package org.xbib.elx.http; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpResponseStatus; +import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionRequestValidationException; @@ -14,8 +17,11 @@ import org.elasticsearch.common.CheckedFunction; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.DeprecationHandler; +import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.rest.BytesRestResponse; +import org.elasticsearch.rest.RestStatus; import org.xbib.netty.http.client.Request; import org.xbib.netty.http.client.RequestBuilder; import org.xbib.netty.http.client.transport.Transport; @@ -33,7 +39,7 @@ public abstract class HttpAction httpActionContext, ActionListener listener) throws IOException { + final void execute(HttpActionContext httpActionContext, ActionListener listener) throws IOException { try { ActionRequestValidationException validationException = httpActionContext.getRequest().validate(); if (validationException != null) { @@ -59,22 +65,29 @@ public abstract class HttpAction { - logger.info("returned response " + fullHttpResponse.status().code() + + logger.log(Level.DEBUG, "got response: " + fullHttpResponse.status().code() + " headers = " + fullHttpResponse.headers().entries() + " content = " + fullHttpResponse.content().toString(StandardCharsets.UTF_8)); - listener.onResponse(parseToResponse(httpActionContext.setHttpResponse(fullHttpResponse))); + httpActionContext.setHttpResponse(fullHttpResponse); + if (fullHttpResponse.status().equals(HttpResponseStatus.OK)) { + listener.onResponse(parseToResponse(httpActionContext)); + } else { + ElasticsearchStatusException statusException = parseToError(httpActionContext); + if (statusException.status().equals(RestStatus.NOT_FOUND)) { + listener.onResponse(emptyResponse()); + } else { + listener.onFailure(statusException); + } + } }); Transport transport = httpActionContext.getExtendedHttpClient().internalClient().execute(httpRequest); - logger.info("transport = " + transport); httpActionContext.setHttpClientTransport(transport); if (transport.isFailed()) { listener.onFailure(new Exception(transport.getFailure())); } - logger.info("done, listener is " + listener); } catch (Throwable e) { listener.onFailure(new RuntimeException(e)); throw new IOException(e); @@ -82,7 +95,7 @@ public abstract class HttpAction httpActionContext) { + try (XContentParser parser = XContentFactory.xContent(XContentType.JSON) + .createParser(httpActionContext.getExtendedHttpClient().getRegistry(), + DeprecationHandler.THROW_UNSUPPORTED_OPERATION, + httpActionContext.getHttpResponse().content().toString(StandardCharsets.UTF_8))) { + return errorParser().apply(parser); + } catch (IOException e) { + logger.error(e.getMessage(), e); + return new ElasticsearchStatusException(e.getMessage(), RestStatus.INTERNAL_SERVER_ERROR, e); + } + } + + protected CheckedFunction errorParser() { + return BytesRestResponse::errorFromXContent; + } + protected abstract RequestBuilder createHttpRequest(String baseUrl, R request) throws IOException; protected abstract CheckedFunction entityParser(); + protected abstract T emptyResponse(); + } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/health/HttpClusterHealthAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/health/HttpClusterHealthAction.java index 5ed27be..a79ac00 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/health/HttpClusterHealthAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/health/HttpClusterHealthAction.java @@ -3,23 +3,12 @@ package org.xbib.elx.http.action.admin.cluster.health; import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; -import org.elasticsearch.cluster.health.ClusterHealthStatus; -import org.elasticsearch.cluster.health.ClusterIndexHealth; import org.elasticsearch.common.CheckedFunction; -import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.common.xcontent.ConstructingObjectParser; import org.elasticsearch.common.xcontent.XContentParser; import org.xbib.elx.http.HttpAction; import org.xbib.netty.http.client.RequestBuilder; import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static java.util.Collections.emptyMap; -import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; public class HttpClusterHealthAction extends HttpAction { @@ -30,106 +19,16 @@ public class HttpClusterHealthAction extends HttpAction entityParser() { - throw new UnsupportedOperationException(); + return HttpClusterHealthResponse::fromXContent; } - private static final String CLUSTER_NAME = "cluster_name"; - private static final String STATUS = "status"; - private static final String TIMED_OUT = "timed_out"; - private static final String NUMBER_OF_NODES = "number_of_nodes"; - private static final String NUMBER_OF_DATA_NODES = "number_of_data_nodes"; - private static final String NUMBER_OF_PENDING_TASKS = "number_of_pending_tasks"; - private static final String NUMBER_OF_IN_FLIGHT_FETCH = "number_of_in_flight_fetch"; - private static final String DELAYED_UNASSIGNED_SHARDS = "delayed_unassigned_shards"; - private static final String TASK_MAX_WAIT_TIME_IN_QUEUE = "task_max_waiting_in_queue"; - private static final String TASK_MAX_WAIT_TIME_IN_QUEUE_IN_MILLIS = "task_max_waiting_in_queue_millis"; - private static final String ACTIVE_SHARDS_PERCENT_AS_NUMBER = "active_shards_percent_as_number"; - private static final String ACTIVE_SHARDS_PERCENT = "active_shards_percent"; - private static final String ACTIVE_PRIMARY_SHARDS = "active_primary_shards"; - private static final String ACTIVE_SHARDS = "active_shards"; - private static final String RELOCATING_SHARDS = "relocating_shards"; - private static final String INITIALIZING_SHARDS = "initializing_shards"; - private static final String UNASSIGNED_SHARDS = "unassigned_shards"; - private static final String INDICES = "indices"; - - private static final ConstructingObjectParser PARSER = - new ConstructingObjectParser<>("cluster_health_response", true, - parsedObjects -> { - int i = 0; - // ClusterStateHealth fields - int numberOfNodes = (int) parsedObjects[i++]; - int numberOfDataNodes = (int) parsedObjects[i++]; - int activeShards = (int) parsedObjects[i++]; - int relocatingShards = (int) parsedObjects[i++]; - int activePrimaryShards = (int) parsedObjects[i++]; - int initializingShards = (int) parsedObjects[i++]; - int unassignedShards = (int) parsedObjects[i++]; - double activeShardsPercent = (double) parsedObjects[i++]; - String statusStr = (String) parsedObjects[i++]; - ClusterHealthStatus status = ClusterHealthStatus.fromString(statusStr); - @SuppressWarnings("unchecked") List indexList = - (List) parsedObjects[i++]; - final Map indices; - if (indexList == null || indexList.isEmpty()) { - indices = emptyMap(); - } else { - indices = new HashMap<>(indexList.size()); - for (ClusterIndexHealth indexHealth : indexList) { - indices.put(indexHealth.getIndex(), indexHealth); - } - } - /*ClusterStateHealth stateHealth = new ClusterStateHealth(activePrimaryShards, activeShards, relocatingShards, - initializingShards, unassignedShards, numberOfNodes, numberOfDataNodes, activeShardsPercent, status, - indices);*/ - //ClusterState clusterState = new ClusterState(); - //ClusterStateHealth clusterStateHealth = new ClusterStateHealth(clusterState, concreteIndices); - - // ClusterHealthResponse fields - String clusterName = (String) parsedObjects[i++]; - int numberOfPendingTasks = (int) parsedObjects[i++]; - int numberOfInFlightFetch = (int) parsedObjects[i++]; - int delayedUnassignedShards = (int) parsedObjects[i++]; - long taskMaxWaitingTimeMillis = (long) parsedObjects[i++]; - boolean timedOut = (boolean) parsedObjects[i]; - - return new ClusterHealthResponse(clusterName, null, null, numberOfPendingTasks, - numberOfInFlightFetch, delayedUnassignedShards, - TimeValue.timeValueMillis(taskMaxWaitingTimeMillis)); - /*return new ClusterHealthResponse(clusterName, numberOfPendingTasks, numberOfInFlightFetch, - delayedUnassignedShards, - TimeValue.timeValueMillis(taskMaxWaitingTimeMillis), timedOut, stateHealth);*/ - }); - - - // private static final ObjectParser.NamedObjectParser INDEX_PARSER = - // (XContentParser parser, Void context, String index) -> ClusterIndexHealth.innerFromXContent(parser, index); - - static { - // ClusterStateHealth fields - PARSER.declareInt(constructorArg(), new ParseField(NUMBER_OF_NODES)); - PARSER.declareInt(constructorArg(), new ParseField(NUMBER_OF_DATA_NODES)); - PARSER.declareInt(constructorArg(), new ParseField(ACTIVE_SHARDS)); - PARSER.declareInt(constructorArg(), new ParseField(RELOCATING_SHARDS)); - PARSER.declareInt(constructorArg(), new ParseField(ACTIVE_PRIMARY_SHARDS)); - PARSER.declareInt(constructorArg(), new ParseField(INITIALIZING_SHARDS)); - PARSER.declareInt(constructorArg(), new ParseField(UNASSIGNED_SHARDS)); - PARSER.declareDouble(constructorArg(), new ParseField(ACTIVE_SHARDS_PERCENT_AS_NUMBER)); - PARSER.declareString(constructorArg(), new ParseField(STATUS)); - // Can be absent if LEVEL == 'cluster' - //PARSER.declareNamedObjects(optionalConstructorArg(), INDEX_PARSER, new ParseField(INDICES)); - - // ClusterHealthResponse fields - PARSER.declareString(constructorArg(), new ParseField(CLUSTER_NAME)); - PARSER.declareInt(constructorArg(), new ParseField(NUMBER_OF_PENDING_TASKS)); - PARSER.declareInt(constructorArg(), new ParseField(NUMBER_OF_IN_FLIGHT_FETCH)); - PARSER.declareInt(constructorArg(), new ParseField(DELAYED_UNASSIGNED_SHARDS)); - PARSER.declareLong(constructorArg(), new ParseField(TASK_MAX_WAIT_TIME_IN_QUEUE_IN_MILLIS)); - PARSER.declareBoolean(constructorArg(), new ParseField(TIMED_OUT)); + @Override + protected ClusterHealthResponse emptyResponse() { + return new HttpClusterHealthResponse(); } - } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/health/HttpClusterHealthResponse.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/health/HttpClusterHealthResponse.java new file mode 100644 index 0000000..2a4c3a1 --- /dev/null +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/health/HttpClusterHealthResponse.java @@ -0,0 +1,215 @@ +package org.xbib.elx.http.action.admin.cluster.health; + +import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.cluster.health.ClusterHealthStatus; +import org.elasticsearch.cluster.health.ClusterIndexHealth; +import org.elasticsearch.cluster.health.ClusterStateHealth; +import org.elasticsearch.common.io.stream.BytesStreamOutput; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.rest.RestStatus; + +import java.io.IOException; +import java.util.Collections; +import java.util.Map; + +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; + +public class HttpClusterHealthResponse extends ClusterHealthResponse { + + private static final String CLUSTER_NAME = "cluster_name"; + private static final String STATUS = "status"; + private static final String TIMED_OUT = "timed_out"; + private static final String NUMBER_OF_NODES = "number_of_nodes"; + private static final String NUMBER_OF_DATA_NODES = "number_of_data_nodes"; + private static final String NUMBER_OF_PENDING_TASKS = "number_of_pending_tasks"; + private static final String NUMBER_OF_IN_FLIGHT_FETCH = "number_of_in_flight_fetch"; + private static final String DELAYED_UNASSIGNED_SHARDS = "delayed_unassigned_shards"; + private static final String TASK_MAX_WAIT_TIME_IN_QUEUE = "task_max_waiting_in_queue"; + private static final String TASK_MAX_WAIT_TIME_IN_QUEUE_IN_MILLIS = "task_max_waiting_in_queue_millis"; + private static final String ACTIVE_SHARDS_PERCENT_AS_NUMBER = "active_shards_percent_as_number"; + private static final String ACTIVE_SHARDS_PERCENT = "active_shards_percent"; + private static final String ACTIVE_PRIMARY_SHARDS = "active_primary_shards"; + private static final String ACTIVE_SHARDS = "active_shards"; + private static final String RELOCATING_SHARDS = "relocating_shards"; + private static final String INITIALIZING_SHARDS = "initializing_shards"; + private static final String UNASSIGNED_SHARDS = "unassigned_shards"; + private static final String INDICES = "indices"; + + private String clusterName; + + private ClusterStateHealth clusterStateHealth; + + private boolean timedOut; + + private int delayedUnassignedShards; + + private int numberOfPendingTasks; + + private int numberOfInFlightFetch; + + public HttpClusterHealthResponse() { + } + + private void init(String clusterName, + ClusterHealthStatus clusterHealthStatus, + boolean timedOut, + int numberOfNodes, + int numberOfDataNodes, + Map indices, + int activePrimaryShards, + int activeShards, + int relocatingShards, + int initializingShards, + int unassignedShards, + int delayedUnassignedShards, + int numberOfPendingTasks, int numberOfInFlightFetch, + TimeValue taskMaxWaitingTime, + double activeShardsPercent) throws IOException { + this.clusterName = clusterName; + BytesStreamOutput streamOutput = new BytesStreamOutput(); + streamOutput.writeVInt(activePrimaryShards); + streamOutput.writeVInt(activeShards); + streamOutput.writeVInt(relocatingShards); + streamOutput.writeVInt(initializingShards); + streamOutput.writeVInt(unassignedShards); + streamOutput.writeVInt(numberOfNodes); + streamOutput.writeVInt(numberOfDataNodes); + streamOutput.writeByte(clusterHealthStatus.value()); + streamOutput.writeVInt(indices.size()); + for (ClusterIndexHealth indexHealth : indices.values()) { + indexHealth.writeTo(streamOutput); + } + streamOutput.writeDouble(activeShardsPercent); + this.clusterStateHealth = new ClusterStateHealth(streamOutput.bytes().streamInput()); + this.timedOut = timedOut; + this.delayedUnassignedShards = delayedUnassignedShards; + this.numberOfPendingTasks = numberOfPendingTasks; + this.numberOfInFlightFetch = numberOfInFlightFetch; + } + + @Override + public String getClusterName() { + return clusterName; + } + + @Override + public ClusterStateHealth getClusterStateHealth() { + return clusterStateHealth; + } + + @Override + public boolean isTimedOut() { + return this.timedOut; + } + + @Override + public int getActiveShards() { + return clusterStateHealth.getActiveShards(); + } + + @Override + public int getRelocatingShards() { + return clusterStateHealth.getRelocatingShards(); + } + + @Override + public int getActivePrimaryShards() { + return clusterStateHealth.getActivePrimaryShards(); + } + + @Override + public int getInitializingShards() { + return clusterStateHealth.getInitializingShards(); + } + + @Override + public int getUnassignedShards() { + return clusterStateHealth.getUnassignedShards(); + } + + @Override + public int getDelayedUnassignedShards() { + return delayedUnassignedShards; + } + + @Override + public int getNumberOfNodes() { + return clusterStateHealth.getNumberOfNodes(); + } + + @Override + public int getNumberOfDataNodes() { + return clusterStateHealth.getNumberOfDataNodes(); + } + + @Override + public int getNumberOfPendingTasks() { + return numberOfPendingTasks; + } + + @Override + public int getNumberOfInFlightFetch() { + return numberOfInFlightFetch; + } + + @Override + public ClusterHealthStatus getStatus() { + return clusterStateHealth.getStatus(); + } + + @Override + public Map getIndices() { + return clusterStateHealth.getIndices(); + } + + @Override + public double getActiveShardsPercent() { + return clusterStateHealth.getActiveShardsPercent(); + } + + @Override + public RestStatus status() { + return isTimedOut() ? RestStatus.REQUEST_TIMEOUT : RestStatus.OK; + } + + public static HttpClusterHealthResponse fromXContent(XContentParser parser) throws IOException { + XContentParser.Token token = parser.nextToken(); + ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation); + Map map = parser.map(); + String clusterName = (String) map.get(CLUSTER_NAME); + ClusterHealthStatus status = ClusterHealthStatus.fromString((String) map.get(STATUS)); + Boolean timedOut = (Boolean) map.get(TIMED_OUT); + Integer numberOfNodes = (Integer) map.get(NUMBER_OF_NODES); + Integer numberOfDataNodes = (Integer) map.get(NUMBER_OF_DATA_NODES); + Integer activePrimaryShards = (Integer) map.get(ACTIVE_PRIMARY_SHARDS); + Integer activeShards = (Integer) map.get(ACTIVE_SHARDS); + Integer relocatingShards = (Integer) map.get(RELOCATING_SHARDS); + Integer initializingShards = (Integer) map.get(INITIALIZING_SHARDS); + Integer unassignedShards = (Integer) map.get(UNASSIGNED_SHARDS); + Integer delayedUnassignedShards = (Integer) map.get(DELAYED_UNASSIGNED_SHARDS); + Integer numberOfPendingTasks = (Integer) map.get(NUMBER_OF_PENDING_TASKS); + Integer numberOfInFlightFetch = (Integer) map.get(NUMBER_OF_IN_FLIGHT_FETCH); + Integer taskMaxWaitingInQueueMillis = (Integer) map.get(TASK_MAX_WAIT_TIME_IN_QUEUE_IN_MILLIS); + Double activeShardsPercentAsNumber = (Double) map.get(ACTIVE_SHARDS_PERCENT_AS_NUMBER); + HttpClusterHealthResponse clusterHealthResponse = new HttpClusterHealthResponse(); + clusterHealthResponse.init(clusterName, + status, + timedOut, + numberOfNodes, + numberOfDataNodes, + Collections.emptyMap(), + activePrimaryShards, + activeShards, + relocatingShards, + initializingShards, + unassignedShards, + delayedUnassignedShards, + numberOfPendingTasks, + numberOfInFlightFetch, + TimeValue.timeValueMillis(taskMaxWaitingInQueueMillis), + activeShardsPercentAsNumber + ); + return clusterHealthResponse; + } +} \ No newline at end of file diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/node/info/HttpNodesInfoAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/node/info/HttpNodesInfoAction.java index 619f80a..f513b5d 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/node/info/HttpNodesInfoAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/node/info/HttpNodesInfoAction.java @@ -99,10 +99,14 @@ public class HttpNodesInfoAction extends HttpAction httpContext) { Map map = null; - String string = (String)map.get("cluster_name"); ClusterName clusterName = new ClusterName(string); List nodeInfoList = new LinkedList<>(); diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/settings/HttpClusterUpdateSettingsAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/settings/HttpClusterUpdateSettingsAction.java index f5d9631..972c34a 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/settings/HttpClusterUpdateSettingsAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/settings/HttpClusterUpdateSettingsAction.java @@ -43,4 +43,9 @@ public class HttpClusterUpdateSettingsAction extends HttpAction entityParser() { return ClusterUpdateSettingsResponse::fromXContent; } + + @Override + protected ClusterUpdateSettingsResponse emptyResponse() { + return new ClusterUpdateSettingsResponse(); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/state/HttpClusterStateAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/state/HttpClusterStateAction.java index 5adf01c..d540b68 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/state/HttpClusterStateAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/cluster/state/HttpClusterStateAction.java @@ -1,17 +1,47 @@ package org.xbib.elx.http.action.admin.cluster.state; +import com.carrotsearch.hppc.LongArrayList; +import org.apache.logging.log4j.Level; import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; +import org.elasticsearch.cluster.ClusterName; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.cluster.metadata.IndexTemplateMetaData; +import org.elasticsearch.cluster.metadata.MappingMetaData; +import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.common.CheckedFunction; +import org.elasticsearch.common.collect.MapBuilder; +import org.elasticsearch.common.compress.CompressedXContent; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.NamedObjectNotFoundException; import org.elasticsearch.common.xcontent.XContentParser; import org.xbib.elx.http.HttpAction; import org.xbib.netty.http.client.RequestBuilder; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; public class HttpClusterStateAction extends HttpAction { + private static final String CLUSTER_NAME = "cluster_name"; + + private static final String COMPRESSED_SIZE_IN_BYTES = "compressed_size_in_bytes"; + + private static final String BLOCKS = "blocks"; + + private static final String NODES = "nodes"; + + private static final String METADATA = "metadata"; + @Override public ClusterStateAction getActionInstance() { return ClusterStateAction.INSTANCE; @@ -19,11 +49,232 @@ public class HttpClusterStateAction extends HttpAction list = new ArrayList<>(); + if (request.metaData()) { + list.add("metadata"); + } + if (request.blocks()) { + list.add("blocks"); + } + if (request.nodes()) { + list.add("nodes"); + } + if (request.routingTable()) { + list.add("routing_table"); + } + if (request.customs()) { + list.add("customs"); + } + if (list.isEmpty()) { + list.add("_all"); + } + return newGetRequest(url, "/_cluster/state/" + String.join(",", list) + + "/" + String.join(",", request.indices())); } @Override protected CheckedFunction entityParser() { - throw new UnsupportedOperationException(); + return this::fromXContent; + } + + @Override + protected ClusterStateResponse emptyResponse() { + return new ClusterStateResponse(); + } + + private ClusterStateResponse fromXContent(XContentParser parser) throws IOException { + XContentParser.Token token = parser.nextToken(); + ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation); + ClusterName clusterName = null; + ClusterState.Builder builder = null; + Integer length = null; + String currentFieldName = parser.currentName(); + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token.isValue()) { + if (CLUSTER_NAME.equals(currentFieldName)) { + clusterName = new ClusterName(parser.text()); + builder = ClusterState.builder(clusterName); + } + if (COMPRESSED_SIZE_IN_BYTES.equals(currentFieldName)) { + length = parser.intValue(); + } + } + if (METADATA.equals(currentFieldName)) { + // MetaData.fromXContent(parser) is broken because of "meta-data" + parser.nextToken(); + builder.metaData(metadataFromXContent(parser)); + } + + } + ClusterState clusterState = builder.build(); + return new ClusterStateResponse(clusterName, clusterState, length); + } + + private MetaData metadataFromXContent(XContentParser parser) throws IOException { + MetaData.Builder builder = new MetaData.Builder(); + XContentParser.Token token = parser.currentToken(); + String currentFieldName = parser.currentName(); + if (token != XContentParser.Token.START_OBJECT) { + throw new IllegalArgumentException("Expected a START_OBJECT but got " + token); + } + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token == XContentParser.Token.START_OBJECT) { + if ("settings".equals(currentFieldName)) { + builder.persistentSettings(Settings.fromXContent(parser)); + } else if ("indices".equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + //IndexMetaData.Builder.fromXContent is broken + //builder.put(IndexMetaData.Builder.fromXContent(parser), false); + builder.put(indexMetaDataFromXContent(parser), false); + } + } else if ("templates".equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + builder.put(IndexTemplateMetaData.Builder.fromXContent(parser, parser.currentName())); + } + } else if ("index-graveyard".equals(currentFieldName)) { + parser.skipChildren(); + } else { + try { + MetaData.Custom custom = parser.namedObject(MetaData.Custom.class, currentFieldName, null); + builder.putCustom(custom.getWriteableName(), custom); + } catch (NamedObjectNotFoundException ex) { + logger.warn("Skipping unknown custom object with type {}", currentFieldName); + parser.skipChildren(); + } + } + } else if (token.isValue()) { + if ("version".equals(currentFieldName)) { + // private field + //builder.version = parser.longValue(); + } else if ("cluster_uuid".equals(currentFieldName) || "uuid".equals(currentFieldName)) { + // private field + //builder.clusterUUID = parser.text(); + } else { + throw new IllegalArgumentException("Unexpected field [" + currentFieldName + "]"); + } + } else { + throw new IllegalArgumentException("Unexpected token " + token); + } + } + return builder.build(); + } + + private static final String KEY_IN_SYNC_ALLOCATIONS = "in_sync_allocations"; + private static final String KEY_VERSION = "version"; + private static final String KEY_ROUTING_NUM_SHARDS = "routing_num_shards"; + private static final String KEY_SETTINGS = "settings"; + private static final String KEY_STATE = "state"; + private static final String KEY_MAPPINGS = "mappings"; + private static final String KEY_ALIASES = "aliases"; + private static final String KEY_PRIMARY_TERMS = "primary_terms"; + + private IndexMetaData indexMetaDataFromXContent(XContentParser parser) throws IOException { + if (parser.currentToken() == null) { // fresh parser? move to the first token + parser.nextToken(); + } + if (parser.currentToken() == XContentParser.Token.START_OBJECT) { // on a start object move to next token + parser.nextToken(); + } + if (parser.currentToken() != XContentParser.Token.FIELD_NAME) { + throw new IllegalArgumentException("expected field name but got a " + parser.currentToken()); + } + IndexMetaData.Builder builder = new IndexMetaData.Builder(parser.currentName()); + String currentFieldName = null; + XContentParser.Token token = parser.nextToken(); + if (token != XContentParser.Token.START_OBJECT) { + throw new IllegalArgumentException("expected object but got a " + token); + } + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token == XContentParser.Token.START_OBJECT) { + if (KEY_SETTINGS.equals(currentFieldName)) { + builder.settings(Settings.fromXContent(parser)); + } else if (KEY_MAPPINGS.equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token == XContentParser.Token.START_OBJECT) { + Map mappingSource = MapBuilder.newMapBuilder().put(currentFieldName, parser.mapOrdered()).map(); + builder.putMapping(new MappingMetaData(currentFieldName, mappingSource)); + } else { + throw new IllegalArgumentException("Unexpected token: " + token); + } + } + } else if (KEY_ALIASES.equals(currentFieldName)) { + while (parser.nextToken() != XContentParser.Token.END_OBJECT) { + builder.putAlias(AliasMetaData.Builder.fromXContent(parser)); + } + } else if (KEY_IN_SYNC_ALLOCATIONS.equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token == XContentParser.Token.START_ARRAY) { + Set allocationIds = new HashSet<>(); + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + if (token == XContentParser.Token.VALUE_STRING) { + allocationIds.add(parser.text()); + } + } + builder.putInSyncAllocationIds(Integer.valueOf(currentFieldName), allocationIds); + } else { + throw new IllegalArgumentException("Unexpected token: " + token); + } + } + } else if (KEY_PRIMARY_TERMS.equals(currentFieldName)) { + parser.skipChildren(); // TODO + } else { + throw new IllegalArgumentException("Unexpected field for an object " + currentFieldName); + } + } else if (token == XContentParser.Token.START_ARRAY) { + if (KEY_MAPPINGS.equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + if (token == XContentParser.Token.VALUE_EMBEDDED_OBJECT) { + builder.putMapping(new MappingMetaData(new CompressedXContent(parser.binaryValue()))); + } else { + Map mapping = parser.mapOrdered(); + if (mapping.size() == 1) { + String mappingType = mapping.keySet().iterator().next(); + builder.putMapping(new MappingMetaData(mappingType, mapping)); + } + } + } + } else if (KEY_PRIMARY_TERMS.equals(currentFieldName)) { + LongArrayList list = new LongArrayList(); + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + if (token == XContentParser.Token.VALUE_NUMBER) { + list.add(parser.longValue()); + } else { + throw new IllegalStateException("found a non-numeric value under [" + KEY_PRIMARY_TERMS + "]"); + } + } + // private fiels + //builder.primaryTerms(list.toArray()); + } else if (KEY_ALIASES.equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + builder.putAlias(new AliasMetaData.Builder(parser.text()).build()); + } + } else { + throw new IllegalArgumentException("Unexpected field for an array " + currentFieldName); + } + } else if (token.isValue()) { + if (KEY_STATE.equals(currentFieldName)) { + builder.state(IndexMetaData.State.fromString(parser.text())); + } else if (KEY_VERSION.equals(currentFieldName)) { + builder.version(parser.longValue()); + } else if (KEY_ROUTING_NUM_SHARDS.equals(currentFieldName)) { + builder.setRoutingNumShards(parser.intValue()); + } else { + throw new IllegalArgumentException("Unexpected field [" + currentFieldName + "]"); + } + } else { + throw new IllegalArgumentException("Unexpected token " + token); + } + } + return builder.build(); } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/alias/HttpIndicesAliasesAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/alias/HttpIndicesAliasesAction.java new file mode 100644 index 0000000..c3ea236 --- /dev/null +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/alias/HttpIndicesAliasesAction.java @@ -0,0 +1,48 @@ +package org.xbib.elx.http.action.admin.indices.alias; + +import org.apache.logging.log4j.Level; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse; +import org.elasticsearch.common.CheckedFunction; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.xbib.elx.http.HttpAction; +import org.xbib.netty.http.client.RequestBuilder; + +import java.io.IOException; + +public class HttpIndicesAliasesAction extends HttpAction { + + @Override + public IndicesAliasesAction getActionInstance() { + return IndicesAliasesAction.INSTANCE; + } + + @Override + protected RequestBuilder createHttpRequest(String url, IndicesAliasesRequest request) { + try { + XContentBuilder builder = JsonXContent.contentBuilder(); + request.toXContent(builder, ToXContent.EMPTY_PARAMS); + String body = Strings.toString(builder); + logger.log(Level.DEBUG, "body = " + body); + return newPostRequest(url, "/_aliases", body); + } catch (IOException e) { + logger.error(e.getMessage(), e); + return null; + } + } + + @Override + protected CheckedFunction entityParser() { + return IndicesAliasesResponse::fromXContent; + } + + @Override + protected IndicesAliasesResponse emptyResponse() { + return new IndicesAliasesResponse(); + } +} diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/alias/get/HttpGetAliasAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/alias/get/HttpGetAliasAction.java new file mode 100644 index 0000000..2d03af1 --- /dev/null +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/alias/get/HttpGetAliasAction.java @@ -0,0 +1,87 @@ +package org.xbib.elx.http.action.admin.indices.alias.get; + +import org.elasticsearch.action.GenericAction; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.common.CheckedFunction; +import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.xcontent.XContentParser; +import org.xbib.elx.http.HttpAction; +import org.xbib.netty.http.client.RequestBuilder; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; + +public class HttpGetAliasAction extends HttpAction { + + @Override + protected RequestBuilder createHttpRequest(String url, GetAliasesRequest request) { + // beware of this inconsistency, request.indices() always return empty array + String index = request.indices() != null ? String.join(",", request.indices()) + "/" : ""; + String aliases = request.aliases() != null ? String.join(",", request.aliases()) + "/" : ""; + // do not add "/" in front of index + return newGetRequest(url, index + "_alias/" + aliases); + } + + @Override + public GenericAction getActionInstance() { + return GetAliasesAction.INSTANCE; + } + + @Override + protected CheckedFunction entityParser() { + return this::fromXContent; + } + + @Override + protected GetAliasesResponse emptyResponse() { + ImmutableOpenMap.Builder> aliasesBuilder = ImmutableOpenMap.builder(); + return new GetAliasesResponse(aliasesBuilder.build()); + } + + private GetAliasesResponse fromXContent(XContentParser parser) throws IOException { + if (parser.currentToken() == null) { + parser.nextToken(); + } + ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation); + ImmutableOpenMap.Builder> aliasesBuilder = ImmutableOpenMap.builder(); + while (parser.nextToken() != XContentParser.Token.END_OBJECT) { + if (parser.currentToken() == XContentParser.Token.FIELD_NAME) { + String indexName = parser.currentName(); + if (parser.nextToken() == XContentParser.Token.START_OBJECT) { + List parseInside = parseAliases(parser); + aliasesBuilder.put(indexName, parseInside); + } + } + } + return new GetAliasesResponse(aliasesBuilder.build()); + } + + private static List parseAliases(XContentParser parser) throws IOException { + List aliases = new ArrayList<>(); + XContentParser.Token token; + String currentFieldName = null; + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token == XContentParser.Token.START_OBJECT) { + if ("aliases".equals(currentFieldName)) { + while (parser.nextToken() != XContentParser.Token.END_OBJECT) { + AliasMetaData fromXContent = AliasMetaData.Builder.fromXContent(parser); + aliases.add(fromXContent); + } + } else { + parser.skipChildren(); + } + } else if (token == XContentParser.Token.START_ARRAY) { + parser.skipChildren(); + } + } + return aliases; + } +} \ No newline at end of file diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/create/HttpCreateIndexAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/create/HttpCreateIndexAction.java index 1b9410b..b135b92 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/create/HttpCreateIndexAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/create/HttpCreateIndexAction.java @@ -32,4 +32,9 @@ public class HttpCreateIndexAction extends HttpAction entityParser() { return CreateIndexResponse::fromXContent; } + + @Override + protected CreateIndexResponse emptyResponse() { + return new CreateIndexResponse(); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/delete/HttpDeleteIndexAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/delete/HttpDeleteIndexAction.java index c791444..3c0e328 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/delete/HttpDeleteIndexAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/delete/HttpDeleteIndexAction.java @@ -19,11 +19,16 @@ public class HttpDeleteIndexAction extends HttpAction entityParser() { return DeleteIndexResponse::fromXContent; } + + @Override + protected DeleteIndexResponse emptyResponse() { + return new DeleteIndexResponse(); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/exists/indices/HttpIndicesExistsAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/exists/indices/HttpIndicesExistsAction.java new file mode 100644 index 0000000..57e3127 --- /dev/null +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/exists/indices/HttpIndicesExistsAction.java @@ -0,0 +1,47 @@ +package org.xbib.elx.http.action.admin.indices.exists.indices; + +import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsAction; +import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest; +import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse; +import org.elasticsearch.common.CheckedFunction; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.rest.RestStatus; +import org.xbib.elx.http.HttpAction; +import org.xbib.elx.http.HttpActionContext; +import org.xbib.netty.http.client.RequestBuilder; + +import java.io.IOException; + +public class HttpIndicesExistsAction extends HttpAction { + + @Override + public IndicesExistsAction getActionInstance() { + return IndicesExistsAction.INSTANCE; + } + + @Override + protected RequestBuilder createHttpRequest(String url, IndicesExistsRequest request) { + String index = String.join(",", request.indices()); + return newHeadRequest(url, index); + } + + @Override + protected CheckedFunction entityParser() { + return this::fromXContent; + } + + @Override + protected IndicesExistsResponse emptyResponse() { + return new IndicesExistsResponse(false); // used for 404 Not found + } + + @Override + protected ElasticsearchStatusException parseToError(HttpActionContext httpActionContext) { + return new ElasticsearchStatusException("not found", RestStatus.NOT_FOUND); + } + + private IndicesExistsResponse fromXContent(XContentParser parser) throws IOException { + return new IndicesExistsResponse(true); // used for 200 OK + } +} \ No newline at end of file diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/refresh/HttpRefreshIndexAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/refresh/HttpRefreshIndexAction.java index a6e37c5..fc9819b 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/refresh/HttpRefreshIndexAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/refresh/HttpRefreshIndexAction.java @@ -19,12 +19,17 @@ public class HttpRefreshIndexAction extends HttpAction entityParser() { return RefreshResponse::fromXContent; } + + @Override + protected RefreshResponse emptyResponse() { + return new RefreshResponse(); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/settings/get/HttpGetSettingsAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/settings/get/HttpGetSettingsAction.java new file mode 100644 index 0000000..145a8d4 --- /dev/null +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/settings/get/HttpGetSettingsAction.java @@ -0,0 +1,91 @@ +package org.xbib.elx.http.action.admin.indices.settings.get; + +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsAction; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; +import org.elasticsearch.common.CheckedFunction; +import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParserUtils; +import org.xbib.elx.http.HttpAction; +import org.xbib.netty.http.client.RequestBuilder; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class HttpGetSettingsAction extends HttpAction { + + @Override + public GetSettingsAction getActionInstance() { + return GetSettingsAction.INSTANCE; + } + + @Override + protected RequestBuilder createHttpRequest(String url, GetSettingsRequest request) { + // beware, request.indices() is always an empty array + String index = request.indices() != null ? String.join(",", request.indices()) + "/" : ""; + return newGetRequest(url, index + "_settings"); + } + + @Override + protected CheckedFunction entityParser() { + return this::fromXContent; + } + + @Override + protected GetSettingsResponse emptyResponse() { + ImmutableOpenMap settingsMap = ImmutableOpenMap.builder().build(); + return new GetSettingsResponse(settingsMap); + } + + private GetSettingsResponse fromXContent(XContentParser parser) throws IOException { + Map indexToSettings = new HashMap<>(); + Map indexToDefaultSettings = new HashMap<>(); + if (parser.currentToken() == null) { + parser.nextToken(); + } + XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation); + parser.nextToken(); + while (!parser.isClosed()) { + if (parser.currentToken() == XContentParser.Token.START_OBJECT) { + parseIndexEntry(parser, indexToSettings, indexToDefaultSettings); + } else if (parser.currentToken() == XContentParser.Token.START_ARRAY) { + parser.skipChildren(); + } else { + parser.nextToken(); + } + } + ImmutableOpenMap settingsMap = ImmutableOpenMap.builder().putAll(indexToSettings).build(); + return new GetSettingsResponse(settingsMap); + } + + private static void parseIndexEntry(XContentParser parser, Map indexToSettings, + Map indexToDefaultSettings) throws IOException { + String indexName = parser.currentName(); + parser.nextToken(); + while (!parser.isClosed() && parser.currentToken() != XContentParser.Token.END_OBJECT) { + parseSettingsField(parser, indexName, indexToSettings, indexToDefaultSettings); + } + } + + private static void parseSettingsField(XContentParser parser, String currentIndexName, Map indexToSettings, + Map indexToDefaultSettings) throws IOException { + if (parser.currentToken() == XContentParser.Token.START_OBJECT) { + switch (parser.currentName()) { + case "settings": + indexToSettings.put(currentIndexName, Settings.fromXContent(parser)); + break; + case "defaults": + indexToDefaultSettings.put(currentIndexName, Settings.fromXContent(parser)); + break; + default: + parser.skipChildren(); + } + } else if (parser.currentToken() == XContentParser.Token.START_ARRAY) { + parser.skipChildren(); + } + parser.nextToken(); + } +} diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/settings/put/HttpUpdateSettingsAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/settings/put/HttpUpdateSettingsAction.java index f6dc7e8..b7818da 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/settings/put/HttpUpdateSettingsAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/admin/indices/settings/put/HttpUpdateSettingsAction.java @@ -15,7 +15,6 @@ import org.xbib.netty.http.client.RequestBuilder; import java.io.IOException; import java.io.UncheckedIOException; - public class HttpUpdateSettingsAction extends HttpAction { @Override @@ -30,8 +29,8 @@ public class HttpUpdateSettingsAction extends HttpAction entityParser() { return UpdateSettingsResponse::fromXContent; } + + @Override + protected UpdateSettingsResponse emptyResponse() { + return new UpdateSettingsResponse(); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/bulk/HttpBulkAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/bulk/HttpBulkAction.java index 6a07321..077dda5 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/bulk/HttpBulkAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/bulk/HttpBulkAction.java @@ -2,12 +2,16 @@ package org.xbib.elx.http.action.bulk; import org.elasticsearch.action.DocWriteRequest; import org.elasticsearch.action.bulk.BulkAction; +import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.common.CheckedFunction; +import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; import org.xbib.elx.http.HttpAction; import org.xbib.netty.http.client.RequestBuilder; @@ -21,12 +25,12 @@ public class HttpBulkAction extends HttpAction { } @Override - protected RequestBuilder createHttpRequest(String url, BulkRequest request) { + protected RequestBuilder createHttpRequest(String url, BulkRequest request) throws IOException { StringBuilder bulkContent = new StringBuilder(); for (DocWriteRequest actionRequest : request.requests()) { if (actionRequest instanceof IndexRequest) { IndexRequest indexRequest = (IndexRequest) actionRequest; - bulkContent.append("{\"").append(indexRequest.opType()).append("\":{"); + bulkContent.append("{\"").append(indexRequest.opType().getLowercase()).append("\":{"); bulkContent.append("\"_index\":\"").append(indexRequest.index()).append("\""); bulkContent.append(",\"_type\":\"").append(indexRequest.type()).append("\""); if (indexRequest.id() != null) { @@ -47,6 +51,31 @@ public class HttpBulkAction extends HttpAction { bulkContent.append("}}\n"); bulkContent.append(indexRequest.source().utf8ToString()); bulkContent.append("\n"); + } else if (actionRequest instanceof UpdateRequest) { + UpdateRequest updateRequest = (UpdateRequest) actionRequest; + bulkContent.append("{\"update\":{"); + bulkContent.append("\"_index\":\"").append(updateRequest.index()).append("\""); + bulkContent.append(",\"_type\":\"").append(updateRequest.type()).append("\""); + bulkContent.append(",\"_id\":\"").append(updateRequest.id()).append("\""); + if (updateRequest.routing() != null) { + bulkContent.append(",\"_routing\":\"").append(updateRequest.routing()).append("\""); + } + if (updateRequest.parent() != null) { + bulkContent.append(",\"_parent\":\"").append(updateRequest.parent()).append("\""); + } + if (updateRequest.version() > 0) { + bulkContent.append(",\"_version\":\"").append(updateRequest.version()).append("\""); + if (updateRequest.versionType() != null) { + bulkContent.append(",\"_version_type\":\"").append(updateRequest.versionType().name()).append("\""); + } + } + bulkContent.append("}}\n"); + // only 'doc' supported + if (updateRequest.doc() != null) { + bulkContent.append("{\"doc\":"); + bulkContent.append(XContentHelper.convertToJson(updateRequest.doc().source(), false, XContentType.JSON)); + bulkContent.append("}\n"); + } } else if (actionRequest instanceof DeleteRequest) { DeleteRequest deleteRequest = (DeleteRequest) actionRequest; bulkContent.append("{\"delete\":{"); @@ -66,4 +95,11 @@ public class HttpBulkAction extends HttpAction { protected CheckedFunction entityParser() { return BulkResponse::fromXContent; } + + @Override + protected BulkResponse emptyResponse() { + BulkItemResponse[] responses = null; + long took = 0L; + return new BulkResponse(responses, took); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/get/HttpExistsAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/get/HttpExistsAction.java index bb1d5df..d7c3969 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/get/HttpExistsAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/get/HttpExistsAction.java @@ -11,8 +11,6 @@ import org.xbib.netty.http.client.RequestBuilder; import java.io.IOException; -/** - */ public class HttpExistsAction extends HttpAction { @Override @@ -22,11 +20,16 @@ public class HttpExistsAction extends HttpAction { @Override protected RequestBuilder createHttpRequest(String url, GetRequest request) { - return newHeadRequest(url, request.index() + "/" + request.type() + "/" + request.id()); + return newHeadRequest(url, "/" + request.index() + "/" + request.type() + "/" + request.id()); } @Override protected CheckedFunction entityParser() { return GetResponse::fromXContent; } + + @Override + protected GetResponse emptyResponse() { + return new GetResponse(); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/get/HttpGetAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/get/HttpGetAction.java index b700961..419d0ba 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/get/HttpGetAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/get/HttpGetAction.java @@ -11,8 +11,6 @@ import org.xbib.netty.http.client.RequestBuilder; import java.io.IOException; -/** - */ public class HttpGetAction extends HttpAction { @Override @@ -22,11 +20,16 @@ public class HttpGetAction extends HttpAction { @Override protected RequestBuilder createHttpRequest(String url, GetRequest request) { - return newGetRequest(url, request.index() + "/" + request.type() + "/" + request.id()); + return newGetRequest(url, "/" + request.index() + "/" + request.type() + "/" + request.id()); } @Override protected CheckedFunction entityParser() { return GetResponse::fromXContent; } + + @Override + protected GetResponse emptyResponse() { + return new GetResponse(); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/index/HttpIndexAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/index/HttpIndexAction.java index be7aba2..93de3dd 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/index/HttpIndexAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/index/HttpIndexAction.java @@ -11,8 +11,6 @@ import org.xbib.netty.http.client.RequestBuilder; import java.io.IOException; -/** - */ public class HttpIndexAction extends HttpAction { @Override @@ -22,7 +20,7 @@ public class HttpIndexAction extends HttpAction { @Override protected RequestBuilder createHttpRequest(String url, IndexRequest request) { - return newPutRequest(url, request.index() + "/" + request.type() + "/" + request.id(), + return newPutRequest(url, "/" + request.index() + "/" + request.type() + "/" + request.id(), request.source()); } @@ -30,4 +28,9 @@ public class HttpIndexAction extends HttpAction { protected CheckedFunction entityParser() { return IndexResponse::fromXContent; } + + @Override + protected IndexResponse emptyResponse() { + return new IndexResponse(); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/main/HttpMainAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/main/HttpMainAction.java index 0ee995b..7b17831 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/main/HttpMainAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/main/HttpMainAction.java @@ -27,4 +27,9 @@ public class HttpMainAction extends HttpAction { protected CheckedFunction entityParser() { return MainResponse::fromXContent; } + + @Override + protected MainResponse emptyResponse() { + return new MainResponse(); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/search/HttpSearchAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/search/HttpSearchAction.java index 0cd6a15..8fe9523 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/search/HttpSearchAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/search/HttpSearchAction.java @@ -19,12 +19,18 @@ public class HttpSearchAction extends HttpAction @Override protected RequestBuilder createHttpRequest(String url, SearchRequest request) { - String index = request.indices() != null ? "/" + String.join(",", request.indices()) : ""; - return newPostRequest(url, index + "/_search", request.source().toString()); + // request.indices() always empty array + String index = request.indices() != null ? String.join(",", request.indices()) + "/" : ""; + return newPostRequest(url, index + "_search", request.source().toString()); } @Override protected CheckedFunction entityParser() { return SearchResponse::fromXContent; } + + @Override + protected SearchResponse emptyResponse() { + return new SearchResponse(); + } } diff --git a/elx-http/src/main/java/org/xbib/elx/http/action/update/HttpUpdateAction.java b/elx-http/src/main/java/org/xbib/elx/http/action/update/HttpUpdateAction.java index 134dbb8..8138bee 100644 --- a/elx-http/src/main/java/org/xbib/elx/http/action/update/HttpUpdateAction.java +++ b/elx-http/src/main/java/org/xbib/elx/http/action/update/HttpUpdateAction.java @@ -15,8 +15,6 @@ import org.xbib.netty.http.client.RequestBuilder; import java.io.IOException; -/** - */ public class HttpUpdateAction extends HttpAction { @Override @@ -49,7 +47,7 @@ public class HttpUpdateAction extends HttpAction } BytesReference source = XContentHelper.toXContent(updateRequest, xContentType, false); return newPostRequest(url, - updateRequest.index() + "/" + updateRequest.type() + "/" + updateRequest.id() + "/_update", + "/" + updateRequest.index() + "/" + updateRequest.type() + "/" + updateRequest.id() + "/_update", source); } catch (IOException e) { logger.error(e.getMessage(), e); @@ -61,4 +59,9 @@ public class HttpUpdateAction extends HttpAction protected CheckedFunction entityParser() { return UpdateResponse::fromXContent; } + + @Override + protected UpdateResponse emptyResponse() { + return new UpdateResponse(); + } } diff --git a/elx-http/src/main/resources/META-INF/services/org.xbib.elx.http.HttpAction b/elx-http/src/main/resources/META-INF/services/org.xbib.elx.http.HttpAction index 4d35ec6..eb3a014 100644 --- a/elx-http/src/main/resources/META-INF/services/org.xbib.elx.http.HttpAction +++ b/elx-http/src/main/resources/META-INF/services/org.xbib.elx.http.HttpAction @@ -1,8 +1,15 @@ +org.elasticsearch.action.admin.indices.mapping.get.HttpGetMappingsAction +org.xbib.elx.http.action.admin.cluster.health.HttpClusterHealthAction org.xbib.elx.http.action.admin.cluster.node.info.HttpNodesInfoAction org.xbib.elx.http.action.admin.cluster.settings.HttpClusterUpdateSettingsAction +org.xbib.elx.http.action.admin.cluster.state.HttpClusterStateAction +org.xbib.elx.http.action.admin.indices.alias.HttpIndicesAliasesAction +org.xbib.elx.http.action.admin.indices.alias.get.HttpGetAliasAction org.xbib.elx.http.action.admin.indices.create.HttpCreateIndexAction org.xbib.elx.http.action.admin.indices.delete.HttpDeleteIndexAction +org.xbib.elx.http.action.admin.indices.exists.indices.HttpIndicesExistsAction org.xbib.elx.http.action.admin.indices.refresh.HttpRefreshIndexAction +org.xbib.elx.http.action.admin.indices.settings.get.HttpGetSettingsAction org.xbib.elx.http.action.admin.indices.settings.put.HttpUpdateSettingsAction org.xbib.elx.http.action.bulk.HttpBulkAction org.xbib.elx.http.action.index.HttpIndexAction diff --git a/elx-http/src/test/java/org/xbib/elx/http/test/ClientTest.java b/elx-http/src/test/java/org/xbib/elx/http/test/ClientTest.java index b41c114..57a388b 100644 --- a/elx-http/src/test/java/org/xbib/elx/http/test/ClientTest.java +++ b/elx-http/src/test/java/org/xbib/elx/http/test/ClientTest.java @@ -14,7 +14,6 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.index.query.QueryBuilders; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.xbib.elx.common.ClientBuilder; @@ -31,7 +30,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -@Disabled @ExtendWith(TestExtension.class) class ClientTest { diff --git a/elx-http/src/test/java/org/xbib/elx/http/test/DuplicateIDTest.java b/elx-http/src/test/java/org/xbib/elx/http/test/DuplicateIDTest.java index c5aa731..5e966c0 100644 --- a/elx-http/src/test/java/org/xbib/elx/http/test/DuplicateIDTest.java +++ b/elx-http/src/test/java/org/xbib/elx/http/test/DuplicateIDTest.java @@ -5,7 +5,6 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.action.search.SearchAction; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.client.transport.NoNodeAvailableException; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.xbib.elx.common.ClientBuilder; @@ -20,15 +19,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -@Disabled @ExtendWith(TestExtension.class) class DuplicateIDTest { private static final Logger logger = LogManager.getLogger(DuplicateIDTest.class.getSimpleName()); - private static final Long MAX_ACTIONS_PER_REQUEST = 1000L; + private static final Long MAX_ACTIONS_PER_REQUEST = 10L; - private static final Long ACTIONS = 12345L; + private static final Long ACTIONS = 50L; private final TestExtension.Helper helper; diff --git a/elx-http/src/test/java/org/xbib/elx/http/test/IndexPruneTest.java b/elx-http/src/test/java/org/xbib/elx/http/test/IndexPruneTest.java index 8873235..54c3d6f 100644 --- a/elx-http/src/test/java/org/xbib/elx/http/test/IndexPruneTest.java +++ b/elx-http/src/test/java/org/xbib/elx/http/test/IndexPruneTest.java @@ -7,7 +7,6 @@ import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsReques import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse; import org.elasticsearch.client.transport.NoNodeAvailableException; import org.elasticsearch.common.settings.Settings; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.xbib.elx.api.IndexPruneResult; @@ -25,7 +24,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -@Disabled @ExtendWith(TestExtension.class) class IndexPruneTest { diff --git a/elx-http/src/test/java/org/xbib/elx/http/test/IndexShiftTest.java b/elx-http/src/test/java/org/xbib/elx/http/test/IndexShiftTest.java index ea0f8e9..234c0de 100644 --- a/elx-http/src/test/java/org/xbib/elx/http/test/IndexShiftTest.java +++ b/elx-http/src/test/java/org/xbib/elx/http/test/IndexShiftTest.java @@ -1,5 +1,6 @@ package org.xbib.elx.http.test; +import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; @@ -21,7 +22,6 @@ import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -@Disabled @ExtendWith(TestExtension.class) class IndexShiftTest { @@ -61,13 +61,16 @@ class IndexShiftTest { assertTrue(indexShiftResult.getMovedAliases().isEmpty()); Map aliases = client.getAliases("test1234"); + logger.log(Level.DEBUG, "aliases = " + aliases); assertTrue(aliases.containsKey("a")); assertTrue(aliases.containsKey("b")); assertTrue(aliases.containsKey("c")); assertTrue(aliases.containsKey("test")); String resolved = client.resolveAlias("test"); + logger.log(Level.DEBUG, "resolved = " + resolved); aliases = client.getAliases(resolved); + logger.log(Level.DEBUG, "aliases = " + aliases); assertTrue(aliases.containsKey("a")); assertTrue(aliases.containsKey("b")); assertTrue(aliases.containsKey("c")); diff --git a/elx-http/src/test/java/org/xbib/elx/http/test/SmokeTest.java b/elx-http/src/test/java/org/xbib/elx/http/test/SmokeTest.java index dfcaf50..bfc8021 100644 --- a/elx-http/src/test/java/org/xbib/elx/http/test/SmokeTest.java +++ b/elx-http/src/test/java/org/xbib/elx/http/test/SmokeTest.java @@ -4,7 +4,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.client.transport.NoNodeAvailableException; import org.elasticsearch.common.settings.Settings; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.xbib.elx.api.IndexDefinition; @@ -17,7 +16,6 @@ import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -@Disabled @ExtendWith(TestExtension.class) class SmokeTest { @@ -36,16 +34,19 @@ class SmokeTest { .put(helper.getHttpSettings()) .build(); try { + assertEquals(helper.getClusterName(), client.getClusterName()); client.newIndex("test"); client.index("test", "1", true, "{ \"name\" : \"Hello World\"}"); // single doc ingest client.flush(); client.waitForResponses(30, TimeUnit.SECONDS); - assertEquals(helper.getClusterName(), client.getClusterName()); client.checkMapping("test"); client.update("test", "1", "{ \"name\" : \"Another name\"}"); + client.delete("test", "1"); client.flush(); + client.waitForResponses(30, TimeUnit.SECONDS); client.waitForRecovery("test", 10L, TimeUnit.SECONDS); client.delete("test", "1"); + client.flush(); client.deleteIndex("test"); IndexDefinition indexDefinition = client.buildIndexDefinitionFromSettings("test", Settings.builder() .build()); @@ -58,7 +59,7 @@ class SmokeTest { assertEquals(2, replica); client.deleteIndex(indexDefinition); assertEquals(0, client.getBulkMetric().getFailed().getCount()); - assertEquals(4, client.getBulkMetric().getSucceeded().getCount()); + assertEquals(5, client.getBulkMetric().getSucceeded().getCount()); } catch (NoNodeAvailableException e) { logger.warn("skipping, no node available"); } finally { diff --git a/elx-http/src/test/resources/log4j2.xml b/elx-http/src/test/resources/log4j2.xml index 6c323f8..1258d7f 100644 --- a/elx-http/src/test/resources/log4j2.xml +++ b/elx-http/src/test/resources/log4j2.xml @@ -6,7 +6,7 @@ - + diff --git a/elx-node/src/test/java/org/xbib/elx/node/test/DuplicateIDTest.java b/elx-node/src/test/java/org/xbib/elx/node/test/DuplicateIDTest.java index 4fa3869..16b782f 100644 --- a/elx-node/src/test/java/org/xbib/elx/node/test/DuplicateIDTest.java +++ b/elx-node/src/test/java/org/xbib/elx/node/test/DuplicateIDTest.java @@ -27,7 +27,7 @@ class DuplicateIDTest { private static final Long MAX_ACTIONS_PER_REQUEST = 10L; - private static final Long ACTIONS = 5L; + private static final Long ACTIONS = 50L; private final TestExtension.Helper helper; diff --git a/elx-node/src/test/java/org/xbib/elx/node/test/SmokeTest.java b/elx-node/src/test/java/org/xbib/elx/node/test/SmokeTest.java index a4b4209..80767cb 100644 --- a/elx-node/src/test/java/org/xbib/elx/node/test/SmokeTest.java +++ b/elx-node/src/test/java/org/xbib/elx/node/test/SmokeTest.java @@ -40,6 +40,9 @@ class SmokeTest { client.delete("test", "1"); client.flush(); client.waitForResponses(30, TimeUnit.SECONDS); + client.waitForRecovery("test", 10L, TimeUnit.SECONDS); + client.delete("test", "1"); + client.flush(); client.checkMapping("test"); client.deleteIndex("test"); IndexDefinition indexDefinition = client.buildIndexDefinitionFromSettings("test", Settings.builder() @@ -55,7 +58,7 @@ class SmokeTest { assertEquals(2, replica); client.deleteIndex(indexDefinition); assertEquals(0, client.getBulkMetric().getFailed().getCount()); - assertEquals(4, client.getBulkMetric().getSucceeded().getCount()); + assertEquals(5, client.getBulkMetric().getSucceeded().getCount()); } catch (NoNodeAvailableException e) { logger.warn("skipping, no node available"); } finally { diff --git a/gradle.properties b/gradle.properties index 832cfd3..ec849f4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ group = org.xbib name = elx -version = 6.3.2.2 +version = 6.3.2.3 profile = default release = 0 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 838e6bc..aad3851 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Mon May 06 11:25:14 CEST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.3-all.zip