Browse Source

fix #2236 generateId is mt-safe

Shinsuke Sugaya 5 years ago
parent
commit
8a44c88af9

+ 3 - 4
src/main/java/org/codelibs/fess/helper/CrawlingInfoHelper.java

@@ -25,6 +25,7 @@ import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 
 import org.codelibs.core.lang.StringUtil;
 import org.codelibs.core.lang.StringUtil;
 import org.codelibs.core.security.MessageDigestUtil;
 import org.codelibs.core.security.MessageDigestUtil;
@@ -162,17 +163,15 @@ public class CrawlingInfoHelper {
         final List<String> roleTypeList = (List<String>) dataMap.get(fessConfig.getIndexFieldRole());
         final List<String> roleTypeList = (List<String>) dataMap.get(fessConfig.getIndexFieldRole());
         buf.append(url);
         buf.append(url);
         if (roleTypeList != null && !roleTypeList.isEmpty()) {
         if (roleTypeList != null && !roleTypeList.isEmpty()) {
-            Collections.sort(roleTypeList);
             buf.append(";r=");
             buf.append(";r=");
-            buf.append(String.join(",", roleTypeList));
+            buf.append(roleTypeList.stream().sorted().collect(Collectors.joining(",")));
         }
         }
 
 
         @SuppressWarnings("unchecked")
         @SuppressWarnings("unchecked")
         final List<String> virtualHostList = (List<String>) dataMap.get(fessConfig.getIndexFieldVirtualHost());
         final List<String> virtualHostList = (List<String>) dataMap.get(fessConfig.getIndexFieldVirtualHost());
         if (virtualHostList != null && !virtualHostList.isEmpty()) {
         if (virtualHostList != null && !virtualHostList.isEmpty()) {
-            Collections.sort(virtualHostList);
             buf.append(";v=");
             buf.append(";v=");
-            buf.append(String.join(",", virtualHostList));
+            buf.append(virtualHostList.stream().sorted().collect(Collectors.joining(",")));
         }
         }
 
 
         final String urlId = buf.toString().trim();
         final String urlId = buf.toString().trim();

+ 29 - 0
src/test/java/org/codelibs/fess/helper/CrawlingInfoHelperTest.java

@@ -19,6 +19,9 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.codelibs.fess.unit.UnitFessTestCase;
 import org.codelibs.fess.unit.UnitFessTestCase;
@@ -144,4 +147,30 @@ public class CrawlingInfoHelperTest extends UnitFessTestCase {
                 "6be41c30a9e5e7724f87134cecc6e5aa6fe771773b8845867ce41b1a6d46d50b25f504259c8e9a6657f6ada8865d06ab3bcee5abd306cdd1f43d60c451b34eb6",
                 "6be41c30a9e5e7724f87134cecc6e5aa6fe771773b8845867ce41b1a6d46d50b25f504259c8e9a6657f6ada8865d06ab3bcee5abd306cdd1f43d60c451b34eb6",
                 crawlingInfoHelper.generateId(buf.substring(0, 520)));
                 crawlingInfoHelper.generateId(buf.substring(0, 520)));
     }
     }
+
+    public void test_generateId_multithread() throws Exception {
+        final Map<String, Object> dataMap = new HashMap<String, Object>();
+        dataMap.put("url", "http://example.com/");
+        final List<String> list = new ArrayList<>();
+        for (int i = 100; i > 0; i--) {
+            list.add(String.valueOf(i));
+        }
+        dataMap.put("role", list);
+        dataMap.put("virtual_host", list);
+        final String result =
+                "f8240bbae62b99960056c3a382844836c547c2ec73e019491bb7bbb02d92d98e876c8204b67a59ca8123b82d20986516b7d451f68dd634b39004c0d36c0eeca4";
+        assertEquals(result, crawlingInfoHelper.generateId(dataMap));
+
+        final AtomicInteger counter = new AtomicInteger(0);
+        final ForkJoinPool pool = new ForkJoinPool(10);
+        for (int i = 0; i < 1000; i++) {
+            pool.execute(() -> {
+                assertEquals(result, crawlingInfoHelper.generateId(dataMap));
+                counter.incrementAndGet();
+            });
+        }
+        pool.shutdown();
+        pool.awaitTermination(10, TimeUnit.SECONDS);
+        assertEquals(1000, counter.get());
+    }
 }
 }