You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by gi...@apache.org on 2019/07/21 02:09:13 UTC
[incubator-druid] branch master updated: fix npe with sql metadata
manager polling and empty database (#8106)
This is an automated email from the ASF dual-hosted git repository.
gian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-druid.git
The following commit(s) were added to refs/heads/master by this push:
new f24e2f1 fix npe with sql metadata manager polling and empty database (#8106)
f24e2f1 is described below
commit f24e2f16af38352056e713347de4e63d38c785ad
Author: Clint Wylie <cw...@apache.org>
AuthorDate: Sat Jul 20 19:09:02 2019 -0700
fix npe with sql metadata manager polling and empty database (#8106)
* fix npe with sql metadata manager polling and empty database
* treat null segments separately
* use preconditions check
* add test
---
.../druid/metadata/SQLMetadataSegmentManager.java | 19 ++--
.../SQLMetadataSegmentManagerEmptyTest.java | 113 +++++++++++++++++++++
2 files changed, 124 insertions(+), 8 deletions(-)
diff --git a/server/src/main/java/org/apache/druid/metadata/SQLMetadataSegmentManager.java b/server/src/main/java/org/apache/druid/metadata/SQLMetadataSegmentManager.java
index db1d19e..2f37fd6 100644
--- a/server/src/main/java/org/apache/druid/metadata/SQLMetadataSegmentManager.java
+++ b/server/src/main/java/org/apache/druid/metadata/SQLMetadataSegmentManager.java
@@ -950,14 +950,10 @@ public class SQLMetadataSegmentManager implements MetadataSegmentManager
}
);
- if (segments == null || segments.isEmpty()) {
- log.info("No segments found in the database!");
- return;
- }
-
- log.info("Polled and found %,d segments in the database", segments.size());
-
- ImmutableMap<String, String> dataSourceProperties = createDefaultDataSourceProperties();
+ Preconditions.checkNotNull(
+ segments,
+ "Unexpected 'null' when polling segments from the db, aborting snapshot update."
+ );
// dataSourcesSnapshot is updated only here and the DataSourcesSnapshot object is immutable. If data sources or
// segments are marked as used or unused directly (via markAs...() methods in MetadataSegmentManager), the
@@ -967,6 +963,13 @@ public class SQLMetadataSegmentManager implements MetadataSegmentManager
// segment mark calls in rapid succession. So the snapshot update is not done outside of database poll at this time.
// Updates outside of database polls were primarily for the user experience, so users would immediately see the
// effect of a segment mark call reflected in MetadataResource API calls.
+
+ ImmutableMap<String, String> dataSourceProperties = createDefaultDataSourceProperties();
+ if (segments.isEmpty()) {
+ log.info("No segments found in the database!");
+ } else {
+ log.info("Polled and found %,d segments in the database", segments.size());
+ }
dataSourcesSnapshot = DataSourcesSnapshot.fromUsedSegments(
Iterables.filter(segments, Objects::nonNull), // Filter corrupted entries (see above in this method).
dataSourceProperties
diff --git a/server/src/test/java/org/apache/druid/metadata/SQLMetadataSegmentManagerEmptyTest.java b/server/src/test/java/org/apache/druid/metadata/SQLMetadataSegmentManagerEmptyTest.java
new file mode 100644
index 0000000..1e3f5d8
--- /dev/null
+++ b/server/src/test/java/org/apache/druid/metadata/SQLMetadataSegmentManagerEmptyTest.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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.apache.druid.metadata;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.apache.druid.client.ImmutableDruidDataSource;
+import org.apache.druid.segment.TestHelper;
+import org.joda.time.Period;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.stream.Collectors;
+
+
+/**
+ * Like {@link SQLMetadataRuleManagerTest} except with no segments to make sure it behaves when it's empty
+ */
+public class SQLMetadataSegmentManagerEmptyTest
+{
+
+ @Rule
+ public final TestDerbyConnector.DerbyConnectorRule derbyConnectorRule = new TestDerbyConnector.DerbyConnectorRule();
+
+ private SQLMetadataSegmentManager sqlSegmentsMetadata;
+ private final ObjectMapper jsonMapper = TestHelper.makeJsonMapper();
+
+ @Before
+ public void setUp() throws Exception
+ {
+ TestDerbyConnector connector = derbyConnectorRule.getConnector();
+ MetadataSegmentManagerConfig config = new MetadataSegmentManagerConfig();
+ config.setPollDuration(Period.seconds(1));
+ sqlSegmentsMetadata = new SQLMetadataSegmentManager(
+ jsonMapper,
+ Suppliers.ofInstance(config),
+ derbyConnectorRule.metadataTablesConfigSupplier(),
+ connector
+ );
+ sqlSegmentsMetadata.start();
+
+ connector.createSegmentTable();
+ }
+
+ @After
+ public void teardown()
+ {
+ if (sqlSegmentsMetadata.isPollingDatabasePeriodically()) {
+ sqlSegmentsMetadata.stopPollingDatabasePeriodically();
+ }
+ sqlSegmentsMetadata.stop();
+ }
+
+ @Test
+ public void testPollEmpty()
+ {
+ sqlSegmentsMetadata.startPollingDatabasePeriodically();
+ sqlSegmentsMetadata.poll();
+ Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically());
+ Assert.assertEquals(
+ ImmutableList.of(),
+ sqlSegmentsMetadata.retrieveAllDataSourceNames()
+ );
+ Assert.assertEquals(
+ ImmutableList.of(),
+ sqlSegmentsMetadata
+ .getImmutableDataSourcesWithAllUsedSegments()
+ .stream()
+ .map(ImmutableDruidDataSource::getName)
+ .collect(Collectors.toList())
+ );
+ Assert.assertEquals(
+ null,
+ sqlSegmentsMetadata.getImmutableDataSourceWithUsedSegments("wikipedia")
+ );
+ Assert.assertEquals(
+ ImmutableSet.of(),
+ ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments())
+ );
+ }
+
+ @Test
+ public void testStopAndStart()
+ {
+ // Simulate successive losing and getting the coordinator leadership
+ sqlSegmentsMetadata.startPollingDatabasePeriodically();
+ sqlSegmentsMetadata.stopPollingDatabasePeriodically();
+ sqlSegmentsMetadata.startPollingDatabasePeriodically();
+ sqlSegmentsMetadata.stopPollingDatabasePeriodically();
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org