Skip to content

Commit

Permalink
[CCR] Add get auto follow pattern api (#33849)
Browse files Browse the repository at this point in the history
Relates to #33007
  • Loading branch information
martijnvg authored Sep 24, 2018
1 parent 1c57964 commit 2795ef5
Show file tree
Hide file tree
Showing 12 changed files with 451 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,26 @@
leader_cluster_alias: _local_
body:
leader_index_patterns: ['logs-*']
max_concurrent_read_batches: 2
- is_true: acknowledged

- do:
ccr.get_auto_follow_pattern:
leader_cluster_alias: _local_
- match: { _local_.leader_index_patterns: ['logs-*'] }
- match: { _local_.max_concurrent_read_batches: 2 }

- do:
ccr.get_auto_follow_pattern: {}
- match: { _local_.leader_index_patterns: ['logs-*'] }
- match: { _local_.max_concurrent_read_batches: 2 }

- do:
ccr.delete_auto_follow_pattern:
leader_cluster_alias: _local_
- is_true: acknowledged

- do:
catch: missing
ccr.get_auto_follow_pattern:
leader_cluster_alias: _local_
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.watcher.ResourceWatcherService;
import org.elasticsearch.xpack.ccr.action.AutoFollowCoordinator;
import org.elasticsearch.xpack.ccr.action.TransportGetAutoFollowPatternAction;
import org.elasticsearch.xpack.ccr.rest.RestGetAutoFollowPatternAction;
import org.elasticsearch.xpack.ccr.action.TransportAutoFollowStatsAction;
import org.elasticsearch.xpack.ccr.rest.RestAutoFollowStatsAction;
import org.elasticsearch.xpack.core.ccr.action.AutoFollowStatsAction;
import org.elasticsearch.xpack.core.ccr.action.DeleteAutoFollowPatternAction;
import org.elasticsearch.xpack.core.ccr.action.GetAutoFollowPatternAction;
import org.elasticsearch.xpack.core.ccr.action.PutAutoFollowPatternAction;
import org.elasticsearch.xpack.ccr.action.ShardChangesAction;
import org.elasticsearch.xpack.ccr.action.ShardFollowTask;
Expand Down Expand Up @@ -163,7 +166,8 @@ public List<PersistentTasksExecutor<?>> getPersistentTasksExecutor(ClusterServic
new ActionHandler<>(UnfollowIndexAction.INSTANCE, TransportUnfollowIndexAction.class),
// auto-follow actions
new ActionHandler<>(DeleteAutoFollowPatternAction.INSTANCE, TransportDeleteAutoFollowPatternAction.class),
new ActionHandler<>(PutAutoFollowPatternAction.INSTANCE, TransportPutAutoFollowPatternAction.class));
new ActionHandler<>(PutAutoFollowPatternAction.INSTANCE, TransportPutAutoFollowPatternAction.class),
new ActionHandler<>(GetAutoFollowPatternAction.INSTANCE, TransportGetAutoFollowPatternAction.class));
}

public List<RestHandler> getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings,
Expand All @@ -184,7 +188,8 @@ public List<RestHandler> getRestHandlers(Settings settings, RestController restC
new RestUnfollowIndexAction(settings, restController),
// auto-follow APIs
new RestDeleteAutoFollowPatternAction(settings, restController),
new RestPutAutoFollowPatternAction(settings, restController));
new RestPutAutoFollowPatternAction(settings, restController),
new RestGetAutoFollowPatternAction(settings, restController));
}

public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

package org.elasticsearch.xpack.ccr.action;

import org.elasticsearch.ResourceNotFoundException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.master.TransportMasterNodeReadAction;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xpack.core.ccr.AutoFollowMetadata;
import org.elasticsearch.xpack.core.ccr.AutoFollowMetadata.AutoFollowPattern;
import org.elasticsearch.xpack.core.ccr.action.GetAutoFollowPatternAction;

import java.util.Collections;
import java.util.Map;

public class TransportGetAutoFollowPatternAction
extends TransportMasterNodeReadAction<GetAutoFollowPatternAction.Request, GetAutoFollowPatternAction.Response> {

@Inject
public TransportGetAutoFollowPatternAction(Settings settings,
TransportService transportService,
ClusterService clusterService,
ThreadPool threadPool,
ActionFilters actionFilters,
IndexNameExpressionResolver indexNameExpressionResolver) {
super(settings, GetAutoFollowPatternAction.NAME, transportService, clusterService, threadPool, actionFilters,
GetAutoFollowPatternAction.Request::new, indexNameExpressionResolver);
}

@Override
protected String executor() {
return ThreadPool.Names.SAME;
}

@Override
protected GetAutoFollowPatternAction.Response newResponse() {
return new GetAutoFollowPatternAction.Response();
}

@Override
protected void masterOperation(GetAutoFollowPatternAction.Request request,
ClusterState state,
ActionListener<GetAutoFollowPatternAction.Response> listener) throws Exception {
Map<String, AutoFollowPattern> autoFollowPatterns = getAutoFollowPattern(state.metaData(), request.getLeaderClusterAlias());
listener.onResponse(new GetAutoFollowPatternAction.Response(autoFollowPatterns));
}

@Override
protected ClusterBlockException checkBlock(GetAutoFollowPatternAction.Request request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
}

static Map<String, AutoFollowPattern> getAutoFollowPattern(MetaData metaData, String leaderClusterAlias) {
AutoFollowMetadata autoFollowMetadata = metaData.custom(AutoFollowMetadata.TYPE);
if (autoFollowMetadata == null) {
throw new ResourceNotFoundException("no auto-follow patterns for cluster alias [{}] found", leaderClusterAlias);
}

if (leaderClusterAlias == null) {
return autoFollowMetadata.getPatterns();
}

AutoFollowPattern autoFollowPattern = autoFollowMetadata.getPatterns().get(leaderClusterAlias);
if (autoFollowPattern == null) {
throw new ResourceNotFoundException("no auto-follow patterns for cluster alias [{}] found", leaderClusterAlias);
}
return Collections.singletonMap(leaderClusterAlias, autoFollowPattern);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.ccr.rest;

import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.RestToXContentListener;
import org.elasticsearch.xpack.core.ccr.action.GetAutoFollowPatternAction.Request;

import java.io.IOException;

import static org.elasticsearch.xpack.core.ccr.action.GetAutoFollowPatternAction.INSTANCE;

public class RestGetAutoFollowPatternAction extends BaseRestHandler {

public RestGetAutoFollowPatternAction(Settings settings, RestController controller) {
super(settings);
controller.registerHandler(RestRequest.Method.GET, "/_ccr/auto_follow/{leader_cluster_alias}", this);
controller.registerHandler(RestRequest.Method.GET, "/_ccr/auto_follow", this);
}

@Override
public String getName() {
return "ccr_get_auto_follow_pattern_action";
}

@Override
protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException {
Request request = new Request();
request.setLeaderClusterAlias(restRequest.param("leader_cluster_alias"));
return channel -> client.execute(INSTANCE, request, new RestToXContentListener<>(channel));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.ccr.action;

import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.test.AbstractWireSerializingTestCase;
import org.elasticsearch.xpack.core.ccr.action.GetAutoFollowPatternAction;

public class GetAutoFollowPatternRequestTests extends AbstractWireSerializingTestCase<GetAutoFollowPatternAction.Request> {

@Override
protected Writeable.Reader<GetAutoFollowPatternAction.Request> instanceReader() {
return GetAutoFollowPatternAction.Request::new;
}

@Override
protected GetAutoFollowPatternAction.Request createTestInstance() {
GetAutoFollowPatternAction.Request request = new GetAutoFollowPatternAction.Request();
if (randomBoolean()) {
request.setLeaderClusterAlias(randomAlphaOfLength(4));
}
return request;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.ccr.action;

import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.test.AbstractStreamableTestCase;
import org.elasticsearch.xpack.core.ccr.AutoFollowMetadata.AutoFollowPattern;
import org.elasticsearch.xpack.core.ccr.action.GetAutoFollowPatternAction;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class GetAutoFollowPatternResponseTests extends AbstractStreamableTestCase<GetAutoFollowPatternAction.Response> {

@Override
protected GetAutoFollowPatternAction.Response createBlankInstance() {
return new GetAutoFollowPatternAction.Response();
}

@Override
protected GetAutoFollowPatternAction.Response createTestInstance() {
int numPatterns = randomIntBetween(1, 8);
Map<String, AutoFollowPattern> patterns = new HashMap<>(numPatterns);
for (int i = 0; i < numPatterns; i++) {
AutoFollowPattern autoFollowPattern = new AutoFollowPattern(
Collections.singletonList(randomAlphaOfLength(4)),
randomAlphaOfLength(4),
randomIntBetween(0, Integer.MAX_VALUE),
randomIntBetween(0, Integer.MAX_VALUE),
randomNonNegativeLong(),
randomIntBetween(0, Integer.MAX_VALUE),
randomIntBetween(0, Integer.MAX_VALUE),
TimeValue.timeValueMillis(500),
TimeValue.timeValueMillis(500));
patterns.put(randomAlphaOfLength(4), autoFollowPattern);
}
return new GetAutoFollowPatternAction.Response(patterns);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

package org.elasticsearch.xpack.ccr.action;

import org.elasticsearch.ResourceNotFoundException;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.ccr.AutoFollowMetadata;
import org.elasticsearch.xpack.core.ccr.AutoFollowMetadata.AutoFollowPattern;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.collection.IsMapContaining.hasEntry;

public class TransportGetAutoFollowPatternActionTests extends ESTestCase {

public void testGetAutoFollowPattern() {
Map<String, AutoFollowPattern> patterns = new HashMap<>();
patterns.put("test_alias1",
new AutoFollowPattern(Collections.singletonList("index-*"), null, null, null, null, null, null, null, null));
patterns.put("test_alias2",
new AutoFollowPattern(Collections.singletonList("index-*"), null, null, null, null, null, null, null, null));
MetaData metaData = MetaData.builder()
.putCustom(AutoFollowMetadata.TYPE, new AutoFollowMetadata(patterns, Collections.emptyMap(), Collections.emptyMap()))
.build();

Map<String, AutoFollowPattern> result = TransportGetAutoFollowPatternAction.getAutoFollowPattern(metaData, "test_alias1");
assertThat(result.size(), equalTo(1));
assertThat(result, hasEntry("test_alias1", patterns.get("test_alias1")));

result = TransportGetAutoFollowPatternAction.getAutoFollowPattern(metaData, null);
assertThat(result.size(), equalTo(2));
assertThat(result, hasEntry("test_alias1", patterns.get("test_alias1")));
assertThat(result, hasEntry("test_alias2", patterns.get("test_alias2")));

expectThrows(ResourceNotFoundException.class,
() -> TransportGetAutoFollowPatternAction.getAutoFollowPattern(metaData, "another_alias"));
}

public void testGetAutoFollowPatternNoAutoFollowPatterns() {
AutoFollowMetadata autoFollowMetadata =
new AutoFollowMetadata(Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap());
MetaData metaData = MetaData.builder()
.putCustom(AutoFollowMetadata.TYPE, autoFollowMetadata)
.build();
expectThrows(ResourceNotFoundException.class,
() -> TransportGetAutoFollowPatternAction.getAutoFollowPattern(metaData, "test_alias"));
}

public void testGetAutoFollowPatternNoAutoFollowMetadata() {
MetaData metaData = MetaData.builder().build();
expectThrows(ResourceNotFoundException.class,
() -> TransportGetAutoFollowPatternAction.getAutoFollowPattern(metaData, "test_alias"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ public int hashCode() {

public static class AutoFollowPattern implements Writeable, ToXContentObject {

private static final ParseField LEADER_PATTERNS_FIELD = new ParseField("leader_patterns");
private static final ParseField FOLLOW_PATTERN_FIELD = new ParseField("follow_pattern");
public static final ParseField LEADER_PATTERNS_FIELD = new ParseField("leader_index_patterns");
public static final ParseField FOLLOW_PATTERN_FIELD = new ParseField("follow_index_pattern");
public static final ParseField MAX_BATCH_OPERATION_COUNT = new ParseField("max_batch_operation_count");
public static final ParseField MAX_CONCURRENT_READ_BATCHES = new ParseField("max_concurrent_read_batches");
public static final ParseField MAX_BATCH_SIZE_IN_BYTES = new ParseField("max_batch_size_in_bytes");
Expand Down
Loading

0 comments on commit 2795ef5

Please sign in to comment.