Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import org.elasticsearch.action.admin.cluster.settings.ClusterGetSettingsResponse;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsResponse;
import org.elasticsearch.client.cluster.RemoteInfoRequest;
import org.elasticsearch.client.cluster.RemoteInfoResponse;
import org.elasticsearch.rest.RestStatus;

import java.io.IOException;
Expand Down Expand Up @@ -138,4 +140,33 @@ public Cancellable healthAsync(ClusterHealthRequest healthRequest, RequestOption
return restHighLevelClient.performRequestAsyncAndParseEntity(healthRequest, ClusterRequestConverters::clusterHealth, options,
ClusterHealthResponse::fromXContent, listener, singleton(RestStatus.REQUEST_TIMEOUT.getStatus()));
}

/**
* Get the remote cluster information using the Remote cluster info API.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-remote-info.html"> Remote cluster info
* API on elastic.co</a>
* @param request the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return the response
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public RemoteInfoResponse remoteInfo(RemoteInfoRequest request, RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request, ClusterRequestConverters::remoteInfo, options,
RemoteInfoResponse::fromXContent, singleton(RestStatus.REQUEST_TIMEOUT.getStatus()));
}

/**
* Asynchronously get remote cluster information using the Remote cluster info API.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-remote-info.html"> Remote cluster info
* API on elastic.co</a>
* @param request the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @param listener the listener to be notified upon request completion
* @return cancellable that may be used to cancel the request
*/
public Cancellable remoteInfoAsync(RemoteInfoRequest request, RequestOptions options,
ActionListener<RemoteInfoResponse> listener) {
return restHighLevelClient.performRequestAsyncAndParseEntity(request, ClusterRequestConverters::remoteInfo, options,
RemoteInfoResponse::fromXContent, listener, singleton(RestStatus.REQUEST_TIMEOUT.getStatus()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.elasticsearch.action.admin.cluster.settings.ClusterGetSettingsRequest;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.client.cluster.RemoteInfoRequest;
import org.elasticsearch.common.Strings;

import java.io.IOException;
Expand Down Expand Up @@ -76,4 +77,8 @@ static Request clusterHealth(ClusterHealthRequest healthRequest) {
request.addParameters(params.asMap());
return request;
}

static Request remoteInfo(RemoteInfoRequest remoteInfoRequest) {
return new Request(HttpGet.METHOD_NAME, "/_remote/info");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.elasticsearch.client.cluster;

import java.util.Objects;

public class ProxyModeInfo implements RemoteConnectionInfo.ModeInfo {
static final String NAME = "proxy";
static final String ADDRESS = "address";
static final String NUM_SOCKETS_CONNECTED = "num_sockets_connected";
static final String MAX_SOCKET_CONNECTIONS = "max_socket_connections";
private final String address;
private final int maxSocketConnections;
private final int numSocketsConnected;

ProxyModeInfo(String address, int maxSocketConnections, int numSocketsConnected) {
this.address = address;
this.maxSocketConnections = maxSocketConnections;
this.numSocketsConnected = numSocketsConnected;
}

@Override
public boolean isConnected() {
return numSocketsConnected > 0;
}

@Override
public String modeName() {
return NAME;
}

public String getAddress() {
return address;
}

public int getMaxSocketConnections() {
return maxSocketConnections;
}

public int getNumSocketsConnected() {
return numSocketsConnected;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ProxyModeInfo otherProxy = (ProxyModeInfo) o;
return maxSocketConnections == otherProxy.maxSocketConnections &&
numSocketsConnected == otherProxy.numSocketsConnected &&
Objects.equals(address, otherProxy.address);
}

@Override
public int hashCode() {
return Objects.hash(address, maxSocketConnections, numSocketsConnected);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.elasticsearch.client.cluster;

import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.XContentParser;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;

/**
* This class encapsulates all remote cluster information to be rendered on
* {@code _remote/info} requests.
*/
public final class RemoteConnectionInfo {
private static final String CONNECTED = "connected";
private static final String MODE = "mode";
private static final String INITIAL_CONNECT_TIMEOUT = "initial_connect_timeout";
private static final String SKIP_UNAVAILABLE = "skip_unavailable";

@SuppressWarnings("unchecked")
private static final ConstructingObjectParser<RemoteConnectionInfo, String> PARSER = new ConstructingObjectParser<>(
"RemoteConnectionInfoObjectParser",
false,
(args, clusterAlias) -> {
String mode = (String) args[1];
ModeInfo modeInfo;
if (mode.equals(ProxyModeInfo.NAME)) {
modeInfo = new ProxyModeInfo((String) args[4], (int) args[5], (int) args[6]);
} else if (mode.equals(SniffModeInfo.NAME)) {
modeInfo = new SniffModeInfo((List<String>) args[7], (int) args[8], (int) args[9]);
} else {
throw new IllegalArgumentException("mode cannot be " + mode);
}
return new RemoteConnectionInfo(clusterAlias,
modeInfo,
TimeValue.parseTimeValue((String) args[2], INITIAL_CONNECT_TIMEOUT),
(boolean) args[3]);
});

static {
PARSER.declareBoolean(constructorArg(), new ParseField(CONNECTED));
PARSER.declareString(constructorArg(), new ParseField(MODE));
PARSER.declareString(constructorArg(), new ParseField(INITIAL_CONNECT_TIMEOUT));
PARSER.declareBoolean(constructorArg(), new ParseField(SKIP_UNAVAILABLE));

PARSER.declareString(optionalConstructorArg(), new ParseField(ProxyModeInfo.ADDRESS));
PARSER.declareInt(optionalConstructorArg(), new ParseField(ProxyModeInfo.MAX_SOCKET_CONNECTIONS));
PARSER.declareInt(optionalConstructorArg(), new ParseField(ProxyModeInfo.NUM_SOCKETS_CONNECTED));

PARSER.declareStringArray(optionalConstructorArg(), new ParseField(SniffModeInfo.SEEDS));
PARSER.declareInt(optionalConstructorArg(), new ParseField(SniffModeInfo.MAX_CONNECTIONS_PER_CLUSTER));
PARSER.declareInt(optionalConstructorArg(), new ParseField(SniffModeInfo.NUM_NODES_CONNECTED));
}

final ModeInfo modeInfo;
final TimeValue initialConnectionTimeout;
final String clusterAlias;
final boolean skipUnavailable;

RemoteConnectionInfo(String clusterAlias, ModeInfo modeInfo, TimeValue initialConnectionTimeout, boolean skipUnavailable) {
this.clusterAlias = clusterAlias;
this.modeInfo = modeInfo;
this.initialConnectionTimeout = initialConnectionTimeout;
this.skipUnavailable = skipUnavailable;
}

public boolean isConnected() {
return modeInfo.isConnected();
}

public String getClusterAlias() {
return clusterAlias;
}

public ModeInfo getModeInfo() {
return modeInfo;
}

public TimeValue getInitialConnectionTimeout() {
return initialConnectionTimeout;
}

public boolean isSkipUnavailable() {
return skipUnavailable;
}

public static RemoteConnectionInfo fromXContent(XContentParser parser, String clusterAlias) throws IOException {
return PARSER.parse(parser, clusterAlias);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RemoteConnectionInfo that = (RemoteConnectionInfo) o;
return skipUnavailable == that.skipUnavailable &&
Objects.equals(modeInfo, that.modeInfo) &&
Objects.equals(initialConnectionTimeout, that.initialConnectionTimeout) &&
Objects.equals(clusterAlias, that.clusterAlias);
}

@Override
public int hashCode() {
return Objects.hash(modeInfo, initialConnectionTimeout, clusterAlias, skipUnavailable);
}

public interface ModeInfo {

boolean isConnected();

String modeName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.client.cluster;

import org.elasticsearch.client.Validatable;

/**
* The request object used by the Remote cluster info API.
*/
public final class RemoteInfoRequest implements Validatable {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.client.cluster;

import org.elasticsearch.common.xcontent.XContentParser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;

/**
* A response to _remote/info API request.
*/
public final class RemoteInfoResponse {

private List<RemoteConnectionInfo> infos;

RemoteInfoResponse(Collection<RemoteConnectionInfo> infos) {
this.infos = List.copyOf(infos);
}

public List<RemoteConnectionInfo> getInfos() {
return infos;
}

public static RemoteInfoResponse fromXContent(XContentParser parser) throws IOException {
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);

List<RemoteConnectionInfo> infos = new ArrayList<>();

XContentParser.Token token;
while ((token = parser.nextToken()) == XContentParser.Token.FIELD_NAME) {
String clusterAlias = parser.currentName();
RemoteConnectionInfo info = RemoteConnectionInfo.fromXContent(parser, clusterAlias);
infos.add(info);
}
ensureExpectedToken(XContentParser.Token.END_OBJECT, token, parser::getTokenLocation);
return new RemoteInfoResponse(infos);
}
}
Loading