PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/core/src/test/java/org/elasticsearch/cluster/ClusterInfoServiceIT.java

https://gitlab.com/0072016/0072016--
Java | 265 lines | 203 code | 29 blank | 33 comment | 10 complexity | 45dd827bcc587f085f4a95e3d9bb6586 MD5 | raw file
  1. /*
  2. * Licensed to Elasticsearch under one or more contributor
  3. * license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright
  5. * ownership. Elasticsearch licenses this file to you under
  6. * the Apache License, Version 2.0 (the "License"); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. package org.elasticsearch.cluster;
  20. import com.carrotsearch.hppc.cursors.ObjectCursor;
  21. import org.elasticsearch.ElasticsearchException;
  22. import org.elasticsearch.action.ActionListener;
  23. import org.elasticsearch.action.ActionModule;
  24. import org.elasticsearch.action.ActionRequest;
  25. import org.elasticsearch.action.ActionResponse;
  26. import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsAction;
  27. import org.elasticsearch.action.admin.indices.stats.IndicesStatsAction;
  28. import org.elasticsearch.action.support.ActionFilter;
  29. import org.elasticsearch.action.support.ActionFilters;
  30. import org.elasticsearch.cluster.metadata.IndexMetaData;
  31. import org.elasticsearch.cluster.node.DiscoveryNode;
  32. import org.elasticsearch.cluster.routing.RoutingNodes;
  33. import org.elasticsearch.cluster.routing.ShardRouting;
  34. import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
  35. import org.elasticsearch.cluster.service.ClusterService;
  36. import org.elasticsearch.common.Strings;
  37. import org.elasticsearch.common.collect.ImmutableOpenMap;
  38. import org.elasticsearch.common.inject.Inject;
  39. import org.elasticsearch.common.settings.Settings;
  40. import org.elasticsearch.common.unit.TimeValue;
  41. import org.elasticsearch.index.IndexService;
  42. import org.elasticsearch.index.shard.IndexShard;
  43. import org.elasticsearch.index.store.Store;
  44. import org.elasticsearch.indices.IndicesService;
  45. import org.elasticsearch.plugins.Plugin;
  46. import org.elasticsearch.test.ESIntegTestCase;
  47. import org.elasticsearch.test.InternalTestCluster;
  48. import org.elasticsearch.test.transport.MockTransportService;
  49. import org.elasticsearch.transport.TransportException;
  50. import org.elasticsearch.transport.TransportRequest;
  51. import org.elasticsearch.transport.TransportRequestOptions;
  52. import org.elasticsearch.transport.TransportService;
  53. import org.hamcrest.Matchers;
  54. import java.io.IOException;
  55. import java.util.Collection;
  56. import java.util.Set;
  57. import java.util.concurrent.ExecutionException;
  58. import java.util.concurrent.atomic.AtomicBoolean;
  59. import static java.util.Collections.emptySet;
  60. import static java.util.Collections.unmodifiableSet;
  61. import static org.elasticsearch.common.util.set.Sets.newHashSet;
  62. import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
  63. import static org.hamcrest.CoreMatchers.equalTo;
  64. import static org.hamcrest.Matchers.greaterThan;
  65. import static org.hamcrest.Matchers.greaterThanOrEqualTo;
  66. /**
  67. * Integration tests for the ClusterInfoService collecting information
  68. */
  69. @ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0)
  70. public class ClusterInfoServiceIT extends ESIntegTestCase {
  71. public static class TestPlugin extends Plugin {
  72. @Override
  73. public String name() {
  74. return "ClusterInfoServiceIT";
  75. }
  76. @Override
  77. public String description() {
  78. return "ClusterInfoServiceIT";
  79. }
  80. public void onModule(ActionModule module) {
  81. module.registerFilter(BlockingActionFilter.class);
  82. }
  83. }
  84. public static class BlockingActionFilter extends org.elasticsearch.action.support.ActionFilter.Simple {
  85. private Set<String> blockedActions = emptySet();
  86. @Inject
  87. public BlockingActionFilter(Settings settings) {
  88. super(settings);
  89. }
  90. @Override
  91. protected boolean apply(String action, ActionRequest<?> request, ActionListener<?> listener) {
  92. if (blockedActions.contains(action)) {
  93. throw new ElasticsearchException("force exception on [" + action + "]");
  94. }
  95. return true;
  96. }
  97. @Override
  98. protected boolean apply(String action, ActionResponse response, ActionListener<?> listener) {
  99. return true;
  100. }
  101. @Override
  102. public int order() {
  103. return 0;
  104. }
  105. public void blockActions(String... actions) {
  106. blockedActions = unmodifiableSet(newHashSet(actions));
  107. }
  108. }
  109. @Override
  110. protected Settings nodeSettings(int nodeOrdinal) {
  111. return Settings.builder()
  112. // manual collection or upon cluster forming.
  113. .put(InternalClusterInfoService.INTERNAL_CLUSTER_INFO_TIMEOUT_SETTING.getKey(), "1s")
  114. .build();
  115. }
  116. @Override
  117. protected Collection<Class<? extends Plugin>> nodePlugins() {
  118. return pluginList(TestPlugin.class,
  119. MockTransportService.TestPlugin.class);
  120. }
  121. public void testClusterInfoServiceCollectsInformation() throws Exception {
  122. internalCluster().startNodesAsync(2).get();
  123. assertAcked(prepareCreate("test").setSettings(Settings.builder()
  124. .put(Store.INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING.getKey(), 0)
  125. .put(EnableAllocationDecider.INDEX_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), EnableAllocationDecider.Rebalance.NONE).build()));
  126. ensureGreen("test");
  127. InternalTestCluster internalTestCluster = internalCluster();
  128. // Get the cluster info service on the master node
  129. final InternalClusterInfoService infoService = (InternalClusterInfoService) internalTestCluster.getInstance(ClusterInfoService.class, internalTestCluster.getMasterName());
  130. infoService.setUpdateFrequency(TimeValue.timeValueMillis(200));
  131. infoService.onMaster();
  132. ClusterInfo info = infoService.refresh();
  133. assertNotNull("info should not be null", info);
  134. ImmutableOpenMap<String, DiskUsage> leastUsages = info.getNodeLeastAvailableDiskUsages();
  135. ImmutableOpenMap<String, DiskUsage> mostUsages = info.getNodeMostAvailableDiskUsages();
  136. ImmutableOpenMap<String, Long> shardSizes = info.shardSizes;
  137. assertNotNull(leastUsages);
  138. assertNotNull(shardSizes);
  139. assertThat("some usages are populated", leastUsages.values().size(), Matchers.equalTo(2));
  140. assertThat("some shard sizes are populated", shardSizes.values().size(), greaterThan(0));
  141. for (ObjectCursor<DiskUsage> usage : leastUsages.values()) {
  142. logger.info("--> usage: {}", usage.value);
  143. assertThat("usage has be retrieved", usage.value.getFreeBytes(), greaterThan(0L));
  144. }
  145. for (ObjectCursor<DiskUsage> usage : mostUsages.values()) {
  146. logger.info("--> usage: {}", usage.value);
  147. assertThat("usage has be retrieved", usage.value.getFreeBytes(), greaterThan(0L));
  148. }
  149. for (ObjectCursor<Long> size : shardSizes.values()) {
  150. logger.info("--> shard size: {}", size.value);
  151. assertThat("shard size is greater than 0", size.value, greaterThanOrEqualTo(0L));
  152. }
  153. ClusterService clusterService = internalTestCluster.getInstance(ClusterService.class, internalTestCluster.getMasterName());
  154. ClusterState state = clusterService.state();
  155. RoutingNodes routingNodes = state.getRoutingNodes();
  156. for (ShardRouting shard : routingNodes.getRoutingTable().allShards()) {
  157. String dataPath = info.getDataPath(shard);
  158. assertNotNull(dataPath);
  159. String nodeId = shard.currentNodeId();
  160. DiscoveryNode discoveryNode = state.getNodes().get(nodeId);
  161. IndicesService indicesService = internalTestCluster.getInstance(IndicesService.class, discoveryNode.getName());
  162. IndexService indexService = indicesService.indexService(shard.index());
  163. IndexShard indexShard = indexService.getShardOrNull(shard.id());
  164. assertEquals(indexShard.shardPath().getRootDataPath().toString(), dataPath);
  165. }
  166. }
  167. public void testClusterInfoServiceInformationClearOnError() throws InterruptedException, ExecutionException {
  168. internalCluster().startNodesAsync(2,
  169. // manually control publishing
  170. Settings.builder().put(InternalClusterInfoService.INTERNAL_CLUSTER_INFO_UPDATE_INTERVAL_SETTING.getKey(), "60m").build())
  171. .get();
  172. prepareCreate("test").setSettings(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1).get();
  173. ensureGreen("test");
  174. InternalTestCluster internalTestCluster = internalCluster();
  175. InternalClusterInfoService infoService = (InternalClusterInfoService) internalTestCluster.getInstance(ClusterInfoService.class, internalTestCluster.getMasterName());
  176. // get one healthy sample
  177. ClusterInfo info = infoService.refresh();
  178. assertNotNull("failed to collect info", info);
  179. assertThat("some usages are populated", info.getNodeLeastAvailableDiskUsages().size(), Matchers.equalTo(2));
  180. assertThat("some shard sizes are populated", info.shardSizes.size(), greaterThan(0));
  181. MockTransportService mockTransportService = (MockTransportService) internalCluster().getInstance(TransportService.class, internalTestCluster.getMasterName());
  182. final AtomicBoolean timeout = new AtomicBoolean(false);
  183. final Set<String> blockedActions = newHashSet(NodesStatsAction.NAME, NodesStatsAction.NAME + "[n]", IndicesStatsAction.NAME, IndicesStatsAction.NAME + "[n]");
  184. // drop all outgoing stats requests to force a timeout.
  185. for (DiscoveryNode node : internalTestCluster.clusterService().state().getNodes()) {
  186. mockTransportService.addDelegate(internalTestCluster.getInstance(TransportService.class, node.getName()), new MockTransportService.DelegateTransport(mockTransportService.original()) {
  187. @Override
  188. public void sendRequest(DiscoveryNode node, long requestId, String action, TransportRequest request,
  189. TransportRequestOptions options) throws IOException, TransportException {
  190. if (blockedActions.contains(action)) {
  191. if (timeout.get()) {
  192. logger.info("dropping [{}] to [{}]", action, node);
  193. return;
  194. }
  195. }
  196. super.sendRequest(node, requestId, action, request, options);
  197. }
  198. });
  199. }
  200. // timeouts shouldn't clear the info
  201. timeout.set(true);
  202. info = infoService.refresh();
  203. assertNotNull("info should not be null", info);
  204. // node info will time out both on the request level on the count down latch. this means
  205. // it is likely to update the node disk usage based on the one response that came be from local
  206. // node.
  207. assertThat(info.getNodeLeastAvailableDiskUsages().size(), greaterThanOrEqualTo(1));
  208. assertThat(info.getNodeMostAvailableDiskUsages().size(), greaterThanOrEqualTo(1));
  209. // indices is guaranteed to time out on the latch, not updating anything.
  210. assertThat(info.shardSizes.size(), greaterThan(1));
  211. // now we cause an exception
  212. timeout.set(false);
  213. ActionFilters actionFilters = internalTestCluster.getInstance(ActionFilters.class, internalTestCluster.getMasterName());
  214. BlockingActionFilter blockingActionFilter = null;
  215. for (ActionFilter filter : actionFilters.filters()) {
  216. if (filter instanceof BlockingActionFilter) {
  217. blockingActionFilter = (BlockingActionFilter) filter;
  218. break;
  219. }
  220. }
  221. assertNotNull("failed to find BlockingActionFilter", blockingActionFilter);
  222. blockingActionFilter.blockActions(blockedActions.toArray(Strings.EMPTY_ARRAY));
  223. info = infoService.refresh();
  224. assertNotNull("info should not be null", info);
  225. assertThat(info.getNodeLeastAvailableDiskUsages().size(), equalTo(0));
  226. assertThat(info.getNodeMostAvailableDiskUsages().size(), equalTo(0));
  227. assertThat(info.shardSizes.size(), equalTo(0));
  228. // check we recover
  229. blockingActionFilter.blockActions();
  230. info = infoService.refresh();
  231. assertNotNull("info should not be null", info);
  232. assertThat(info.getNodeLeastAvailableDiskUsages().size(), equalTo(2));
  233. assertThat(info.getNodeMostAvailableDiskUsages().size(), equalTo(2));
  234. assertThat(info.shardSizes.size(), greaterThan(0));
  235. }
  236. }