This is an automated email from the ASF dual-hosted git repository.

suneet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new c410648  fix injection failure of StorageLocationSelectorStrategy 
objects (#10363)
c410648 is described below

commit c4106486306df6fadf92994f7d33a88c6d952551
Author: frank chen <[email protected]>
AuthorDate: Wed Dec 9 01:48:31 2020 +0800

    fix injection failure of StorageLocationSelectorStrategy objects (#10363)
    
    * fix to allow customer storage location selector strategy
    
    * add test cases to check instance of selector strategy
    
    * update doc
    
    * code format
    
    * resolve code review comments
    
    * inject StorageLocation
    
    * fix CI
    
    * fix mismatched license item reported by CI
    
    * change property path from 
druid.segmentCache.locationSelectorStrategy.type to 
druid.segmentCache.locationSelector.strategy
    
    * using a helper method to bind to correct property path
---
 docs/configuration/index.md                        |   4 +-
 licenses.yaml                                      |  11 +-
 server/pom.xml                                     |   4 +
 .../org/apache/druid/guice/StorageNodeModule.java  |  23 ++++
 ...stBytesUsedStorageLocationSelectorStrategy.java |   7 +-
 ...ailableSizeStorageLocationSelectorStrategy.java |   7 +-
 .../RandomStorageLocationSelectorStrategy.java     |   7 +-
 .../RoundRobinStorageLocationSelectorStrategy.java |  11 +-
 .../druid/segment/loading/SegmentLoaderConfig.java |  31 +++---
 .../loading/SegmentLoaderLocalCacheManager.java    |  48 ++++++---
 .../loading/StorageLocationSelectorStrategy.java   |   2 +-
 .../SegmentLoaderLocalCacheManagerTest.java        |  22 ++--
 .../StorageLocationSelectorStrategyTest.java       | 118 +++++++++++++++++++++
 13 files changed, 226 insertions(+), 69 deletions(-)

diff --git a/docs/configuration/index.md b/docs/configuration/index.md
index 0755520..640ab0c 100644
--- a/docs/configuration/index.md
+++ b/docs/configuration/index.md
@@ -1409,7 +1409,7 @@ These Historical configurations can be defined in the 
`historical/runtime.proper
 |Property|Description|Default|
 |--------|-----------|-------|
 |`druid.segmentCache.locations`|Segments assigned to a Historical process are 
first stored on the local file system (in a disk cache) and then served by the 
Historical process. These locations define where that local cache resides. This 
value cannot be NULL or EMPTY. Here is an example 
`druid.segmentCache.locations=[{"path": "/mnt/druidSegments", "maxSize": "10k", 
"freeSpacePercent": 1.0}]`. "freeSpacePercent" is optional, if provided then 
enforces that much of free disk partition space  [...]
-|`druid.segmentCache.locationSelectorStrategy`|The strategy used to select a 
location from the configured `druid.segmentCache.locations` for segment 
distribution. Possible values are `leastBytesUsed`, `roundRobin`, `random`, or 
`mostAvailableSize`. |leastBytesUsed|
+|`druid.segmentCache.locationSelector.strategy`|The strategy used to select a 
location from the configured `druid.segmentCache.locations` for segment 
distribution. Possible values are `leastBytesUsed`, `roundRobin`, `random`, or 
`mostAvailableSize`. |leastBytesUsed|
 |`druid.segmentCache.deleteOnRemove`|Delete segment files from cache once a 
process is no longer serving a segment.|true|
 |`druid.segmentCache.dropSegmentDelayMillis`|How long a process delays before 
completely dropping segment.|30000 (30 seconds)|
 |`druid.segmentCache.infoDir`|Historical processes keep track of the segments 
they are serving so that when the process is restarted they can reload the same 
segments without waiting for the Coordinator to reassign. This path defines 
where this metadata is kept. Directory will be created if 
needed.|${first_location}/info_dir|
@@ -1421,7 +1421,7 @@ These Historical configurations can be defined in the 
`historical/runtime.proper
 
 In `druid.segmentCache.locations`, *freeSpacePercent* was added because 
*maxSize* setting is only a theoretical limit and assumes that much space will 
always be available for storing segments. In case of any druid bug leading to 
unaccounted segment files left alone on disk or some other process writing 
stuff to disk, This check can start failing segment loading early before 
filling up the disk completely and leaving the host usable otherwise.
 
-In `druid.segmentCache.locationSelectorStrategy`, one of leastBytesUsed, 
roundRobin, random, or mostAvailableSize could be specified to represent the 
strategy to distribute segments across multiple segment cache locations.
+In `druid.segmentCache.locationSelector.strategy`, one of `leastBytesUsed`, 
`roundRobin`, `random`, or `mostAvailableSize` could be specified to represent 
the strategy to distribute segments across multiple segment cache locations.
 
 |Strategy|Description|
 |--------|-----------|
diff --git a/licenses.yaml b/licenses.yaml
index 90a7ffd..31c3820 100644
--- a/licenses.yaml
+++ b/licenses.yaml
@@ -231,6 +231,7 @@ libraries:
   - com.fasterxml.jackson.jaxrs: jackson-jaxrs-json-provider
   - com.fasterxml.jackson.jaxrs: jackson-jaxrs-smile-provider
   - com.fasterxml.jackson.module: jackson-module-jaxb-annotations
+  - com.fasterxml.jackson.module: jackson-module-guice
 notice: |
   # Jackson JSON processor
 
@@ -4126,16 +4127,6 @@ libraries:
 
 ---
 
-name: "Jackson Module: Guice"
-license_category: binary
-module: java-core
-license_name: Apache License version 2.0
-version: 2.6.7
-libraries:
-  - com.fasterxml.jackson.module: jackson-module-guice
-
----
-
 name: Google APIs Client Library For Java
 license_category: binary
 module: java-core
diff --git a/server/pom.xml b/server/pom.xml
index caddf48..01b0d03 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -315,6 +315,10 @@
             <groupId>io.timeandspace</groupId>
             <artifactId>cron-scheduler</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.module</groupId>
+            <artifactId>jackson-module-guice</artifactId>
+        </dependency>
 
         <!-- Tests -->
         <dependency>
diff --git a/server/src/main/java/org/apache/druid/guice/StorageNodeModule.java 
b/server/src/main/java/org/apache/druid/guice/StorageNodeModule.java
index d3750a7..a232f6d 100644
--- a/server/src/main/java/org/apache/druid/guice/StorageNodeModule.java
+++ b/server/src/main/java/org/apache/druid/guice/StorageNodeModule.java
@@ -33,11 +33,14 @@ import org.apache.druid.java.util.emitter.EmittingLogger;
 import org.apache.druid.query.DruidProcessingConfig;
 import org.apache.druid.segment.column.ColumnConfig;
 import org.apache.druid.segment.loading.SegmentLoaderConfig;
+import org.apache.druid.segment.loading.StorageLocation;
+import org.apache.druid.segment.loading.StorageLocationSelectorStrategy;
 import org.apache.druid.server.DruidNode;
 import org.apache.druid.server.coordination.DruidServerMetadata;
 import org.apache.druid.server.coordination.ServerType;
 
 import javax.annotation.Nullable;
+import java.util.List;
 
 /**
  */
@@ -52,6 +55,7 @@ public class StorageNodeModule implements Module
   {
     JsonConfigProvider.bind(binder, "druid.server", DruidServerConfig.class);
     JsonConfigProvider.bind(binder, "druid.segmentCache", 
SegmentLoaderConfig.class);
+    bindLocationSelectorStrategy(binder);
 
     binder.bind(ServerTypeConfig.class).toProvider(Providers.of(null));
     binder.bind(ColumnConfig.class).to(DruidProcessingConfig.class);
@@ -117,4 +121,23 @@ public class StorageNodeModule implements Module
   {
     return !segmentLoaderConfig.getLocations().isEmpty();
   }
+
+  /**
+   * provide a list of StorageLocation
+   * so that it can be injected into objects such as implementations of {@link 
StorageLocationSelectorStrategy}
+   */
+  @Provides
+  @LazySingleton
+  public List<StorageLocation> provideStorageLocation(SegmentLoaderConfig 
config)
+  {
+    return config.toStorageLocations();
+  }
+
+  /**
+   * a helper method for both storage module and independent unit test cases
+   */
+  public static void bindLocationSelectorStrategy(Binder binder)
+  {
+    JsonConfigProvider.bind(binder, "druid.segmentCache.locationSelector", 
StorageLocationSelectorStrategy.class);
+  }
 }
diff --git 
a/server/src/main/java/org/apache/druid/segment/loading/LeastBytesUsedStorageLocationSelectorStrategy.java
 
b/server/src/main/java/org/apache/druid/segment/loading/LeastBytesUsedStorageLocationSelectorStrategy.java
index e1e9418..bcc37e3 100644
--- 
a/server/src/main/java/org/apache/druid/segment/loading/LeastBytesUsedStorageLocationSelectorStrategy.java
+++ 
b/server/src/main/java/org/apache/druid/segment/loading/LeastBytesUsedStorageLocationSelectorStrategy.java
@@ -19,6 +19,8 @@
 
 package org.apache.druid.segment.loading;
 
+import com.fasterxml.jackson.annotation.JacksonInject;
+import com.fasterxml.jackson.annotation.JsonCreator;
 import com.google.common.collect.Ordering;
 
 import java.util.Comparator;
@@ -34,9 +36,10 @@ public class LeastBytesUsedStorageLocationSelectorStrategy 
implements StorageLoc
   private static final Ordering<StorageLocation> ORDERING = 
Ordering.from(Comparator
       .comparingLong(StorageLocation::currSizeBytes));
 
-  private List<StorageLocation> storageLocations;
+  private final List<StorageLocation> storageLocations;
 
-  public LeastBytesUsedStorageLocationSelectorStrategy(List<StorageLocation> 
storageLocations)
+  @JsonCreator
+  public LeastBytesUsedStorageLocationSelectorStrategy(@JacksonInject final 
List<StorageLocation> storageLocations)
   {
     this.storageLocations = storageLocations;
   }
diff --git 
a/server/src/main/java/org/apache/druid/segment/loading/MostAvailableSizeStorageLocationSelectorStrategy.java
 
b/server/src/main/java/org/apache/druid/segment/loading/MostAvailableSizeStorageLocationSelectorStrategy.java
index 4790f90..4e4a84c 100644
--- 
a/server/src/main/java/org/apache/druid/segment/loading/MostAvailableSizeStorageLocationSelectorStrategy.java
+++ 
b/server/src/main/java/org/apache/druid/segment/loading/MostAvailableSizeStorageLocationSelectorStrategy.java
@@ -19,6 +19,8 @@
 
 package org.apache.druid.segment.loading;
 
+import com.fasterxml.jackson.annotation.JacksonInject;
+import com.fasterxml.jackson.annotation.JsonCreator;
 import com.google.common.collect.Ordering;
 
 import java.util.Comparator;
@@ -35,9 +37,10 @@ public class 
MostAvailableSizeStorageLocationSelectorStrategy implements Storage
       .comparingLong(StorageLocation::availableSizeBytes)
       .reversed());
 
-  private List<StorageLocation> storageLocations;
+  private final List<StorageLocation> storageLocations;
 
-  public 
MostAvailableSizeStorageLocationSelectorStrategy(List<StorageLocation> 
storageLocations)
+  @JsonCreator
+  public MostAvailableSizeStorageLocationSelectorStrategy(@JacksonInject final 
List<StorageLocation> storageLocations)
   {
     this.storageLocations = storageLocations;
   }
diff --git 
a/server/src/main/java/org/apache/druid/segment/loading/RandomStorageLocationSelectorStrategy.java
 
b/server/src/main/java/org/apache/druid/segment/loading/RandomStorageLocationSelectorStrategy.java
index 85df860..ed0114a 100644
--- 
a/server/src/main/java/org/apache/druid/segment/loading/RandomStorageLocationSelectorStrategy.java
+++ 
b/server/src/main/java/org/apache/druid/segment/loading/RandomStorageLocationSelectorStrategy.java
@@ -19,6 +19,9 @@
 
 package org.apache.druid.segment.loading;
 
+import com.fasterxml.jackson.annotation.JacksonInject;
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
@@ -33,7 +36,8 @@ public class RandomStorageLocationSelectorStrategy implements 
StorageLocationSel
 
   private final List<StorageLocation> storageLocations;
 
-  public RandomStorageLocationSelectorStrategy(List<StorageLocation> 
storageLocations)
+  @JsonCreator
+  public RandomStorageLocationSelectorStrategy(@JacksonInject final 
List<StorageLocation> storageLocations)
   {
     this.storageLocations = storageLocations;
   }
@@ -45,5 +49,4 @@ public class RandomStorageLocationSelectorStrategy implements 
StorageLocationSel
     Collections.shuffle(copyLocation);
     return copyLocation.iterator();
   }
-
 }
diff --git 
a/server/src/main/java/org/apache/druid/segment/loading/RoundRobinStorageLocationSelectorStrategy.java
 
b/server/src/main/java/org/apache/druid/segment/loading/RoundRobinStorageLocationSelectorStrategy.java
index 5e702c9..95e57f5 100644
--- 
a/server/src/main/java/org/apache/druid/segment/loading/RoundRobinStorageLocationSelectorStrategy.java
+++ 
b/server/src/main/java/org/apache/druid/segment/loading/RoundRobinStorageLocationSelectorStrategy.java
@@ -19,6 +19,9 @@
 
 package org.apache.druid.segment.loading;
 
+import com.fasterxml.jackson.annotation.JacksonInject;
+import com.fasterxml.jackson.annotation.JsonCreator;
+
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
@@ -32,11 +35,11 @@ import java.util.concurrent.atomic.AtomicInteger;
  */
 public class RoundRobinStorageLocationSelectorStrategy implements 
StorageLocationSelectorStrategy
 {
-
   private final List<StorageLocation> storageLocations;
   private final AtomicInteger startIndex = new AtomicInteger(0);
 
-  public RoundRobinStorageLocationSelectorStrategy(List<StorageLocation> 
storageLocations)
+  @JsonCreator
+  public RoundRobinStorageLocationSelectorStrategy(@JacksonInject 
List<StorageLocation> storageLocations)
   {
     this.storageLocations = storageLocations;
   }
@@ -44,7 +47,8 @@ public class RoundRobinStorageLocationSelectorStrategy 
implements StorageLocatio
   @Override
   public Iterator<StorageLocation> getLocations()
   {
-    return new Iterator<StorageLocation>() {
+    return new Iterator<StorageLocation>()
+    {
 
       private final int numStorageLocations = storageLocations.size();
       private int remainingIterations = numStorageLocations;
@@ -73,5 +77,4 @@ public class RoundRobinStorageLocationSelectorStrategy 
implements StorageLocatio
       }
     };
   }
-
 }
diff --git 
a/server/src/main/java/org/apache/druid/segment/loading/SegmentLoaderConfig.java
 
b/server/src/main/java/org/apache/druid/segment/loading/SegmentLoaderConfig.java
index edd2c0d..b2cf075 100644
--- 
a/server/src/main/java/org/apache/druid/segment/loading/SegmentLoaderConfig.java
+++ 
b/server/src/main/java/org/apache/druid/segment/loading/SegmentLoaderConfig.java
@@ -20,7 +20,6 @@
 package org.apache.druid.segment.loading;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Lists;
 import org.apache.druid.utils.JvmUtils;
 
@@ -28,6 +27,7 @@ import java.io.File;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  *
@@ -55,9 +55,6 @@ public class SegmentLoaderConfig
   @JsonProperty("numBootstrapThreads")
   private Integer numBootstrapThreads = null;
 
-  @JsonProperty("locationSelectorStrategy")
-  private StorageLocationSelectorStrategy locationSelectorStrategy;
-
   @JsonProperty
   private File infoDir = null;
 
@@ -101,15 +98,6 @@ public class SegmentLoaderConfig
     return numBootstrapThreads == null ? numLoadingThreads : 
numBootstrapThreads;
   }
 
-  public StorageLocationSelectorStrategy 
getStorageLocationSelectorStrategy(List<StorageLocation> storageLocations)
-  {
-    if (locationSelectorStrategy == null) {
-      // default strategy if no strategy is specified in the config
-      locationSelectorStrategy = new 
LeastBytesUsedStorageLocationSelectorStrategy(storageLocations);
-    }
-    return locationSelectorStrategy;
-  }
-
   public File getInfoDir()
   {
     if (infoDir == null) {
@@ -140,11 +128,19 @@ public class SegmentLoaderConfig
     return retVal;
   }
 
-  @VisibleForTesting
-  SegmentLoaderConfig 
withStorageLocationSelectorStrategy(StorageLocationSelectorStrategy strategy)
+  /**
+   * Convert StorageLocationConfig objects to StorageLocation objects
+   *
+   * Note: {@link #getLocations} is called instead of variable access because 
some testcases overrides this method
+   */
+  public List<StorageLocation> toStorageLocations()
   {
-    this.locationSelectorStrategy = strategy;
-    return this;
+    return this.getLocations()
+               .stream()
+               .map(locationConfig -> new 
StorageLocation(locationConfig.getPath(),
+                                                          
locationConfig.getMaxSize(),
+                                                          
locationConfig.getFreeSpacePercent()))
+               .collect(Collectors.toList());
   }
 
   @Override
@@ -154,7 +150,6 @@ public class SegmentLoaderConfig
            "locations=" + locations +
            ", deleteOnRemove=" + deleteOnRemove +
            ", dropSegmentDelayMillis=" + dropSegmentDelayMillis +
-           ", locationSelectorStrategy=" + locationSelectorStrategy +
            ", infoDir=" + infoDir +
            '}';
   }
diff --git 
a/server/src/main/java/org/apache/druid/segment/loading/SegmentLoaderLocalCacheManager.java
 
b/server/src/main/java/org/apache/druid/segment/loading/SegmentLoaderLocalCacheManager.java
index 80e8dc6..2aa2038 100644
--- 
a/server/src/main/java/org/apache/druid/segment/loading/SegmentLoaderLocalCacheManager.java
+++ 
b/server/src/main/java/org/apache/druid/segment/loading/SegmentLoaderLocalCacheManager.java
@@ -30,9 +30,9 @@ import org.apache.druid.segment.IndexIO;
 import org.apache.druid.segment.Segment;
 import org.apache.druid.timeline.DataSegment;
 
+import javax.annotation.Nonnull;
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
@@ -82,24 +82,48 @@ public class SegmentLoaderLocalCacheManager implements 
SegmentLoader
   @Inject
   public SegmentLoaderLocalCacheManager(
       IndexIO indexIO,
+      List<StorageLocation> locations,
       SegmentLoaderConfig config,
+      @Nonnull StorageLocationSelectorStrategy strategy,
       @Json ObjectMapper mapper
   )
   {
     this.indexIO = indexIO;
     this.config = config;
     this.jsonMapper = mapper;
-    this.locations = new ArrayList<>();
-    for (StorageLocationConfig locationConfig : config.getLocations()) {
-      locations.add(
-          new StorageLocation(
-              locationConfig.getPath(),
-              locationConfig.getMaxSize(),
-              locationConfig.getFreeSpacePercent()
-          )
-      );
-    }
-    this.strategy = config.getStorageLocationSelectorStrategy(locations);
+    this.locations = locations;
+    this.strategy = strategy;
+    log.info("Using storage location strategy: [%s]", 
this.strategy.getClass().getSimpleName());
+  }
+
+  @VisibleForTesting
+  SegmentLoaderLocalCacheManager(
+      IndexIO indexIO,
+      SegmentLoaderConfig config,
+      @Nonnull StorageLocationSelectorStrategy strategy,
+      @Json ObjectMapper mapper
+  )
+  {
+    this(indexIO, config.toStorageLocations(), config, strategy, mapper);
+  }
+
+  /**
+   * creates instance with default storage location selector strategy
+   *
+   * This ctor is mainly for test cases, including test cases in other modules
+   */
+  public SegmentLoaderLocalCacheManager(
+      IndexIO indexIO,
+      SegmentLoaderConfig config,
+      @Json ObjectMapper mapper
+  )
+  {
+    this.indexIO = indexIO;
+    this.config = config;
+    this.jsonMapper = mapper;
+    this.locations = config.toStorageLocations();
+    this.strategy = new 
LeastBytesUsedStorageLocationSelectorStrategy(locations);
+    log.info("Using storage location strategy: [%s]", 
this.strategy.getClass().getSimpleName());
   }
 
   @Override
diff --git 
a/server/src/main/java/org/apache/druid/segment/loading/StorageLocationSelectorStrategy.java
 
b/server/src/main/java/org/apache/druid/segment/loading/StorageLocationSelectorStrategy.java
index adc7388..57977d6 100644
--- 
a/server/src/main/java/org/apache/druid/segment/loading/StorageLocationSelectorStrategy.java
+++ 
b/server/src/main/java/org/apache/druid/segment/loading/StorageLocationSelectorStrategy.java
@@ -34,7 +34,7 @@ import java.util.Iterator;
  * https://github.com/apache/druid/pull/8038#discussion_r325520829 of PR 
https://github
  * .com/apache/druid/pull/8038 for more details.
  */
-@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl =
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "strategy", defaultImpl =
     LeastBytesUsedStorageLocationSelectorStrategy.class)
 @JsonSubTypes(value = {
     @JsonSubTypes.Type(name = "leastBytesUsed", value = 
LeastBytesUsedStorageLocationSelectorStrategy.class),
diff --git 
a/server/src/test/java/org/apache/druid/segment/loading/SegmentLoaderLocalCacheManagerTest.java
 
b/server/src/test/java/org/apache/druid/segment/loading/SegmentLoaderLocalCacheManagerTest.java
index 3130696..a01aef4 100644
--- 
a/server/src/test/java/org/apache/druid/segment/loading/SegmentLoaderLocalCacheManagerTest.java
+++ 
b/server/src/test/java/org/apache/druid/segment/loading/SegmentLoaderLocalCacheManagerTest.java
@@ -422,9 +422,8 @@ public class SegmentLoaderLocalCacheManagerTest
 
     manager = new SegmentLoaderLocalCacheManager(
       TestHelper.getTestIndexIO(),
-      new 
SegmentLoaderConfig().withLocations(locationConfigs).withStorageLocationSelectorStrategy(
-        new RoundRobinStorageLocationSelectorStrategy(locations)
-      ),
+      new SegmentLoaderConfig().withLocations(locationConfigs),
+      new RoundRobinStorageLocationSelectorStrategy(locations),
       jsonMapper
     );
     final File segmentSrcFolder = tmpFolder.newFolder("segmentSrcFolder");
@@ -669,21 +668,12 @@ public class SegmentLoaderLocalCacheManagerTest
     locationConfigs.add(locationConfig2);
     locationConfigs.add(locationConfig3);
 
-    List<StorageLocation> locations = new ArrayList<>();
-    for (StorageLocationConfig locConfig : locationConfigs) {
-      locations.add(
-              new StorageLocation(
-                      locConfig.getPath(),
-                      locConfig.getMaxSize(),
-                      null
-              )
-      );
-    }
+    SegmentLoaderConfig segmentLoaderConfig = new 
SegmentLoaderConfig().withLocations(locationConfigs);
+
     manager = new SegmentLoaderLocalCacheManager(
             TestHelper.getTestIndexIO(),
-            new 
SegmentLoaderConfig().withLocations(locationConfigs).withStorageLocationSelectorStrategy(
-                    new RandomStorageLocationSelectorStrategy(locations)
-            ),
+            new SegmentLoaderConfig().withLocations(locationConfigs),
+            new 
RandomStorageLocationSelectorStrategy(segmentLoaderConfig.toStorageLocations()),
             jsonMapper
     );
 
diff --git 
a/server/src/test/java/org/apache/druid/segment/loading/StorageLocationSelectorStrategyTest.java
 
b/server/src/test/java/org/apache/druid/segment/loading/StorageLocationSelectorStrategyTest.java
index 82cbe70..a2bfb5b 100644
--- 
a/server/src/test/java/org/apache/druid/segment/loading/StorageLocationSelectorStrategyTest.java
+++ 
b/server/src/test/java/org/apache/druid/segment/loading/StorageLocationSelectorStrategyTest.java
@@ -19,16 +19,31 @@
 
 package org.apache.druid.segment.loading;
 
+import com.fasterxml.jackson.module.guice.ObjectMapperModule;
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.Provides;
+import org.apache.druid.guice.DruidGuiceExtensions;
+import org.apache.druid.guice.JsonConfigProvider;
+import org.apache.druid.guice.JsonConfigurator;
+import org.apache.druid.guice.LazySingleton;
+import org.apache.druid.guice.StorageNodeModule;
+import org.apache.druid.jackson.DefaultObjectMapper;
 import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 
+import javax.validation.Validation;
+import javax.validation.Validator;
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Properties;
 
 public class StorageLocationSelectorStrategyTest
 {
@@ -256,4 +271,107 @@ public class StorageLocationSelectorStrategyTest
     Assert.assertEquals("The next element of the iterator should point to path 
local_storage_folder_1",
         localStorageFolder1, loc3.getPath());
   }
+
+  @Test
+  public void testDefaultSelectorStrategyConfig()
+  {
+    //no druid.segmentCache.locationSelector.strategy specified, the default 
will be used
+    final Properties props = new Properties();
+    props.setProperty("druid.segmentCache.locations", "[{\"path\": 
\"/tmp/druid/indexCache\"}]");
+
+    StorageLocationSelectorStrategy strategy = 
makeInjectorWithProperties(props).getInstance(StorageLocationSelectorStrategy.class);
+    Assert.assertEquals(LeastBytesUsedStorageLocationSelectorStrategy.class,
+                        strategy.getClass());
+    Assert.assertEquals("/tmp/druid/indexCache", 
strategy.getLocations().next().getPath().getAbsolutePath());
+  }
+
+  @Test
+  public void testRoundRobinSelectorStrategyConfig()
+  {
+    final Properties props = new Properties();
+    props.setProperty("druid.segmentCache.locations", "[{\"path\": 
\"/tmp/druid/indexCache\"}]");
+    props.setProperty("druid.segmentCache.locationSelector.strategy", 
"roundRobin");
+
+    Injector injector = makeInjectorWithProperties(props);
+    StorageLocationSelectorStrategy strategy = 
injector.getInstance(StorageLocationSelectorStrategy.class);
+
+    Assert.assertEquals(RoundRobinStorageLocationSelectorStrategy.class,
+                        strategy.getClass());
+    Assert.assertEquals("/tmp/druid/indexCache", 
strategy.getLocations().next().getPath().getAbsolutePath());
+  }
+
+  @Test
+  public void testLeastBytesUsedSelectorStrategyConfig()
+  {
+    final Properties props = new Properties();
+    props.setProperty("druid.segmentCache.locations", "[{\"path\": 
\"/tmp/druid/indexCache\"}]");
+    props.setProperty("druid.segmentCache.locationSelector.strategy", 
"leastBytesUsed");
+
+    Injector injector = makeInjectorWithProperties(props);
+    StorageLocationSelectorStrategy strategy = 
injector.getInstance(StorageLocationSelectorStrategy.class);
+
+    Assert.assertEquals(LeastBytesUsedStorageLocationSelectorStrategy.class,
+                        strategy.getClass());
+    Assert.assertEquals("/tmp/druid/indexCache", 
strategy.getLocations().next().getPath().getAbsolutePath());
+  }
+
+  @Test
+  public void testRandomSelectorStrategyConfig()
+  {
+    final Properties props = new Properties();
+    props.setProperty("druid.segmentCache.locations", "[{\"path\": 
\"/tmp/druid/indexCache\"}]");
+    props.setProperty("druid.segmentCache.locationSelector.strategy", 
"random");
+
+    Injector injector = makeInjectorWithProperties(props);
+    StorageLocationSelectorStrategy strategy = 
injector.getInstance(StorageLocationSelectorStrategy.class);
+
+    Assert.assertEquals(RandomStorageLocationSelectorStrategy.class,
+                        strategy.getClass());
+    Assert.assertEquals("/tmp/druid/indexCache", 
strategy.getLocations().next().getPath().getAbsolutePath());
+  }
+
+  @Test
+  public void testMostAvailableSizeSelectorStrategyConfig()
+  {
+    final Properties props = new Properties();
+    props.setProperty("druid.segmentCache.locationSelector.strategy", 
"mostAvailableSize");
+    props.setProperty("druid.segmentCache.locations", "[{\"path\": 
\"/tmp/druid/indexCache\"}]");
+
+    Injector injector = makeInjectorWithProperties(props);
+    StorageLocationSelectorStrategy strategy = 
injector.getInstance(StorageLocationSelectorStrategy.class);
+
+    Assert.assertEquals(MostAvailableSizeStorageLocationSelectorStrategy.class,
+                        strategy.getClass());
+    Assert.assertEquals("/tmp/druid/indexCache", 
strategy.getLocations().next().getPath().getAbsolutePath());
+  }
+
+  private Injector makeInjectorWithProperties(final Properties props)
+  {
+    return Guice.createInjector(
+        new Module()
+          {
+            @Override
+            public void configure(Binder binder)
+            {
+              //ObjectMapperModule introduce Guice injector for jackson
+              binder.install(new ObjectMapperModule()
+                                 .withObjectMapper(new DefaultObjectMapper()));
+              binder.install(new DruidGuiceExtensions());
+
+              
binder.bind(Validator.class).toInstance(Validation.buildDefaultValidatorFactory().getValidator());
+              binder.bind(JsonConfigurator.class).in(LazySingleton.class);
+              binder.bind(Properties.class).toInstance(props);
+
+              JsonConfigProvider.bind(binder, "druid.segmentCache", 
SegmentLoaderConfig.class);
+              StorageNodeModule.bindLocationSelectorStrategy(binder);
+            }
+
+            @Provides
+            public List provideStorageLocation(SegmentLoaderConfig 
segmentLoader)
+            {
+              return segmentLoader.toStorageLocations();
+            }
+          }
+      );
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to