From 9d6eab2b5bc67db113dafac6ff3bab2d905ed0f7 Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Mon, 17 Feb 2020 09:03:51 +0100 Subject: [PATCH] Fix NPE in cluster state collector for monitoring. (#52371) Take into account a null license may be returned by the license service. Closes #52317 --- .../cluster/ClusterStatsCollector.java | 3 +- .../cluster/ClusterStatsCollectorTests.java | 60 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsCollector.java b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsCollector.java index ac699759482a8..704fbea489140 100644 --- a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsCollector.java +++ b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsCollector.java @@ -105,7 +105,8 @@ protected Collection doCollect(final MonitoringDoc.Node node, final List xpackUsage = collect(usageSupplier); final boolean apmIndicesExist = doAPMIndicesExist(clusterState); // if they have any other type of license, then they are either okay or already know - final boolean clusterNeedsTLSEnabled = license.operationMode() == License.OperationMode.TRIAL && + final boolean clusterNeedsTLSEnabled = license != null && + license.operationMode() == License.OperationMode.TRIAL && settings.hasValue(SECURITY_ENABLED.getKey()) && SECURITY_ENABLED.get(settings) && TRANSPORT_SSL_ENABLED.get(settings) == false; diff --git a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsCollectorTests.java b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsCollectorTests.java index b6f75d518ab86..cbaa7172be998 100644 --- a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsCollectorTests.java +++ b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsCollectorTests.java @@ -262,4 +262,64 @@ public void testDoCollect() throws Exception { verify(clusterAdminClient).prepareClusterStats(); verify(client).execute(same(XPackUsageAction.INSTANCE), any(XPackUsageRequest.class)); } + + public void testDoCollectNoLicense() throws Exception { + final TimeValue timeout; + { + final String clusterName = randomAlphaOfLength(10); + whenClusterStateWithName(clusterName); + final String clusterUUID = UUID.randomUUID().toString(); + whenClusterStateWithUUID(clusterUUID); + timeout = TimeValue.timeValueSeconds(randomIntBetween(1, 120)); + withCollectionTimeout(ClusterStatsCollector.CLUSTER_STATS_TIMEOUT, timeout); + } + final IndexNameExpressionResolver indexNameExpressionResolver; + { + indexNameExpressionResolver = mock(IndexNameExpressionResolver.class); + when(indexNameExpressionResolver.concreteIndices(clusterState, IndicesOptions.lenientExpandOpen(), "apm-*")) + .thenReturn(new Index[0]); + } + + final Client client = mock(Client.class); + { + final ClusterStatsResponse mockClusterStatsResponse = mock(ClusterStatsResponse.class); + final ClusterHealthStatus clusterStatus = randomFrom(ClusterHealthStatus.values()); + when(mockClusterStatsResponse.getStatus()).thenReturn(clusterStatus); + when(mockClusterStatsResponse.getNodesStats()).thenReturn(mock(ClusterStatsNodes.class)); + + final ClusterStatsIndices mockClusterStatsIndices = mock(ClusterStatsIndices.class); + + when(mockClusterStatsIndices.getIndexCount()).thenReturn(0); + when(mockClusterStatsResponse.getIndicesStats()).thenReturn(mockClusterStatsIndices); + + final ClusterStatsRequestBuilder clusterStatsRequestBuilder = mock(ClusterStatsRequestBuilder.class); + when(clusterStatsRequestBuilder.get(eq(timeout))).thenReturn(mockClusterStatsResponse); + + final ClusterAdminClient clusterAdminClient = mock(ClusterAdminClient.class); + when(clusterAdminClient.prepareClusterStats()).thenReturn(clusterStatsRequestBuilder); + + final AdminClient adminClient = mock(AdminClient.class); + when(adminClient.cluster()).thenReturn(clusterAdminClient); + when(client.admin()).thenReturn(adminClient); + + final XPackUsageResponse xPackUsageResponse = new XPackUsageResponse( + singletonList(new MonitoringFeatureSetUsage(true, true, false, null))); + @SuppressWarnings("unchecked") + final ActionFuture xPackUsageFuture = (ActionFuture) mock(ActionFuture.class); + when(client.execute(same(XPackUsageAction.INSTANCE), any(XPackUsageRequest.class))).thenReturn(xPackUsageFuture); + when(xPackUsageFuture.actionGet()).thenReturn(xPackUsageResponse); + } + + final long interval = randomNonNegativeLong(); + final Settings.Builder settings = Settings.builder(); + final MonitoringDoc.Node node = MonitoringTestUtils.randomMonitoringNode(random()); + + final ClusterStatsCollector collector = + new ClusterStatsCollector(settings.build(), clusterService, licenseState, + client, licenseService, indexNameExpressionResolver); + final Collection results = collector.doCollect(node, interval, clusterState); + assertEquals(1, results.size()); + final ClusterStatsMonitoringDoc doc = (ClusterStatsMonitoringDoc) results.iterator().next(); + assertThat(doc.getLicense(), nullValue()); + } }