From 9a066558a447bf18f9b10699984fd1621f0ef26e Mon Sep 17 00:00:00 2001 From: Jihoon Son Date: Mon, 25 Feb 2019 11:10:35 -0800 Subject: [PATCH] Fix exception when the scheme is missing in endpointUrl for S3 (#7129) * Fix exception when the scheme is missing in endpointUrl for S3 * add null check --- .../apache/druid/java/util/common/URIs.java | 43 ++++++++++++ .../druid/java/util/common/URIsTest.java | 70 +++++++++++++++++++ .../storage/s3/S3StorageDruidModule.java | 4 +- 3 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/org/apache/druid/java/util/common/URIs.java create mode 100644 core/src/test/java/org/apache/druid/java/util/common/URIsTest.java diff --git a/core/src/main/java/org/apache/druid/java/util/common/URIs.java b/core/src/main/java/org/apache/druid/java/util/common/URIs.java new file mode 100644 index 00000000000..f2476e71f09 --- /dev/null +++ b/core/src/main/java/org/apache/druid/java/util/common/URIs.java @@ -0,0 +1,43 @@ +/* + * 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.java.util.common; + +import com.google.common.base.Preconditions; + +import java.net.URI; + +public final class URIs +{ + public static URI parse(String strUri, String defaultScheme) + { + Preconditions.checkNotNull(strUri, "strUri"); + Preconditions.checkNotNull(defaultScheme, "defaultScheme"); + final String[] tokens = strUri.split("://"); + if (tokens.length == 1) { + return URI.create(StringUtils.format("%s://%s", defaultScheme, strUri)); + } else { + return URI.create(strUri); + } + } + + private URIs() + { + } +} diff --git a/core/src/test/java/org/apache/druid/java/util/common/URIsTest.java b/core/src/test/java/org/apache/druid/java/util/common/URIsTest.java new file mode 100644 index 00000000000..bb65e8e5981 --- /dev/null +++ b/core/src/test/java/org/apache/druid/java/util/common/URIsTest.java @@ -0,0 +1,70 @@ +/* + * 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.java.util.common; + +import org.junit.Assert; +import org.junit.Test; + +import java.net.URI; + +public class URIsTest +{ + @Test + public void testFullUri() + { + final String strUri = "https://test-user@127.0.0.1:8000/test/path?test-query#test-fragment"; + final URI uri = URIs.parse(strUri, "http"); + + Assert.assertEquals("https", uri.getScheme()); + Assert.assertEquals("test-user", uri.getUserInfo()); + Assert.assertEquals("127.0.0.1", uri.getHost()); + Assert.assertEquals(8000, uri.getPort()); + Assert.assertEquals("/test/path", uri.getPath()); + Assert.assertEquals("test-query", uri.getQuery()); + Assert.assertEquals("test-fragment", uri.getFragment()); + } + + @Test + public void testWithoutScheme() + { + final String strUri = "test-user@127.0.0.1:8000/test/path?test-query#test-fragment"; + final URI uri = URIs.parse(strUri, "http"); + + Assert.assertEquals("http", uri.getScheme()); + Assert.assertEquals("test-user", uri.getUserInfo()); + Assert.assertEquals("127.0.0.1", uri.getHost()); + Assert.assertEquals(8000, uri.getPort()); + Assert.assertEquals("/test/path", uri.getPath()); + Assert.assertEquals("test-query", uri.getQuery()); + Assert.assertEquals("test-fragment", uri.getFragment()); + } + + @Test + public void testSimpleUri() + { + final String strUri = "127.0.0.1:8000"; + final URI uri = URIs.parse(strUri, "https"); + + Assert.assertEquals("https", uri.getScheme()); + Assert.assertNull(uri.getUserInfo()); + Assert.assertEquals("127.0.0.1", uri.getHost()); + Assert.assertEquals(8000, uri.getPort()); + } +} diff --git a/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3StorageDruidModule.java b/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3StorageDruidModule.java index 2bac01896b8..61d145d591e 100644 --- a/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3StorageDruidModule.java +++ b/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3StorageDruidModule.java @@ -43,6 +43,7 @@ import org.apache.druid.guice.JsonConfigProvider; import org.apache.druid.guice.LazySingleton; import org.apache.druid.initialization.DruidModule; import org.apache.druid.java.util.common.IAE; +import org.apache.druid.java.util.common.URIs; import org.apache.druid.java.util.common.logger.Logger; import javax.annotation.Nullable; @@ -184,7 +185,8 @@ public class S3StorageDruidModule implements DruidModule final Protocol protocolFromClientConfig = parseProtocol(clientConfig.getProtocol()); final String endpointUrl = endpointConfig.getUrl(); if (StringUtils.isNotEmpty(endpointUrl)) { - final URI uri = URI.create(endpointUrl); + //noinspection ConstantConditions + final URI uri = URIs.parse(endpointUrl, protocolFromClientConfig.toString()); final Protocol protocol = parseProtocol(uri.getScheme()); if (protocol != null && (protocol != protocolFromClientConfig)) { log.warn("[%s] protocol will be used for endpoint [%s]", protocol, endpointUrl);