diff --git a/shield/src/main/java/org/elasticsearch/shield/authz/Permission.java b/shield/src/main/java/org/elasticsearch/shield/authz/Permission.java index 37455750d0d..5d9a8d4f87c 100644 --- a/shield/src/main/java/org/elasticsearch/shield/authz/Permission.java +++ b/shield/src/main/java/org/elasticsearch/shield/authz/Permission.java @@ -5,9 +5,6 @@ */ package org.elasticsearch.shield.authz; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterators; @@ -31,6 +28,8 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; import java.util.function.Predicate; /** @@ -303,24 +302,23 @@ public interface Permission { } }; - private final LoadingCache> allowedIndicesMatchersForAction = CacheBuilder.newBuilder() - .build(new CacheLoader>() { - @Override - public Predicate load(String action) throws Exception { - List indices = new ArrayList<>(); - for (Group group : groups) { - if (group.actionMatcher.test(action)) { - indices.addAll(Arrays.asList(group.indices)); - } - } - return new AutomatonPredicate(Automatons.patterns(Collections.unmodifiableList(indices))); - } - }); + private final Function> loadingFunction; + + private final ConcurrentHashMap> allowedIndicesMatchersForAction = new ConcurrentHashMap<>(); private final Group[] groups; public Core(Group... groups) { this.groups = groups; + loadingFunction = (action) -> { + List indices = new ArrayList<>(); + for (Group group : groups) { + if (group.actionMatcher.test(action)) { + indices.addAll(Arrays.asList(group.indices)); + } + } + return new AutomatonPredicate(Automatons.patterns(Collections.unmodifiableList(indices))); + }; } @Override @@ -342,7 +340,7 @@ public interface Permission { * has the privilege for executing the given action on. */ public Predicate allowedIndicesMatcher(String action) { - return allowedIndicesMatchersForAction.getUnchecked(action); + return allowedIndicesMatchersForAction.computeIfAbsent(action, loadingFunction); } @Override diff --git a/shield/src/main/java/org/elasticsearch/shield/authz/Privilege.java b/shield/src/main/java/org/elasticsearch/shield/authz/Privilege.java index e7e3144c3d9..99bb76f6c94 100644 --- a/shield/src/main/java/org/elasticsearch/shield/authz/Privilege.java +++ b/shield/src/main/java/org/elasticsearch/shield/authz/Privilege.java @@ -5,9 +5,6 @@ */ package org.elasticsearch.shield.authz; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.UncheckedExecutionException; import dk.brics.automaton.Automaton; @@ -26,6 +23,7 @@ import org.elasticsearch.shield.support.Automatons; import java.util.Locale; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; import java.util.function.Predicate; @@ -180,17 +178,7 @@ public abstract class Privilege

> { return values; } - private static final LoadingCache cache = CacheBuilder.newBuilder().build( - new CacheLoader() { - @Override - public Index load(Name name) throws Exception { - Index index = NONE; - for (String part : name.parts) { - index = index == NONE ? resolve(part) : index.plus(resolve(part)); - } - return index; - } - }); + private static final ConcurrentHashMap cache = new ConcurrentHashMap<>(); private Index(String name, String... patterns) { super(name, patterns); @@ -235,11 +223,13 @@ public abstract class Privilege

> { } public static Index get(Name name) { - try { - return cache.getUnchecked(name); - } catch (UncheckedExecutionException e) { - throw (RuntimeException) e.getCause(); - } + return cache.computeIfAbsent(name, (theName) -> { + Index index = NONE; + for (String part : theName.parts) { + index = index == NONE ? resolve(part) : index.plus(resolve(part)); + } + return index; + }); } public static Index union(Index... indices) { @@ -288,17 +278,8 @@ public abstract class Privilege

> { return values; } - private static final LoadingCache cache = CacheBuilder.newBuilder().build( - new CacheLoader() { - @Override - public Cluster load(Name name) throws Exception { - Cluster cluster = NONE; - for (String part : name.parts) { - cluster = cluster == NONE ? resolve(part) : cluster.plus(resolve(part)); - } - return cluster; - } - }); + private static final ConcurrentHashMap cache = new ConcurrentHashMap<>(); + private Cluster(String name, String... patterns) { super(name, patterns); @@ -341,11 +322,13 @@ public abstract class Privilege

> { } public static Cluster get(Name name) { - try { - return cache.getUnchecked(name); - } catch (UncheckedExecutionException e) { - throw (RuntimeException) e.getCause(); - } + return cache.computeIfAbsent(name, (theName) -> { + Cluster cluster = NONE; + for (String part : theName.parts) { + cluster = cluster == NONE ? resolve(part) : cluster.plus(resolve(part)); + } + return cluster; + }); } private static Cluster resolve(String name) { diff --git a/shield/src/main/java/org/elasticsearch/shield/ssl/AbstractSSLService.java b/shield/src/main/java/org/elasticsearch/shield/ssl/AbstractSSLService.java index 92fe59f5ff9..a6d3d4d5f0e 100644 --- a/shield/src/main/java/org/elasticsearch/shield/ssl/AbstractSSLService.java +++ b/shield/src/main/java/org/elasticsearch/shield/ssl/AbstractSSLService.java @@ -5,11 +5,7 @@ */ package org.elasticsearch.shield.ssl; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; import com.google.common.primitives.Ints; -import com.google.common.util.concurrent.UncheckedExecutionException; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.logging.ESLogger; @@ -30,6 +26,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import java.util.concurrent.ConcurrentHashMap; /** * This service houses the private key and trust managers needed for SSL/TLS negotiation. It is the central place to @@ -47,7 +44,8 @@ public abstract class AbstractSSLService extends AbstractComponent { static final int DEFAULT_SESSION_CACHE_SIZE = 1000; static final String DEFAULT_PROTOCOL = "TLSv1.2"; - protected final LoadingCache sslContexts = CacheBuilder.newBuilder().build(new SSLContextCacheLoader()); + private final ConcurrentHashMap sslContexts = new ConcurrentHashMap<>(); + private final SSLContextCacheLoader cacheLoader = new SSLContextCacheLoader(); protected Environment env; public AbstractSSLService(Settings settings, Environment environment) { @@ -91,16 +89,8 @@ public abstract class AbstractSSLService extends AbstractComponent { protected SSLContext sslContext(Settings settings) { SSLSettings sslSettings = sslSettings(settings); - try { - return sslContexts.getUnchecked(sslSettings); - } catch (UncheckedExecutionException e) { - // Unwrap ElasticsearchSSLException - if (e.getCause() instanceof ElasticsearchException) { - throw (ElasticsearchException) e.getCause(); - } else { - throw new ElasticsearchException("failed to load SSLContext", e); - } - } + return sslContexts.computeIfAbsent(sslSettings, (theSettings) -> + cacheLoader.load(theSettings)); } /** @@ -179,10 +169,9 @@ public abstract class AbstractSSLService extends AbstractComponent { return env.configFile().resolve(location); } - private class SSLContextCacheLoader extends CacheLoader { + private class SSLContextCacheLoader { - @Override - public SSLContext load(SSLSettings sslSettings) throws Exception { + public SSLContext load(SSLSettings sslSettings) { if (logger.isDebugEnabled()) { logger.debug("using keystore[{}], key_algorithm[{}], truststore[{}], truststore_algorithm[{}], tls_protocol[{}], session_cache_size[{}], session_cache_timeout[{}]", sslSettings.keyStorePath, sslSettings.keyStoreAlgorithm, sslSettings.trustStorePath, sslSettings.trustStoreAlgorithm, sslSettings.sslProtocol, sslSettings.sessionCacheSize, sslSettings.sessionCacheTimeout); diff --git a/shield/src/main/java/org/elasticsearch/shield/transport/ShieldServerTransportService.java b/shield/src/main/java/org/elasticsearch/shield/transport/ShieldServerTransportService.java index 6f37164bd68..5252e07a4cd 100644 --- a/shield/src/main/java/org/elasticsearch/shield/transport/ShieldServerTransportService.java +++ b/shield/src/main/java/org/elasticsearch/shield/transport/ShieldServerTransportService.java @@ -68,6 +68,12 @@ public class ShieldServerTransportService extends TransportService { super.registerRequestHandler(action, requestFactory, executor, wrappedHandler); } + @Override + public void registerRequestHandler(String action, Supplier request, String executor, boolean forceExecution, TransportRequestHandler handler) { + TransportRequestHandler wrappedHandler = new ProfileSecuredRequestHandler<>(action, handler, profileFilters); + super.registerRequestHandler(action, request, executor, forceExecution, wrappedHandler); + } + protected Map initializeProfileFilters() { if (!(transport instanceof ShieldNettyTransport)) { return Collections.singletonMap(NettyTransport.DEFAULT_PROFILE, new ServerTransportFilter.NodeProfile(authcService, authzService, actionMapper, false)); diff --git a/shield/src/test/java/org/elasticsearch/integration/SettingsFilterTests.java b/shield/src/test/java/org/elasticsearch/integration/SettingsFilterTests.java index 3584ce2ec64..cda16a7af6b 100644 --- a/shield/src/test/java/org/elasticsearch/integration/SettingsFilterTests.java +++ b/shield/src/test/java/org/elasticsearch/integration/SettingsFilterTests.java @@ -5,7 +5,6 @@ */ package org.elasticsearch.integration; -import com.google.common.base.Charsets; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.elasticsearch.common.settings.Settings; @@ -25,6 +24,7 @@ import org.junit.After; import org.junit.Test; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -158,7 +158,7 @@ public class SettingsFilterTests extends ShieldIntegTestCase { static List extractSettings(String data) throws Exception { List settingsList = new ArrayList<>(); - XContentParser parser = JsonXContent.jsonXContent.createParser(data.getBytes(Charsets.UTF_8)); + XContentParser parser = JsonXContent.jsonXContent.createParser(data.getBytes(StandardCharsets.UTF_8)); XContentParser.Token token = null; while ((token = parser.nextToken()) != null) { if (token == XContentParser.Token.FIELD_NAME && parser.currentName().equals("settings")) { diff --git a/shield/src/test/java/org/elasticsearch/shield/crypto/InternalCryptoServiceTests.java b/shield/src/test/java/org/elasticsearch/shield/crypto/InternalCryptoServiceTests.java index 054db859ff9..4f0f72dc76d 100644 --- a/shield/src/test/java/org/elasticsearch/shield/crypto/InternalCryptoServiceTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/crypto/InternalCryptoServiceTests.java @@ -5,7 +5,6 @@ */ package org.elasticsearch.shield.crypto; -import com.google.common.base.Charsets; import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; @@ -19,6 +18,7 @@ import org.junit.Test; import javax.crypto.SecretKey; import java.io.IOException; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; @@ -257,8 +257,8 @@ public class InternalCryptoServiceTests extends ESTestCase { assertThat(service.encrypted(new byte[0]), is(false)); assertThat(service.encrypted(new byte[InternalCryptoService.ENCRYPTED_BYTE_PREFIX.length]), is(false)); assertThat(service.encrypted(InternalCryptoService.ENCRYPTED_BYTE_PREFIX), is(true)); - assertThat(service.encrypted(randomAsciiOfLengthBetween(0, 100).getBytes(Charsets.UTF_8)), is(false)); - assertThat(service.encrypted(service.encrypt(randomAsciiOfLength(10).getBytes(Charsets.UTF_8))), is(true)); + assertThat(service.encrypted(randomAsciiOfLengthBetween(0, 100).getBytes(StandardCharsets.UTF_8)), is(false)); + assertThat(service.encrypted(service.encrypt(randomAsciiOfLength(10).getBytes(StandardCharsets.UTF_8))), is(true)); } @Test diff --git a/shield/src/test/java/org/elasticsearch/shield/support/ShieldFilesTests.java b/shield/src/test/java/org/elasticsearch/shield/support/ShieldFilesTests.java index 938704f79fa..d4900e4db4b 100644 --- a/shield/src/test/java/org/elasticsearch/shield/support/ShieldFilesTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/support/ShieldFilesTests.java @@ -5,7 +5,6 @@ */ package org.elasticsearch.shield.support; -import com.google.common.base.Charsets; import com.google.common.jimfs.Configuration; import com.google.common.jimfs.Jimfs; import org.elasticsearch.common.util.set.Sets; @@ -14,6 +13,7 @@ import org.elasticsearch.test.ESTestCase; import org.junit.Test; import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; @@ -36,7 +36,7 @@ public class ShieldFilesTests extends ESTestCase { boolean supportsPosixPermissions = Environment.getFileStore(path).supportsFileAttributeView(PosixFileAttributeView.class); assumeTrue("Ignoring because posix file attributes are not supported", supportsPosixPermissions); - Files.write(path, "foo".getBytes(Charsets.UTF_8)); + Files.write(path, "foo".getBytes(StandardCharsets.UTF_8)); Set perms = Sets.newHashSet(OWNER_READ, OWNER_WRITE); if (randomBoolean()) perms.add(OWNER_EXECUTE); @@ -59,8 +59,8 @@ public class ShieldFilesTests extends ESTestCase { try (FileSystem fs = Jimfs.newFileSystem(jimFsConfiguration)) { Path path = fs.getPath("foo"); Path tempPath = fs.getPath("bar"); - Files.write(path, "foo".getBytes(Charsets.UTF_8)); - Files.write(tempPath, "bar".getBytes(Charsets.UTF_8)); + Files.write(path, "foo".getBytes(StandardCharsets.UTF_8)); + Files.write(tempPath, "bar".getBytes(StandardCharsets.UTF_8)); PosixFileAttributeView view = Files.getFileAttributeView(path, PosixFileAttributeView.class); view.setGroup(fs.getUserPrincipalLookupService().lookupPrincipalByGroupName(randomAsciiOfLength(10))); diff --git a/shield/src/test/java/org/elasticsearch/shield/test/ShieldTestUtils.java b/shield/src/test/java/org/elasticsearch/shield/test/ShieldTestUtils.java index c811a4dca95..363132e0833 100644 --- a/shield/src/test/java/org/elasticsearch/shield/test/ShieldTestUtils.java +++ b/shield/src/test/java/org/elasticsearch/shield/test/ShieldTestUtils.java @@ -5,13 +5,13 @@ */ package org.elasticsearch.shield.test; -import com.google.common.base.Charsets; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.io.FileSystemUtils; import org.elasticsearch.common.io.Streams; import java.io.IOException; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -47,6 +47,6 @@ public class ShieldTestUtils { } public static String writeFile(Path folder, String name, String content) { - return writeFile(folder, name, content.getBytes(Charsets.UTF_8)); + return writeFile(folder, name, content.getBytes(StandardCharsets.UTF_8)); } } diff --git a/shield/src/test/java/org/elasticsearch/shield/transport/filter/IpFilteringIntegrationTests.java b/shield/src/test/java/org/elasticsearch/shield/transport/filter/IpFilteringIntegrationTests.java index 4b5d4f38cfa..e396aa77a1a 100644 --- a/shield/src/test/java/org/elasticsearch/shield/transport/filter/IpFilteringIntegrationTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/transport/filter/IpFilteringIntegrationTests.java @@ -5,7 +5,6 @@ */ package org.elasticsearch.shield.transport.filter; -import com.google.common.base.Charsets; import org.elasticsearch.client.Client; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; @@ -22,6 +21,7 @@ import java.io.OutputStream; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; +import java.nio.charset.StandardCharsets; import static org.elasticsearch.test.ESIntegTestCase.ClusterScope; import static org.elasticsearch.test.ESIntegTestCase.Scope; @@ -82,7 +82,7 @@ public class IpFilteringIntegrationTests extends ShieldIntegTestCase { assertThat(socket.isConnected(), is(true)); try (OutputStream os = socket.getOutputStream()) { - os.write("fooooo".getBytes(Charsets.UTF_8)); + os.write("fooooo".getBytes(StandardCharsets.UTF_8)); os.flush(); } } diff --git a/shield/src/test/java/org/elasticsearch/test/ShieldIntegTestCase.java b/shield/src/test/java/org/elasticsearch/test/ShieldIntegTestCase.java index e7c38a32283..1df9c56ea2a 100644 --- a/shield/src/test/java/org/elasticsearch/test/ShieldIntegTestCase.java +++ b/shield/src/test/java/org/elasticsearch/test/ShieldIntegTestCase.java @@ -5,22 +5,15 @@ */ package org.elasticsearch.test; -import com.carrotsearch.hppc.cursors.ObjectObjectCursor; -import com.google.common.base.Function; -import com.google.common.collect.Collections2; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus; import org.elasticsearch.action.admin.cluster.node.info.NodeInfo; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; import org.elasticsearch.client.Client; -import org.elasticsearch.cluster.ClusterService; -import org.elasticsearch.cluster.ClusterState; -import org.elasticsearch.cluster.metadata.IndexTemplateMetaData; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.PluginInfo; import org.elasticsearch.shield.ShieldPlugin; -import org.elasticsearch.shield.audit.index.IndexAuditTrail; import org.elasticsearch.shield.authc.support.SecuredString; import org.elasticsearch.test.ESIntegTestCase.SuppressLocalMode; import org.junit.AfterClass; @@ -33,6 +26,7 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.nio.file.Path; import java.util.*; +import java.util.stream.Collectors; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoTimeout; import static org.hamcrest.CoreMatchers.is; @@ -135,12 +129,7 @@ public abstract class ShieldIntegTestCase extends ESIntegTestCase { for (NodeInfo nodeInfo : nodeInfos) { // TODO: disable this assertion for now, because the test framework randomly runs with mock plugins. Maybe we should run without mock plugins? // assertThat(nodeInfo.getPlugins().getInfos(), hasSize(2)); - Collection pluginNames = Collections2.transform(nodeInfo.getPlugins().getInfos(), new Function() { - @Override - public String apply(PluginInfo pluginInfo) { - return pluginInfo.getName(); - } - }); + Collection pluginNames = nodeInfo.getPlugins().getInfos().stream().map(p -> p.getName()).collect(Collectors.toList()); assertThat("plugin [" + ShieldPlugin.NAME + "] not found in [" + pluginNames + "]", pluginNames.contains(ShieldPlugin.NAME), is(true)); assertThat("plugin [" + licensePluginName() + "] not found in [" + pluginNames + "]", pluginNames.contains(licensePluginName()), is(true)); } diff --git a/shield/src/test/resources/org/elasticsearch/transport/handlers b/shield/src/test/resources/org/elasticsearch/transport/handlers index ebf5177a0f0..26eac0ea059 100644 --- a/shield/src/test/resources/org/elasticsearch/transport/handlers +++ b/shield/src/test/resources/org/elasticsearch/transport/handlers @@ -67,7 +67,8 @@ internal:discovery/zen/fd/ping internal:discovery/zen/join internal:discovery/zen/join/validate internal:discovery/zen/leave -internal:discovery/zen/publish +internal:discovery/zen/publish/send +internal:discovery/zen/publish/commit internal:discovery/zen/rejoin internal:discovery/zen/unicast internal:gateway/local/allocate_dangled diff --git a/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/HtmlSanitizer.java b/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/HtmlSanitizer.java index b47eb1da7b4..86da94b2252 100644 --- a/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/HtmlSanitizer.java +++ b/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/HtmlSanitizer.java @@ -6,6 +6,7 @@ package org.elasticsearch.watcher.actions.email.service; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.owasp.html.CssSchema; @@ -38,6 +39,7 @@ public class HtmlSanitizer { }; private final boolean enabled; + @SuppressForbidden( reason = "PolicyFactory uses guava Function") private final PolicyFactory policy; @Inject @@ -55,6 +57,7 @@ public class HtmlSanitizer { return policy.sanitize(html); } + @SuppressForbidden( reason = "PolicyFactory uses guava Function") static PolicyFactory createCommonPolicy(String[] allow, String[] disallow) { HtmlPolicyBuilder policyBuilder = new HtmlPolicyBuilder(); diff --git a/watcher/src/test/java/org/elasticsearch/watcher/trigger/schedule/HourlyScheduleTests.java b/watcher/src/test/java/org/elasticsearch/watcher/trigger/schedule/HourlyScheduleTests.java index 1275698e84b..0c3bcaa5d36 100644 --- a/watcher/src/test/java/org/elasticsearch/watcher/trigger/schedule/HourlyScheduleTests.java +++ b/watcher/src/test/java/org/elasticsearch/watcher/trigger/schedule/HourlyScheduleTests.java @@ -5,7 +5,6 @@ */ package org.elasticsearch.watcher.trigger.schedule; -import com.google.common.collect.Collections2; import com.google.common.primitives.Ints; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.bytes.BytesReference; @@ -14,6 +13,8 @@ import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.junit.Test; +import java.util.stream.Collectors; + import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.hamcrest.Matchers.*; @@ -164,7 +165,7 @@ public class HourlyScheduleTests extends ScheduleTestCase { int[] minutes = validMinutes(); XContentBuilder builder = jsonBuilder() .startObject() - .field("minute", Collections2.transform(Ints.asList(minutes), Ints.stringConverter().reverse())) + .field("minute", Ints.asList(minutes).stream().map(p -> p.toString()).collect(Collectors.toList())) .endObject(); BytesReference bytes = builder.bytes(); XContentParser parser = JsonXContent.jsonXContent.createParser(bytes); @@ -182,7 +183,7 @@ public class HourlyScheduleTests extends ScheduleTestCase { int[] minutes = invalidMinutes(); XContentBuilder builder = jsonBuilder() .startObject() - .field("minute", Collections2.transform(Ints.asList(minutes), Ints.stringConverter().reverse())) + .field("minute", Ints.asList(minutes).stream().map(p -> p.toString()).collect(Collectors.toList())) .endObject(); BytesReference bytes = builder.bytes(); XContentParser parser = JsonXContent.jsonXContent.createParser(bytes);