Browse Source

Merge branch '10.3.x'

Shinsuke Sugaya 8 năm trước cách đây
mục cha
commit
5676f46667
27 tập tin đã thay đổi với 389 bổ sung41 xóa
  1. 4 0
      src/main/assemblies/files/fess.in.bat
  2. 4 0
      src/main/config/es/fess_config.json
  3. 2 0
      src/main/java/org/codelibs/fess/Constants.java
  4. 2 2
      src/main/java/org/codelibs/fess/app/service/BadWordService.java
  5. 2 2
      src/main/java/org/codelibs/fess/app/service/ElevateWordService.java
  6. 1 1
      src/main/java/org/codelibs/fess/app/web/admin/backup/AdminBackupAction.java
  7. 48 3
      src/main/java/org/codelibs/fess/app/web/admin/upgrade/AdminUpgradeAction.java
  8. 6 6
      src/main/java/org/codelibs/fess/ds/impl/GitBucketDataStoreImpl.java
  9. 4 4
      src/main/java/org/codelibs/fess/entity/PingResponse.java
  10. 1 0
      src/main/java/org/codelibs/fess/es/config/bsbhv/BsThumbnailQueueBhv.java
  11. 17 0
      src/main/java/org/codelibs/fess/es/config/bsentity/BsThumbnailQueue.java
  12. 9 0
      src/main/java/org/codelibs/fess/es/config/bsentity/dbmeta/ThumbnailQueueDbm.java
  13. 4 0
      src/main/java/org/codelibs/fess/es/config/cbean/bs/BsThumbnailQueueCB.java
  14. 207 0
      src/main/java/org/codelibs/fess/es/config/cbean/cq/bs/BsThumbnailQueueCQ.java
  15. 1 1
      src/main/java/org/codelibs/fess/es/config/exentity/AccessToken.java
  16. 14 4
      src/main/java/org/codelibs/fess/es/config/exentity/CrawlingConfigWrapper.java
  17. 2 1
      src/main/java/org/codelibs/fess/helper/SystemHelper.java
  18. 14 0
      src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java
  19. 8 0
      src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java
  20. 27 11
      src/main/java/org/codelibs/fess/thumbnail/ThumbnailManager.java
  21. 2 1
      src/main/java/org/codelibs/fess/thumbnail/impl/BaseThumbnailGenerator.java
  22. 2 2
      src/main/java/org/codelibs/fess/thumbnail/impl/WebDriverGenerator.java
  23. 1 0
      src/main/resources/fess_config.properties
  24. 4 0
      src/main/resources/fess_indices/.fess_config/thumbnail_queue.json
  25. 1 1
      src/main/webapp/WEB-INF/view/admin/accesstoken/admin_accesstoken.jsp
  26. 1 1
      src/main/webapp/WEB-INF/view/admin/accesstoken/admin_accesstoken_details.jsp
  27. 1 1
      src/main/webapp/WEB-INF/view/admin/accesstoken/admin_accesstoken_edit.jsp

+ 4 - 0
src/main/assemblies/files/fess.in.bat

@@ -84,7 +84,11 @@ set APP_NAME=fess
 set ES_HOME=%FESS_HOME%/es
 set ES_HOME=%FESS_HOME%/es
 
 
 set FESS_CLASSPATH=%FESS_HOME%\lib\classes
 set FESS_CLASSPATH=%FESS_HOME%\lib\classes
+if ""%FESS_JAVA_OPTS%""=="""" (
+set FESS_JAVA_OPTS=-Dfess
+) else (
 set FESS_JAVA_OPTS=-Dfess %FESS_JAVA_OPTS%
 set FESS_JAVA_OPTS=-Dfess %FESS_JAVA_OPTS%
+)
 set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Des-foreground=yes
 set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Des-foreground=yes
 set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Dfess.home="%FESS_HOME%"
 set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Dfess.home="%FESS_HOME%"
 set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Dfess.es.dir="%ES_HOME%"
 set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Dfess.es.dir="%ES_HOME%"

+ 4 - 0
src/main/config/es/fess_config.json

@@ -975,6 +975,10 @@
           "createdTime" : {
           "createdTime" : {
             "type" : "long"
             "type" : "long"
           },
           },
+          "target" : {
+            "type" : "string",
+            "index" : "not_analyzed"
+          },
           "generator" : {
           "generator" : {
             "type" : "string",
             "type" : "string",
             "index" : "not_analyzed"
             "index" : "not_analyzed"

+ 2 - 0
src/main/java/org/codelibs/fess/Constants.java

@@ -404,4 +404,6 @@ public class Constants extends CoreLibConstants {
     public static final String PERMISSIONS = "permissions";
     public static final String PERMISSIONS = "permissions";
 
 
     public static final String CIPHER_PREFIX = "{cipher}";
     public static final String CIPHER_PREFIX = "{cipher}";
+
+    public static final String SYSTEM_USER = "system";
 }
 }

+ 2 - 2
src/main/java/org/codelibs/fess/app/service/BadWordService.java

@@ -123,11 +123,11 @@ public class BadWordService {
                     } else if (badWord == null) {
                     } else if (badWord == null) {
                         badWord = new BadWord();
                         badWord = new BadWord();
                         badWord.setSuggestWord(targetWord);
                         badWord.setSuggestWord(targetWord);
-                        badWord.setCreatedBy("system");
+                        badWord.setCreatedBy(Constants.SYSTEM_USER);
                         badWord.setCreatedTime(now);
                         badWord.setCreatedTime(now);
                         badWordBhv.insert(badWord);
                         badWordBhv.insert(badWord);
                     } else {
                     } else {
-                        badWord.setUpdatedBy("system");
+                        badWord.setUpdatedBy(Constants.SYSTEM_USER);
                         badWord.setUpdatedTime(now);
                         badWord.setUpdatedTime(now);
                         badWordBhv.update(badWord);
                         badWordBhv.update(badWord);
                     }
                     }

+ 2 - 2
src/main/java/org/codelibs/fess/app/service/ElevateWordService.java

@@ -221,7 +221,7 @@ public class ElevateWordService {
                         elevateWord.setPermissions(permissions);
                         elevateWord.setPermissions(permissions);
                         elevateWord.setTargetLabel(label);
                         elevateWord.setTargetLabel(label);
                         elevateWord.setBoost(StringUtil.isBlank(boost) ? 1.0f : Float.parseFloat(boost));
                         elevateWord.setBoost(StringUtil.isBlank(boost) ? 1.0f : Float.parseFloat(boost));
-                        elevateWord.setCreatedBy("system");
+                        elevateWord.setCreatedBy(Constants.SYSTEM_USER);
                         elevateWord.setCreatedTime(now);
                         elevateWord.setCreatedTime(now);
                         elevateWordBhv.insert(elevateWord);
                         elevateWordBhv.insert(elevateWord);
                     } else if (StringUtil.isBlank(reading) && StringUtil.isBlank(boost)) {
                     } else if (StringUtil.isBlank(reading) && StringUtil.isBlank(boost)) {
@@ -230,7 +230,7 @@ public class ElevateWordService {
                         elevateWord.setReading(reading);
                         elevateWord.setReading(reading);
                         elevateWord.setPermissions(permissions);
                         elevateWord.setPermissions(permissions);
                         elevateWord.setBoost(StringUtil.isBlank(boost) ? 1.0f : Float.parseFloat(boost));
                         elevateWord.setBoost(StringUtil.isBlank(boost) ? 1.0f : Float.parseFloat(boost));
-                        elevateWord.setUpdatedBy("system");
+                        elevateWord.setUpdatedBy(Constants.SYSTEM_USER);
                         elevateWord.setUpdatedTime(now);
                         elevateWord.setUpdatedTime(now);
                         elevateWordBhv.update(elevateWord);
                         elevateWordBhv.update(elevateWord);
                     }
                     }

+ 1 - 1
src/main/java/org/codelibs/fess/app/web/admin/backup/AdminBackupAction.java

@@ -77,7 +77,7 @@ public class AdminBackupAction extends FessAdminAction {
             if (fileName.startsWith("system") && fileName.endsWith(".properties")) {
             if (fileName.startsWith("system") && fileName.endsWith(".properties")) {
                 try (final InputStream in = form.bulkFile.getInputStream()) {
                 try (final InputStream in = form.bulkFile.getInputStream()) {
                     ComponentUtil.getSystemProperties().load(in);
                     ComponentUtil.getSystemProperties().load(in);
-                } catch (IOException e) {
+                } catch (final IOException e) {
                     logger.warn("Failed to process system.properties file: " + form.bulkFile.getFileName(), e);
                     logger.warn("Failed to process system.properties file: " + form.bulkFile.getFileName(), e);
                 }
                 }
             } else {
             } else {

+ 48 - 3
src/main/java/org/codelibs/fess/app/web/admin/upgrade/AdminUpgradeAction.java

@@ -59,11 +59,14 @@ import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
 import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
 import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
 import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
 import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
 import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData;
 import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData;
+import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
 import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
 import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
 import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
 import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
 import org.elasticsearch.action.index.IndexRequest;
 import org.elasticsearch.action.index.IndexRequest;
 import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.IndicesAdminClient;
+import org.elasticsearch.cluster.metadata.MappingMetaData;
+import org.elasticsearch.common.collect.ImmutableOpenMap;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentParser;
@@ -169,7 +172,7 @@ public class AdminUpgradeAction extends FessAdminAction {
 
 
                 saveInfo(messages -> messages.addSuccessUpgradeFrom(GLOBAL));
                 saveInfo(messages -> messages.addSuccessUpgradeFrom(GLOBAL));
 
 
-                fessEsClient.refresh();
+                systemHelper.reloadConfiguration();
             } catch (final Exception e) {
             } catch (final Exception e) {
                 logger.warn("Failed to upgrade data.", e);
                 logger.warn("Failed to upgrade data.", e);
                 saveError(messages -> messages.addErrorsFailedToUpgradeFrom(GLOBAL, VERSION_10_1, e.getLocalizedMessage()));
                 saveError(messages -> messages.addErrorsFailedToUpgradeFrom(GLOBAL, VERSION_10_1, e.getLocalizedMessage()));
@@ -182,7 +185,7 @@ public class AdminUpgradeAction extends FessAdminAction {
 
 
                 saveInfo(messages -> messages.addSuccessUpgradeFrom(GLOBAL));
                 saveInfo(messages -> messages.addSuccessUpgradeFrom(GLOBAL));
 
 
-                fessEsClient.refresh();
+                systemHelper.reloadConfiguration();
             } catch (final Exception e) {
             } catch (final Exception e) {
                 logger.warn("Failed to upgrade data.", e);
                 logger.warn("Failed to upgrade data.", e);
                 saveError(messages -> messages.addErrorsFailedToUpgradeFrom(GLOBAL, VERSION_10_1, e.getLocalizedMessage()));
                 saveError(messages -> messages.addErrorsFailedToUpgradeFrom(GLOBAL, VERSION_10_1, e.getLocalizedMessage()));
@@ -196,7 +199,7 @@ public class AdminUpgradeAction extends FessAdminAction {
 
 
                 saveInfo(messages -> messages.addSuccessUpgradeFrom(GLOBAL));
                 saveInfo(messages -> messages.addSuccessUpgradeFrom(GLOBAL));
 
 
-                fessEsClient.refresh();
+                systemHelper.reloadConfiguration();
             } catch (final Exception e) {
             } catch (final Exception e) {
                 logger.warn("Failed to upgrade data.", e);
                 logger.warn("Failed to upgrade data.", e);
                 saveError(messages -> messages.addErrorsFailedToUpgradeFrom(GLOBAL, VERSION_10_0, e.getLocalizedMessage()));
                 saveError(messages -> messages.addErrorsFailedToUpgradeFrom(GLOBAL, VERSION_10_0, e.getLocalizedMessage()));
@@ -224,11 +227,25 @@ public class AdminUpgradeAction extends FessAdminAction {
         final String searchIndex = fessConfig.getIndexDocumentSearchIndex();
         final String searchIndex = fessConfig.getIndexDocumentSearchIndex();
 
 
         // update mapping
         // update mapping
+        addMapping(indicesClient, updateIndex, "access_token", "fess_indices/.fess_config");
+        addMapping(indicesClient, updateIndex, "thumbnail_queue", "fess_indices/.fess_config");
+
         addFieldMapping(indicesClient, updateIndex, "doc", "filename",
         addFieldMapping(indicesClient, updateIndex, "doc", "filename",
                 "{\"properties\":{\"filename\":{\"type\":\"string\",\"index\":\"not_analyzed\"}}}");
                 "{\"properties\":{\"filename\":{\"type\":\"string\",\"index\":\"not_analyzed\"}}}");
         addFieldMapping(indicesClient, searchIndex, "doc", "filename",
         addFieldMapping(indicesClient, searchIndex, "doc", "filename",
                 "{\"properties\":{\"filename\":{\"type\":\"string\",\"index\":\"not_analyzed\"}}}");
                 "{\"properties\":{\"filename\":{\"type\":\"string\",\"index\":\"not_analyzed\"}}}");
         addFieldMapping(indicesClient, configIndex, "job_log", "lastUpdated", "{\"properties\":{\"lastUpdated\":{\"type\":\"long\"}}}");
         addFieldMapping(indicesClient, configIndex, "job_log", "lastUpdated", "{\"properties\":{\"lastUpdated\":{\"type\":\"long\"}}}");
+
+        // data migration
+        addData(configIndex,
+                "scheduled_job",
+                "thumbnail_generate",
+                "{\"name\":\"Thumbnail Generator\",\"target\":\"all\",\"cronExpression\":\"* * * * *\",\"scriptType\":\"groovy\",\"scriptData\":\"return container.getComponent(\\\"generateThumbnailJob\\\").execute();\",\"jobLogging\":false,\"crawler\":false,\"available\":true,\"sortOrder\":7,\"createdBy\":\"system\",\"createdTime\":0,\"updatedBy\":\"system\",\"updatedTime\":0}");
+        addData(configIndex,
+                "scheduled_job",
+                "ping_es",
+                "{\"name\":\"Ping Elasticsearch\",\"target\":\"all\",\"cronExpression\":\"* * * * *\",\"scriptType\":\"groovy\",\"scriptData\":\"return container.getComponent(\\\"pingEsJob\\\").execute();\",\"jobLogging\":false,\"crawler\":false,\"available\":true,\"sortOrder\":8,\"createdBy\":\"system\",\"createdTime\":0,\"updatedBy\":\"system\",\"updatedTime\":0}");
+
     }
     }
 
 
     private void upgradeFrom10_1() {
     private void upgradeFrom10_1() {
@@ -1030,6 +1047,34 @@ public class AdminUpgradeAction extends FessAdminAction {
         }
         }
     }
     }
 
 
+    private void addMapping(final IndicesAdminClient indicesClient, final String index, final String type, final String indexResourcePath) {
+        final GetMappingsResponse getMappingsResponse =
+                indicesClient.prepareGetMappings(index).execute().actionGet(fessConfig.getIndexIndicesTimeout());
+        final ImmutableOpenMap<String, MappingMetaData> indexMappings = getMappingsResponse.mappings().get(index);
+        if (indexMappings == null || !indexMappings.containsKey(type)) {
+            String source = null;
+            final String mappingFile = indexResourcePath + "/" + type + ".json";
+            try {
+                source = FileUtil.readUTF8(mappingFile);
+            } catch (final Exception e) {
+                logger.warn(mappingFile + " is not found.", e);
+            }
+            try {
+                final PutMappingResponse putMappingResponse =
+                        indicesClient.preparePutMapping(index).setType(type).setSource(source).execute()
+                                .actionGet(fessConfig.getIndexIndicesTimeout());
+                if (putMappingResponse.isAcknowledged()) {
+                    logger.info("Created " + index + "/" + type + " mapping.");
+                } else {
+                    logger.warn("Failed to create " + index + "/" + type + " mapping.");
+                }
+                // TODO bulk
+            } catch (final Exception e) {
+                logger.warn("Failed to create " + index + "/" + type + " mapping.", e);
+            }
+        }
+    }
+
     private void addFieldMapping(final IndicesAdminClient indicesClient, final String index, final String type, final String field,
     private void addFieldMapping(final IndicesAdminClient indicesClient, final String index, final String type, final String field,
             final String source) {
             final String source) {
         final GetFieldMappingsResponse gfmResponse =
         final GetFieldMappingsResponse gfmResponse =

+ 6 - 6
src/main/java/org/codelibs/fess/ds/impl/GitBucketDataStoreImpl.java

@@ -74,12 +74,12 @@ public class GitBucketDataStoreImpl extends AbstractDataStoreImpl {
 
 
         final CrawlingConfig crawlingConfig = new CrawlingConfigWrapper(dataConfig) {
         final CrawlingConfig crawlingConfig = new CrawlingConfigWrapper(dataConfig) {
             @Override
             @Override
-            public Map<String, Object> initializeClientFactory(CrawlerClientFactory crawlerClientFactory) {
+            public Map<String, Object> initializeClientFactory(final CrawlerClientFactory crawlerClientFactory) {
                 final Map<String, Object> paramMap = super.initializeClientFactory(crawlerClientFactory);
                 final Map<String, Object> paramMap = super.initializeClientFactory(crawlerClientFactory);
-                List<RequestHeader> headerList = new ArrayList<>();
-                RequestHeader[] headers = (RequestHeader[]) paramMap.get(HcHttpClient.REQUERT_HEADERS_PROPERTY);
+                final List<RequestHeader> headerList = new ArrayList<>();
+                final RequestHeader[] headers = (RequestHeader[]) paramMap.get(HcHttpClient.REQUERT_HEADERS_PROPERTY);
                 if (headers != null) {
                 if (headers != null) {
-                    for (RequestHeader header : headers) {
+                    for (final RequestHeader header : headers) {
                         headerList.add(header);
                         headerList.add(header);
                     }
                     }
                 }
                 }
@@ -175,7 +175,7 @@ public class GitBucketDataStoreImpl extends AbstractDataStoreImpl {
     }
     }
 
 
     private void storeFileContent(final String rootURL, final String authToken, final String owner, final String name,
     private void storeFileContent(final String rootURL, final String authToken, final String owner, final String name,
-            List<String> roleList, final String path, final CrawlingConfig crawlingConfig, final IndexUpdateCallback callback,
+            final List<String> roleList, final String path, final CrawlingConfig crawlingConfig, final IndexUpdateCallback callback,
             final Map<String, String> paramMap, final Map<String, String> scriptMap, final Map<String, Object> defaultDataMap) {
             final Map<String, String> paramMap, final Map<String, String> scriptMap, final Map<String, Object> defaultDataMap) {
         final String apiUrl = rootURL + "api/v3/repos/" + owner + "/" + name + "/contents/" + path;
         final String apiUrl = rootURL + "api/v3/repos/" + owner + "/" + name + "/contents/" + path;
         final String viewUrl = rootURL + owner + "/" + name + "/blob/master/" + path;
         final String viewUrl = rootURL + owner + "/" + name + "/blob/master/" + path;
@@ -199,7 +199,7 @@ public class GitBucketDataStoreImpl extends AbstractDataStoreImpl {
     }
     }
 
 
     protected void collectFileNames(final String rootURL, final String authToken, final String owner, final String name, final String path,
     protected void collectFileNames(final String rootURL, final String authToken, final String owner, final String name, final String path,
-            final int depth, final long readInterval, Consumer<String> consumer) {
+            final int depth, final long readInterval, final Consumer<String> consumer) {
 
 
         if (MAX_DEPTH <= depth) {
         if (MAX_DEPTH <= depth) {
             return;
             return;

+ 4 - 4
src/main/java/org/codelibs/fess/entity/PingResponse.java

@@ -21,13 +21,13 @@ import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
 import org.elasticsearch.cluster.health.ClusterHealthStatus;
 import org.elasticsearch.cluster.health.ClusterHealthStatus;
 
 
 public class PingResponse {
 public class PingResponse {
-    private int status;
+    private final int status;
 
 
-    private List<String> failures;
+    private final List<String> failures;
 
 
-    private String clusterName;
+    private final String clusterName;
 
 
-    private String clusterStatus;
+    private final String clusterStatus;
 
 
     public PingResponse(final ClusterHealthResponse response) {
     public PingResponse(final ClusterHealthResponse response) {
         status = response.getStatus() == ClusterHealthStatus.RED ? 1 : 0;
         status = response.getStatus() == ClusterHealthStatus.RED ? 1 : 0;

+ 1 - 0
src/main/java/org/codelibs/fess/es/config/bsbhv/BsThumbnailQueueBhv.java

@@ -75,6 +75,7 @@ public abstract class BsThumbnailQueueBhv extends EsAbstractBehavior<ThumbnailQu
             final RESULT result = entityType.newInstance();
             final RESULT result = entityType.newInstance();
             result.setCreatedBy(DfTypeUtil.toString(source.get("createdBy")));
             result.setCreatedBy(DfTypeUtil.toString(source.get("createdBy")));
             result.setCreatedTime(DfTypeUtil.toLong(source.get("createdTime")));
             result.setCreatedTime(DfTypeUtil.toLong(source.get("createdTime")));
+            result.setTarget(DfTypeUtil.toString(source.get("target")));
             result.setGenerator(DfTypeUtil.toString(source.get("generator")));
             result.setGenerator(DfTypeUtil.toString(source.get("generator")));
             result.setPath(DfTypeUtil.toString(source.get("path")));
             result.setPath(DfTypeUtil.toString(source.get("path")));
             result.setUrl(DfTypeUtil.toString(source.get("url")));
             result.setUrl(DfTypeUtil.toString(source.get("url")));

+ 17 - 0
src/main/java/org/codelibs/fess/es/config/bsentity/BsThumbnailQueue.java

@@ -43,6 +43,9 @@ public class BsThumbnailQueue extends EsAbstractEntity {
     /** createdTime */
     /** createdTime */
     protected Long createdTime;
     protected Long createdTime;
 
 
+    /** target */
+    protected String target;
+
     /** generator */
     /** generator */
     protected String generator;
     protected String generator;
 
 
@@ -79,6 +82,9 @@ public class BsThumbnailQueue extends EsAbstractEntity {
         if (createdTime != null) {
         if (createdTime != null) {
             sourceMap.put("createdTime", createdTime);
             sourceMap.put("createdTime", createdTime);
         }
         }
+        if (target != null) {
+            sourceMap.put("target", target);
+        }
         if (generator != null) {
         if (generator != null) {
             sourceMap.put("generator", generator);
             sourceMap.put("generator", generator);
         }
         }
@@ -99,6 +105,7 @@ public class BsThumbnailQueue extends EsAbstractEntity {
         StringBuilder sb = new StringBuilder();
         StringBuilder sb = new StringBuilder();
         sb.append(dm).append(createdBy);
         sb.append(dm).append(createdBy);
         sb.append(dm).append(createdTime);
         sb.append(dm).append(createdTime);
+        sb.append(dm).append(target);
         sb.append(dm).append(generator);
         sb.append(dm).append(generator);
         sb.append(dm).append(path);
         sb.append(dm).append(path);
         sb.append(dm).append(url);
         sb.append(dm).append(url);
@@ -132,6 +139,16 @@ public class BsThumbnailQueue extends EsAbstractEntity {
         this.createdTime = value;
         this.createdTime = value;
     }
     }
 
 
+    public String getTarget() {
+        checkSpecifiedProperty("target");
+        return convertEmptyToNull(target);
+    }
+
+    public void setTarget(String value) {
+        registerModifiedProperty("target");
+        this.target = value;
+    }
+
     public String getGenerator() {
     public String getGenerator() {
         checkSpecifiedProperty("generator");
         checkSpecifiedProperty("generator");
         return convertEmptyToNull(generator);
         return convertEmptyToNull(generator);

+ 9 - 0
src/main/java/org/codelibs/fess/es/config/bsentity/dbmeta/ThumbnailQueueDbm.java

@@ -83,6 +83,8 @@ public class ThumbnailQueueDbm extends AbstractDBMeta {
                 (et, vl) -> ((ThumbnailQueue) et).setCreatedBy(DfTypeUtil.toString(vl)), "createdBy");
                 (et, vl) -> ((ThumbnailQueue) et).setCreatedBy(DfTypeUtil.toString(vl)), "createdBy");
         setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getCreatedTime(),
         setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getCreatedTime(),
                 (et, vl) -> ((ThumbnailQueue) et).setCreatedTime(DfTypeUtil.toLong(vl)), "createdTime");
                 (et, vl) -> ((ThumbnailQueue) et).setCreatedTime(DfTypeUtil.toLong(vl)), "createdTime");
+        setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getTarget(), (et, vl) -> ((ThumbnailQueue) et).setTarget(DfTypeUtil.toString(vl)),
+                "target");
         setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getGenerator(),
         setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getGenerator(),
                 (et, vl) -> ((ThumbnailQueue) et).setGenerator(DfTypeUtil.toString(vl)), "generator");
                 (et, vl) -> ((ThumbnailQueue) et).setGenerator(DfTypeUtil.toString(vl)), "generator");
         setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getPath(), (et, vl) -> ((ThumbnailQueue) et).setPath(DfTypeUtil.toString(vl)), "path");
         setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getPath(), (et, vl) -> ((ThumbnailQueue) et).setPath(DfTypeUtil.toString(vl)), "path");
@@ -127,6 +129,8 @@ public class ThumbnailQueueDbm extends AbstractDBMeta {
             false, "String", 0, 0, null, false, null, null, null, null, null, false);
             false, "String", 0, 0, null, false, null, null, null, null, null, false);
     protected final ColumnInfo _columnCreatedTime = cci("createdTime", "createdTime", null, null, Long.class, "createdTime", null, false,
     protected final ColumnInfo _columnCreatedTime = cci("createdTime", "createdTime", null, null, Long.class, "createdTime", null, false,
             false, false, "Long", 0, 0, null, false, null, null, null, null, null, false);
             false, false, "Long", 0, 0, null, false, null, null, null, null, null, false);
+    protected final ColumnInfo _columnTarget = cci("target", "target", null, null, String.class, "target", null, false, false, false,
+            "String", 0, 0, null, false, null, null, null, null, null, false);
     protected final ColumnInfo _columnGenerator = cci("generator", "generator", null, null, String.class, "generator", null, false, false,
     protected final ColumnInfo _columnGenerator = cci("generator", "generator", null, null, String.class, "generator", null, false, false,
             false, "String", 0, 0, null, false, null, null, null, null, null, false);
             false, "String", 0, 0, null, false, null, null, null, null, null, false);
     protected final ColumnInfo _columnPath = cci("path", "path", null, null, String.class, "path", null, false, false, false, "String", 0,
     protected final ColumnInfo _columnPath = cci("path", "path", null, null, String.class, "path", null, false, false, false, "String", 0,
@@ -142,6 +146,10 @@ public class ThumbnailQueueDbm extends AbstractDBMeta {
         return _columnCreatedTime;
         return _columnCreatedTime;
     }
     }
 
 
+    public ColumnInfo columnTarget() {
+        return _columnTarget;
+    }
+
     public ColumnInfo columnGenerator() {
     public ColumnInfo columnGenerator() {
         return _columnGenerator;
         return _columnGenerator;
     }
     }
@@ -158,6 +166,7 @@ public class ThumbnailQueueDbm extends AbstractDBMeta {
         List<ColumnInfo> ls = newArrayList();
         List<ColumnInfo> ls = newArrayList();
         ls.add(columnCreatedBy());
         ls.add(columnCreatedBy());
         ls.add(columnCreatedTime());
         ls.add(columnCreatedTime());
+        ls.add(columnTarget());
         ls.add(columnGenerator());
         ls.add(columnGenerator());
         ls.add(columnPath());
         ls.add(columnPath());
         ls.add(columnUrl());
         ls.add(columnUrl());

+ 4 - 0
src/main/java/org/codelibs/fess/es/config/cbean/bs/BsThumbnailQueueCB.java

@@ -155,6 +155,10 @@ public class BsThumbnailQueueCB extends EsAbstractConditionBean {
             doColumn("createdTime");
             doColumn("createdTime");
         }
         }
 
 
+        public void columnTarget() {
+            doColumn("target");
+        }
+
         public void columnGenerator() {
         public void columnGenerator() {
             doColumn("generator");
             doColumn("generator");
         }
         }

+ 207 - 0
src/main/java/org/codelibs/fess/es/config/cbean/cq/bs/BsThumbnailQueueCQ.java

@@ -543,6 +543,213 @@ public abstract class BsThumbnailQueueCQ extends EsAbstractConditionQuery {
         return this;
         return this;
     }
     }
 
 
+    public void setTarget_Equal(String target) {
+        setTarget_Term(target, null);
+    }
+
+    public void setTarget_Equal(String target, ConditionOptionCall<TermQueryBuilder> opLambda) {
+        setTarget_Term(target, opLambda);
+    }
+
+    public void setTarget_Term(String target) {
+        setTarget_Term(target, null);
+    }
+
+    public void setTarget_Term(String target, ConditionOptionCall<TermQueryBuilder> opLambda) {
+        TermQueryBuilder builder = regTermQ("target", target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_NotEqual(String target) {
+        setTarget_NotTerm(target, null);
+    }
+
+    public void setTarget_NotTerm(String target) {
+        setTarget_NotTerm(target, null);
+    }
+
+    public void setTarget_NotEqual(String target, ConditionOptionCall<BoolQueryBuilder> opLambda) {
+        setTarget_NotTerm(target, opLambda);
+    }
+
+    public void setTarget_NotTerm(String target, ConditionOptionCall<BoolQueryBuilder> opLambda) {
+        not(not -> not.setTarget_Term(target), opLambda);
+    }
+
+    public void setTarget_Terms(Collection<String> targetList) {
+        setTarget_Terms(targetList, null);
+    }
+
+    public void setTarget_Terms(Collection<String> targetList, ConditionOptionCall<TermsQueryBuilder> opLambda) {
+        TermsQueryBuilder builder = regTermsQ("target", targetList);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_InScope(Collection<String> targetList) {
+        setTarget_Terms(targetList, null);
+    }
+
+    public void setTarget_InScope(Collection<String> targetList, ConditionOptionCall<TermsQueryBuilder> opLambda) {
+        setTarget_Terms(targetList, opLambda);
+    }
+
+    public void setTarget_Match(String target) {
+        setTarget_Match(target, null);
+    }
+
+    public void setTarget_Match(String target, ConditionOptionCall<MatchQueryBuilder> opLambda) {
+        MatchQueryBuilder builder = regMatchQ("target", target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_MatchPhrase(String target) {
+        setTarget_MatchPhrase(target, null);
+    }
+
+    public void setTarget_MatchPhrase(String target, ConditionOptionCall<MatchQueryBuilder> opLambda) {
+        MatchQueryBuilder builder = regMatchPhraseQ("target", target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_MatchPhrasePrefix(String target) {
+        setTarget_MatchPhrasePrefix(target, null);
+    }
+
+    public void setTarget_MatchPhrasePrefix(String target, ConditionOptionCall<MatchQueryBuilder> opLambda) {
+        MatchQueryBuilder builder = regMatchPhrasePrefixQ("target", target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_Fuzzy(String target) {
+        setTarget_Fuzzy(target, null);
+    }
+
+    public void setTarget_Fuzzy(String target, ConditionOptionCall<FuzzyQueryBuilder> opLambda) {
+        FuzzyQueryBuilder builder = regFuzzyQ("target", target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_Prefix(String target) {
+        setTarget_Prefix(target, null);
+    }
+
+    public void setTarget_Prefix(String target, ConditionOptionCall<PrefixQueryBuilder> opLambda) {
+        PrefixQueryBuilder builder = regPrefixQ("target", target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_Wildcard(String target) {
+        setTarget_Wildcard(target, null);
+    }
+
+    public void setTarget_Wildcard(String target, ConditionOptionCall<WildcardQueryBuilder> opLambda) {
+        WildcardQueryBuilder builder = regWildcardQ("target", target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_Regexp(String target) {
+        setTarget_Regexp(target, null);
+    }
+
+    public void setTarget_Regexp(String target, ConditionOptionCall<RegexpQueryBuilder> opLambda) {
+        RegexpQueryBuilder builder = regRegexpQ("target", target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_GreaterThan(String target) {
+        setTarget_GreaterThan(target, null);
+    }
+
+    public void setTarget_GreaterThan(String target, ConditionOptionCall<RangeQueryBuilder> opLambda) {
+        RangeQueryBuilder builder = regRangeQ("target", ConditionKey.CK_GREATER_THAN, target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_LessThan(String target) {
+        setTarget_LessThan(target, null);
+    }
+
+    public void setTarget_LessThan(String target, ConditionOptionCall<RangeQueryBuilder> opLambda) {
+        RangeQueryBuilder builder = regRangeQ("target", ConditionKey.CK_LESS_THAN, target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_GreaterEqual(String target) {
+        setTarget_GreaterEqual(target, null);
+    }
+
+    public void setTarget_GreaterEqual(String target, ConditionOptionCall<RangeQueryBuilder> opLambda) {
+        RangeQueryBuilder builder = regRangeQ("target", ConditionKey.CK_GREATER_EQUAL, target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_LessEqual(String target) {
+        setTarget_LessEqual(target, null);
+    }
+
+    public void setTarget_LessEqual(String target, ConditionOptionCall<RangeQueryBuilder> opLambda) {
+        RangeQueryBuilder builder = regRangeQ("target", ConditionKey.CK_LESS_EQUAL, target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_Exists() {
+        setTarget_Exists(null);
+    }
+
+    public void setTarget_Exists(ConditionOptionCall<ExistsQueryBuilder> opLambda) {
+        ExistsQueryBuilder builder = regExistsQ("target");
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setTarget_CommonTerms(String target) {
+        setTarget_CommonTerms(target, null);
+    }
+
+    public void setTarget_CommonTerms(String target, ConditionOptionCall<CommonTermsQueryBuilder> opLambda) {
+        CommonTermsQueryBuilder builder = regCommonTermsQ("target", target);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public BsThumbnailQueueCQ addOrderBy_Target_Asc() {
+        regOBA("target");
+        return this;
+    }
+
+    public BsThumbnailQueueCQ addOrderBy_Target_Desc() {
+        regOBD("target");
+        return this;
+    }
+
     public void setGenerator_Equal(String generator) {
     public void setGenerator_Equal(String generator) {
         setGenerator_Term(generator, null);
         setGenerator_Term(generator, null);
     }
     }

+ 1 - 1
src/main/java/org/codelibs/fess/es/config/exentity/AccessToken.java

@@ -50,7 +50,7 @@ public class AccessToken extends BsAccessToken {
         return new Date(getExpiredTime().longValue());
         return new Date(getExpiredTime().longValue());
     }
     }
 
 
-    public void setExpires(Date date) {
+    public void setExpires(final Date date) {
         setExpiredTime(date != null ? date.getTime() : null);
         setExpiredTime(date != null ? date.getTime() : null);
     }
     }
 
 

+ 14 - 4
src/main/java/org/codelibs/fess/es/config/exentity/CrawlingConfigWrapper.java

@@ -21,49 +21,59 @@ import org.codelibs.fess.crawler.client.CrawlerClientFactory;
 
 
 public class CrawlingConfigWrapper implements CrawlingConfig {
 public class CrawlingConfigWrapper implements CrawlingConfig {
 
 
-    private CrawlingConfig crawlingConfig;
+    private final CrawlingConfig crawlingConfig;
 
 
     public CrawlingConfigWrapper(final CrawlingConfig crawlingConfig) {
     public CrawlingConfigWrapper(final CrawlingConfig crawlingConfig) {
         this.crawlingConfig = crawlingConfig;
         this.crawlingConfig = crawlingConfig;
     }
     }
 
 
+    @Override
     public String getId() {
     public String getId() {
         return crawlingConfig.getId();
         return crawlingConfig.getId();
     }
     }
 
 
+    @Override
     public String getName() {
     public String getName() {
         return crawlingConfig.getName();
         return crawlingConfig.getName();
     }
     }
 
 
+    @Override
     public String[] getPermissions() {
     public String[] getPermissions() {
         return crawlingConfig.getPermissions();
         return crawlingConfig.getPermissions();
     }
     }
 
 
+    @Override
     public String[] getLabelTypeValues() {
     public String[] getLabelTypeValues() {
         return crawlingConfig.getLabelTypeValues();
         return crawlingConfig.getLabelTypeValues();
     }
     }
 
 
+    @Override
     public String getDocumentBoost() {
     public String getDocumentBoost() {
         return crawlingConfig.getDocumentBoost();
         return crawlingConfig.getDocumentBoost();
     }
     }
 
 
-    public String getIndexingTarget(String input) {
+    @Override
+    public String getIndexingTarget(final String input) {
         return crawlingConfig.getIndexingTarget(input);
         return crawlingConfig.getIndexingTarget(input);
     }
     }
 
 
+    @Override
     public String getConfigId() {
     public String getConfigId() {
         return crawlingConfig.getConfigId();
         return crawlingConfig.getConfigId();
     }
     }
 
 
+    @Override
     public Integer getTimeToLive() {
     public Integer getTimeToLive() {
         return crawlingConfig.getTimeToLive();
         return crawlingConfig.getTimeToLive();
     }
     }
 
 
-    public Map<String, Object> initializeClientFactory(CrawlerClientFactory crawlerClientFactory) {
+    @Override
+    public Map<String, Object> initializeClientFactory(final CrawlerClientFactory crawlerClientFactory) {
         return crawlingConfig.initializeClientFactory(crawlerClientFactory);
         return crawlingConfig.initializeClientFactory(crawlerClientFactory);
     }
     }
 
 
-    public Map<String, String> getConfigParameterMap(ConfigName name) {
+    @Override
+    public Map<String, String> getConfigParameterMap(final ConfigName name) {
         return crawlingConfig.getConfigParameterMap(name);
         return crawlingConfig.getConfigParameterMap(name);
     }
     }
 }
 }

+ 2 - 1
src/main/java/org/codelibs/fess/helper/SystemHelper.java

@@ -299,6 +299,7 @@ public class SystemHelper {
     }
     }
 
 
     public void reloadConfiguration() {
     public void reloadConfiguration() {
+        ComponentUtil.getFessEsClient().refresh();
         ComponentUtil.getLabelTypeHelper().init();
         ComponentUtil.getLabelTypeHelper().init();
         ComponentUtil.getPathMappingHelper().init();
         ComponentUtil.getPathMappingHelper().init();
         ComponentUtil.getSuggestHelper().init();
         ComponentUtil.getSuggestHelper().init();
@@ -316,7 +317,7 @@ public class SystemHelper {
         this.random = random;
         this.random = random;
     }
     }
 
 
-    public boolean isChangedClusterState(int status) {
+    public boolean isChangedClusterState(final int status) {
         return previousClusterState.getAndSet(status) != status;
         return previousClusterState.getAndSet(status) != status;
     }
     }
 
 

+ 14 - 0
src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java

@@ -652,6 +652,9 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g. true */
     /** The key of the configuration. e.g. true */
     String THUMBNAIL_HTML_PHANTOMJS_ENABLED = "thumbnail.html.phantomjs.enabled";
     String THUMBNAIL_HTML_PHANTOMJS_ENABLED = "thumbnail.html.phantomjs.enabled";
 
 
+    /** The key of the configuration. e.g. all */
+    String THUMBNAIL_GENERATOR_TARGETS = "thumbnail.generator.targets";
+
     /** The key of the configuration. e.g. Administrator */
     /** The key of the configuration. e.g. Administrator */
     String MAIL_FROM_NAME = "mail.from.name";
     String MAIL_FROM_NAME = "mail.from.name";
 
 
@@ -3163,6 +3166,13 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
      */
      */
     boolean isThumbnailHtmlPhantomjsEnabled();
     boolean isThumbnailHtmlPhantomjsEnabled();
 
 
+    /**
+     * Get the value for the key 'thumbnail.generator.targets'. <br>
+     * The value is, e.g. all <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getThumbnailGeneratorTargets();
+
     /**
     /**
      * Get the value for the key 'mail.from.name'. <br>
      * Get the value for the key 'mail.from.name'. <br>
      * The value is, e.g. Administrator <br>
      * The value is, e.g. Administrator <br>
@@ -5398,6 +5408,10 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             return is(FessConfig.THUMBNAIL_HTML_PHANTOMJS_ENABLED);
             return is(FessConfig.THUMBNAIL_HTML_PHANTOMJS_ENABLED);
         }
         }
 
 
+        public String getThumbnailGeneratorTargets() {
+            return get(FessConfig.THUMBNAIL_GENERATOR_TARGETS);
+        }
+
         public String getMailFromName() {
         public String getMailFromName() {
             return get(FessConfig.MAIL_FROM_NAME);
             return get(FessConfig.MAIL_FROM_NAME);
         }
         }

+ 8 - 0
src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java

@@ -1438,4 +1438,12 @@ public interface FessProp {
                 stream -> stream.filter(StringUtil::isNotBlank).map(s -> s.trim()).forEach(list::add));
                 stream -> stream.filter(StringUtil::isNotBlank).map(s -> s.trim()).forEach(list::add));
         return list.toArray(new String[list.size()]);
         return list.toArray(new String[list.size()]);
     }
     }
+
+    String getThumbnailGeneratorTargets();
+
+    public default String[] getThumbnailGeneratorTargetsAsArray() {
+        return getThumbnailGeneratorTargets().split(",");
+
+    }
+
 }
 }

+ 27 - 11
src/main/java/org/codelibs/fess/thumbnail/ThumbnailManager.java

@@ -29,7 +29,6 @@ import java.util.Map;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.annotation.PreDestroy;
@@ -45,6 +44,7 @@ import org.codelibs.fess.es.config.exbhv.ThumbnailQueueBhv;
 import org.codelibs.fess.es.config.exentity.ThumbnailQueue;
 import org.codelibs.fess.es.config.exentity.ThumbnailQueue;
 import org.codelibs.fess.exception.FessSystemException;
 import org.codelibs.fess.exception.FessSystemException;
 import org.codelibs.fess.exception.JobProcessingException;
 import org.codelibs.fess.exception.JobProcessingException;
+import org.codelibs.fess.helper.SystemHelper;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.DocumentUtil;
 import org.codelibs.fess.util.DocumentUtil;
@@ -52,6 +52,8 @@ import org.lastaflute.web.util.LaRequestUtil;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 
 
+import com.google.common.collect.Lists;
+
 public class ThumbnailManager {
 public class ThumbnailManager {
     private static final String DEFAULT_SCREENSHOT_DIR = "/WEB-INF/thumbnails";
     private static final String DEFAULT_SCREENSHOT_DIR = "/WEB-INF/thumbnails";
 
 
@@ -116,12 +118,12 @@ public class ThumbnailManager {
             final List<Tuple3<String, String, String>> taskList = new ArrayList<>();
             final List<Tuple3<String, String, String>> taskList = new ArrayList<>();
             while (generating) {
             while (generating) {
                 try {
                 try {
-                    Tuple3<String, String, String> task = thumbnailTaskQueue.poll(thumbnailTaskQueueTimeout, TimeUnit.MILLISECONDS);
+                    final Tuple3<String, String, String> task = thumbnailTaskQueue.poll(thumbnailTaskQueueTimeout, TimeUnit.MILLISECONDS);
                     if (task == null) {
                     if (task == null) {
                         if (!taskList.isEmpty()) {
                         if (!taskList.isEmpty()) {
                             storeQueue(taskList);
                             storeQueue(taskList);
                         }
                         }
-                    } else {
+                    } else if (!taskList.contains(task)) {
                         taskList.add(task);
                         taskList.add(task);
                         if (taskList.size() > thumbnailTaskBulkSize) {
                         if (taskList.size() > thumbnailTaskBulkSize) {
                             storeQueue(taskList);
                             storeQueue(taskList);
@@ -158,13 +160,22 @@ public class ThumbnailManager {
     }
     }
 
 
     protected void storeQueue(final List<Tuple3<String, String, String>> taskList) {
     protected void storeQueue(final List<Tuple3<String, String, String>> taskList) {
-        List<ThumbnailQueue> list = taskList.stream().filter(entity -> entity != null).map(task -> {
-            ThumbnailQueue entity = new ThumbnailQueue();
-            entity.setGenerator(task.getValue1());
-            entity.setUrl(task.getValue2());
-            entity.setPath(task.getValue3());
-            return entity;
-        }).collect(Collectors.toList());
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
+        final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
+        final String[] targets = fessConfig.getThumbnailGeneratorTargetsAsArray();
+        final List<ThumbnailQueue> list = new ArrayList<>();
+        taskList.stream().filter(entity -> entity != null).forEach(task -> {
+            for (final String target : targets) {
+                final ThumbnailQueue entity = new ThumbnailQueue();
+                entity.setGenerator(task.getValue1());
+                entity.setUrl(task.getValue2());
+                entity.setPath(task.getValue3());
+                entity.setTarget(target);
+                entity.setCreatedBy(Constants.SYSTEM_USER);
+                entity.setCreatedTime(systemHelper.getCurrentTimeAsLong());
+                list.add(entity);
+            }
+        });
         taskList.clear();
         taskList.clear();
         final ThumbnailQueueBhv thumbnailQueueBhv = ComponentUtil.getComponent(ThumbnailQueueBhv.class);
         final ThumbnailQueueBhv thumbnailQueueBhv = ComponentUtil.getComponent(ThumbnailQueueBhv.class);
         thumbnailQueueBhv.batchInsert(list);
         thumbnailQueueBhv.batchInsert(list);
@@ -175,6 +186,11 @@ public class ThumbnailManager {
         final List<String> idList = new ArrayList<>();
         final List<String> idList = new ArrayList<>();
         final ThumbnailQueueBhv thumbnailQueueBhv = ComponentUtil.getComponent(ThumbnailQueueBhv.class);
         final ThumbnailQueueBhv thumbnailQueueBhv = ComponentUtil.getComponent(ThumbnailQueueBhv.class);
         thumbnailQueueBhv.selectList(cb -> {
         thumbnailQueueBhv.selectList(cb -> {
+            if (StringUtil.isBlank(fessConfig.getSchedulerTargetName())) {
+                cb.query().setTarget_Equal(Constants.DEFAULT_JOB_TARGET);
+            } else {
+                cb.query().setTarget_InScope(Lists.newArrayList(Constants.DEFAULT_JOB_TARGET, fessConfig.getSchedulerTargetName()));
+            }
             cb.query().addOrderBy_CreatedTime_Asc();
             cb.query().addOrderBy_CreatedTime_Asc();
             cb.fetchFirst(fessConfig.getPageThumbnailQueueMaxFetchSizeAsInteger());
             cb.fetchFirst(fessConfig.getPageThumbnailQueueMaxFetchSizeAsInteger());
         }).forEach(entity -> {
         }).forEach(entity -> {
@@ -213,7 +229,7 @@ public class ThumbnailManager {
             if (generator.isTarget(docMap)) {
             if (generator.isTarget(docMap)) {
                 final String url = DocumentUtil.getValue(docMap, fessConfig.getIndexFieldUrl(), String.class);
                 final String url = DocumentUtil.getValue(docMap, fessConfig.getIndexFieldUrl(), String.class);
                 final String path = getImageFilename(docMap);
                 final String path = getImageFilename(docMap);
-                Tuple3<String, String, String> task = new Tuple3<String, String, String>(generator.getName(), url, path);
+                final Tuple3<String, String, String> task = new Tuple3<>(generator.getName(), url, path);
                 thumbnailTaskQueue.offer(task);
                 thumbnailTaskQueue.offer(task);
                 break;
                 break;
             }
             }

+ 2 - 1
src/main/java/org/codelibs/fess/thumbnail/impl/BaseThumbnailGenerator.java

@@ -105,11 +105,12 @@ public abstract class BaseThumbnailGenerator implements ThumbnailGenerator {
         this.generatorList = generatorList;
         this.generatorList = generatorList;
     }
     }
 
 
+    @Override
     public String getName() {
     public String getName() {
         return name;
         return name;
     }
     }
 
 
-    public void setName(String name) {
+    public void setName(final String name) {
         this.name = name;
         this.name = name;
     }
     }
 
 

+ 2 - 2
src/main/java/org/codelibs/fess/thumbnail/impl/WebDriverGenerator.java

@@ -139,7 +139,7 @@ public class WebDriverGenerator extends BaseThumbnailGenerator {
                     final File thumbnail = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
                     final File thumbnail = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
                     convert(thumbnail, outputFile);
                     convert(thumbnail, outputFile);
                     return true;
                     return true;
-                } catch (UnreachableBrowserException e) {
+                } catch (final UnreachableBrowserException e) {
                     if (logger.isDebugEnabled()) {
                     if (logger.isDebugEnabled()) {
                         logger.debug("WebDriver is not available.", e);
                         logger.debug("WebDriver is not available.", e);
                     }
                     }
@@ -265,7 +265,7 @@ public class WebDriverGenerator extends BaseThumbnailGenerator {
         this.thumbnailHeight = thumbnailHeight;
         this.thumbnailHeight = thumbnailHeight;
     }
     }
 
 
-    public void setUnreachableCheckInterval(long unreachableCheckInterval) {
+    public void setUnreachableCheckInterval(final long unreachableCheckInterval) {
         this.unreachableCheckInterval = unreachableCheckInterval;
         this.unreachableCheckInterval = unreachableCheckInterval;
     }
     }
 }
 }

+ 1 - 0
src/main/resources/fess_config.properties

@@ -349,6 +349,7 @@ paging.search.page.size=20
 paging.search.page.max.size=100
 paging.search.page.max.size=100
 
 
 thumbnail.html.phantomjs.enabled=true
 thumbnail.html.phantomjs.enabled=true
+thumbnail.generator.targets=all
 
 
 # ----------------------------------------------------------
 # ----------------------------------------------------------
 #                                                       Mail
 #                                                       Mail

+ 4 - 0
src/main/resources/fess_indices/.fess_config/thumbnail_queue.json

@@ -19,6 +19,10 @@
         "type": "string",
         "type": "string",
         "index": "not_analyzed"
         "index": "not_analyzed"
       },
       },
+      "target": {
+        "type": "string",
+        "index": "not_analyzed"
+      },
       "createdTime": {
       "createdTime": {
         "type": "long"
         "type": "long"
       },
       },

+ 1 - 1
src/main/webapp/WEB-INF/view/admin/accesstoken/admin_accesstoken.jsp

@@ -10,7 +10,7 @@
 	<div class="wrapper">
 	<div class="wrapper">
 		<jsp:include page="/WEB-INF/view/common/admin/header.jsp"></jsp:include>
 		<jsp:include page="/WEB-INF/view/common/admin/header.jsp"></jsp:include>
 		<jsp:include page="/WEB-INF/view/common/admin/sidebar.jsp">
 		<jsp:include page="/WEB-INF/view/common/admin/sidebar.jsp">
-			<jsp:param name="menuCategoryType" value="crawl" />
+			<jsp:param name="menuCategoryType" value="system" />
 			<jsp:param name="menuType" value="accessToken" />
 			<jsp:param name="menuType" value="accessToken" />
 		</jsp:include>
 		</jsp:include>
 		<div class="content-wrapper">
 		<div class="content-wrapper">

+ 1 - 1
src/main/webapp/WEB-INF/view/admin/accesstoken/admin_accesstoken_details.jsp

@@ -10,7 +10,7 @@
 	<div class="wrapper">
 	<div class="wrapper">
 		<jsp:include page="/WEB-INF/view/common/admin/header.jsp"></jsp:include>
 		<jsp:include page="/WEB-INF/view/common/admin/header.jsp"></jsp:include>
 		<jsp:include page="/WEB-INF/view/common/admin/sidebar.jsp">
 		<jsp:include page="/WEB-INF/view/common/admin/sidebar.jsp">
-			<jsp:param name="menuCategoryType" value="crawl" />
+			<jsp:param name="menuCategoryType" value="system" />
 			<jsp:param name="menuType" value="accessToken" />
 			<jsp:param name="menuType" value="accessToken" />
 		</jsp:include>
 		</jsp:include>
 		<div class="content-wrapper">
 		<div class="content-wrapper">

+ 1 - 1
src/main/webapp/WEB-INF/view/admin/accesstoken/admin_accesstoken_edit.jsp

@@ -10,7 +10,7 @@
 	<div class="wrapper">
 	<div class="wrapper">
 		<jsp:include page="/WEB-INF/view/common/admin/header.jsp"></jsp:include>
 		<jsp:include page="/WEB-INF/view/common/admin/header.jsp"></jsp:include>
 		<jsp:include page="/WEB-INF/view/common/admin/sidebar.jsp">
 		<jsp:include page="/WEB-INF/view/common/admin/sidebar.jsp">
-			<jsp:param name="menuCategoryType" value="crawl" />
+			<jsp:param name="menuCategoryType" value="system" />
 			<jsp:param name="menuType" value="accessToken" />
 			<jsp:param name="menuType" value="accessToken" />
 		</jsp:include>
 		</jsp:include>
 		<div class="content-wrapper">
 		<div class="content-wrapper">