Merge branch 'master' into feature/async_rest_client

This commit is contained in:
javanna 2016-07-22 22:22:03 +02:00 committed by Luca Cavanna
commit 36becd9bfe
8 changed files with 121 additions and 16 deletions

View File

@ -33,6 +33,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
@ -509,7 +510,19 @@ public class Strings {
else return s.split(","); else return s.split(",");
} }
/**
* A convenience method for splitting a delimited string into
* a set and trimming leading and trailing whitespace from all
* split strings.
*
* @param s the string to split
* @param c the delimiter to split on
* @return the set of split strings
*/
public static Set<String> splitStringToSet(final String s, final char c) { public static Set<String> splitStringToSet(final String s, final char c) {
if (s == null || s.isEmpty()) {
return Collections.emptySet();
}
final char[] chars = s.toCharArray(); final char[] chars = s.toCharArray();
int count = 1; int count = 1;
for (final char x : chars) { for (final char x : chars) {
@ -521,16 +534,25 @@ public class Strings {
final int len = chars.length; final int len = chars.length;
int start = 0; // starting index in chars of the current substring. int start = 0; // starting index in chars of the current substring.
int pos = 0; // current index in chars. int pos = 0; // current index in chars.
int end = 0; // the position of the end of the current token
for (; pos < len; pos++) { for (; pos < len; pos++) {
if (chars[pos] == c) { if (chars[pos] == c) {
int size = pos - start; int size = end - start;
if (size > 0) { // only add non empty strings if (size > 0) { // only add non empty strings
result.add(new String(chars, start, size)); result.add(new String(chars, start, size));
} }
start = pos + 1; start = pos + 1;
end = start;
} else if (Character.isWhitespace(chars[pos])) {
if (start == pos) {
// skip over preceding whitespace
start++;
}
} else {
end = pos + 1;
} }
} }
int size = pos - start; int size = end - start;
if (size > 0) { if (size > 0) {
result.add(new String(chars, start, size)); result.add(new String(chars, start, size));
} }

View File

@ -40,9 +40,9 @@ public final class HttpTransportSettings {
public static final Setting<Integer> SETTING_CORS_MAX_AGE = public static final Setting<Integer> SETTING_CORS_MAX_AGE =
Setting.intSetting("http.cors.max-age", 1728000, Property.NodeScope); Setting.intSetting("http.cors.max-age", 1728000, Property.NodeScope);
public static final Setting<String> SETTING_CORS_ALLOW_METHODS = public static final Setting<String> SETTING_CORS_ALLOW_METHODS =
new Setting<>("http.cors.allow-methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE", (value) -> value, Property.NodeScope); new Setting<>("http.cors.allow-methods", "OPTIONS,HEAD,GET,POST,PUT,DELETE", (value) -> value, Property.NodeScope);
public static final Setting<String> SETTING_CORS_ALLOW_HEADERS = public static final Setting<String> SETTING_CORS_ALLOW_HEADERS =
new Setting<>("http.cors.allow-headers", "X-Requested-With, Content-Type, Content-Length", (value) -> value, Property.NodeScope); new Setting<>("http.cors.allow-headers", "X-Requested-With,Content-Type,Content-Length", (value) -> value, Property.NodeScope);
public static final Setting<Boolean> SETTING_CORS_ALLOW_CREDENTIALS = public static final Setting<Boolean> SETTING_CORS_ALLOW_CREDENTIALS =
Setting.boolSetting("http.cors.allow-credentials", false, Property.NodeScope); Setting.boolSetting("http.cors.allow-credentials", false, Property.NodeScope);
public static final Setting<Boolean> SETTING_PIPELINING = public static final Setting<Boolean> SETTING_PIPELINING =

View File

@ -19,6 +19,7 @@
package org.elasticsearch.common; package org.elasticsearch.common;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
@ -73,4 +74,32 @@ public class StringsTests extends ESTestCase {
assertThat(toString, containsString("\"ok\":\"here\"")); assertThat(toString, containsString("\"ok\":\"here\""));
assertThat(toString, containsString("\"catastrophe\":\"\"")); assertThat(toString, containsString("\"catastrophe\":\"\""));
} }
public void testSplitStringToSet() {
assertEquals(Strings.splitStringByCommaToSet(null), Sets.newHashSet());
assertEquals(Strings.splitStringByCommaToSet(""), Sets.newHashSet());
assertEquals(Strings.splitStringByCommaToSet("a,b,c"), Sets.newHashSet("a","b","c"));
assertEquals(Strings.splitStringByCommaToSet("a, b, c"), Sets.newHashSet("a","b","c"));
assertEquals(Strings.splitStringByCommaToSet(" a , b, c "), Sets.newHashSet("a","b","c"));
assertEquals(Strings.splitStringByCommaToSet("aa, bb, cc"), Sets.newHashSet("aa","bb","cc"));
assertEquals(Strings.splitStringByCommaToSet(" a "), Sets.newHashSet("a"));
assertEquals(Strings.splitStringByCommaToSet(" a "), Sets.newHashSet("a"));
assertEquals(Strings.splitStringByCommaToSet(" aa "), Sets.newHashSet("aa"));
assertEquals(Strings.splitStringByCommaToSet(" "), Sets.newHashSet());
assertEquals(Strings.splitStringToSet(null, ' '), Sets.newHashSet());
assertEquals(Strings.splitStringToSet("", ' '), Sets.newHashSet());
assertEquals(Strings.splitStringToSet("a b c", ' '), Sets.newHashSet("a","b","c"));
assertEquals(Strings.splitStringToSet("a, b, c", ' '), Sets.newHashSet("a,","b,","c"));
assertEquals(Strings.splitStringToSet(" a b c ", ' '), Sets.newHashSet("a","b","c"));
assertEquals(Strings.splitStringToSet(" a b c ", ' '), Sets.newHashSet("a","b","c"));
assertEquals(Strings.splitStringToSet("aa bb cc", ' '), Sets.newHashSet("aa","bb","cc"));
assertEquals(Strings.splitStringToSet(" a ", ' '), Sets.newHashSet("a"));
assertEquals(Strings.splitStringToSet(" a ", ' '), Sets.newHashSet("a"));
assertEquals(Strings.splitStringToSet(" a ", ' '), Sets.newHashSet("a"));
assertEquals(Strings.splitStringToSet("a ", ' '), Sets.newHashSet("a"));
assertEquals(Strings.splitStringToSet(" aa ", ' '), Sets.newHashSet("aa"));
assertEquals(Strings.splitStringToSet("aa ", ' '), Sets.newHashSet("aa"));
assertEquals(Strings.splitStringToSet(" ", ' '), Sets.newHashSet());
}
} }

View File

@ -81,9 +81,11 @@ import java.net.InetSocketAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.elasticsearch.common.settings.Setting.boolSetting; import static org.elasticsearch.common.settings.Setting.boolSetting;
import static org.elasticsearch.common.settings.Setting.byteSizeSetting; import static org.elasticsearch.common.settings.Setting.byteSizeSetting;
@ -390,14 +392,10 @@ public class Netty3HttpServerTransport extends AbstractLifecycleComponent implem
if (SETTING_CORS_ALLOW_CREDENTIALS.get(settings)) { if (SETTING_CORS_ALLOW_CREDENTIALS.get(settings)) {
builder.allowCredentials(); builder.allowCredentials();
} }
String[] strMethods = settings.getAsArray(SETTING_CORS_ALLOW_METHODS.getKey()); Set<String> strMethods = Strings.splitStringByCommaToSet(SETTING_CORS_ALLOW_METHODS.get(settings));
HttpMethod[] methods = Arrays.asList(strMethods) return builder.allowedRequestMethods(strMethods.stream().map(HttpMethod::valueOf).collect(Collectors.toSet()))
.stream()
.map(HttpMethod::valueOf)
.toArray(size -> new HttpMethod[size]);
return builder.allowedRequestMethods(methods)
.maxAge(SETTING_CORS_MAX_AGE.get(settings)) .maxAge(SETTING_CORS_MAX_AGE.get(settings))
.allowedRequestHeaders(settings.getAsArray(SETTING_CORS_ALLOW_HEADERS.getKey())) .allowedRequestHeaders(Strings.splitStringByCommaToSet(SETTING_CORS_ALLOW_HEADERS.get(settings)))
.shortCircuit() .shortCircuit()
.build(); .build();
} }

View File

@ -193,8 +193,8 @@ public final class Netty3CorsConfigBuilder {
* @param methods the {@link HttpMethod}s that should be allowed. * @param methods the {@link HttpMethod}s that should be allowed.
* @return {@link Netty3CorsConfigBuilder} to support method chaining. * @return {@link Netty3CorsConfigBuilder} to support method chaining.
*/ */
public Netty3CorsConfigBuilder allowedRequestMethods(final HttpMethod... methods) { public Netty3CorsConfigBuilder allowedRequestMethods(final Set<HttpMethod> methods) {
requestMethods.addAll(Arrays.asList(methods)); requestMethods.addAll(methods);
return this; return this;
} }
@ -214,8 +214,8 @@ public final class Netty3CorsConfigBuilder {
* @param headers the headers to be added to the preflight 'Access-Control-Allow-Headers' response header. * @param headers the headers to be added to the preflight 'Access-Control-Allow-Headers' response header.
* @return {@link Netty3CorsConfigBuilder} to support method chaining. * @return {@link Netty3CorsConfigBuilder} to support method chaining.
*/ */
public Netty3CorsConfigBuilder allowedRequestHeaders(final String... headers) { public Netty3CorsConfigBuilder allowedRequestHeaders(final Set<String> headers) {
requestHeaders.addAll(Arrays.asList(headers)); requestHeaders.addAll(headers);
return this; return this;
} }

View File

@ -23,6 +23,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.MockBigArrays; import org.elasticsearch.common.util.MockBigArrays;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.http.netty3.cors.Netty3CorsConfig; import org.elasticsearch.http.netty3.cors.Netty3CorsConfig;
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService; import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
@ -86,4 +87,19 @@ public class Netty3HttpServerTransportTests extends ESTestCase {
assertThat(corsConfig.allowedRequestMethods().stream().map(HttpMethod::getName).collect(Collectors.toSet()), equalTo(methods)); assertThat(corsConfig.allowedRequestMethods().stream().map(HttpMethod::getName).collect(Collectors.toSet()), equalTo(methods));
transport.close(); transport.close();
} }
public void testCorsConfigDefaults() {
final Set<String> headers = Sets.newHashSet("X-Requested-With", "Content-Type", "Content-Length");
final Set<String> methods = Sets.newHashSet("OPTIONS", "HEAD", "GET", "POST", "PUT", "DELETE");
final Settings settings = Settings.builder()
.put(SETTING_CORS_ENABLED.getKey(), true)
.put(SETTING_CORS_ALLOW_ORIGIN.getKey(), "*")
.put(SETTING_CORS_ALLOW_CREDENTIALS.getKey(), true)
.build();
final Netty3HttpServerTransport transport = new Netty3HttpServerTransport(settings, networkService, bigArrays, threadPool);
final Netty3CorsConfig corsConfig = transport.getCorsConfig();
assertThat(corsConfig.allowedRequestHeaders(), equalTo(headers));
assertThat(corsConfig.allowedRequestMethods().stream().map(HttpMethod::getName).collect(Collectors.toSet()), equalTo(methods));
transport.close();
}
} }

View File

@ -0,0 +1,40 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.http.netty3;
import com.carrotsearch.randomizedtesting.annotations.Name;
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
import org.elasticsearch.test.rest.ESRestTestCase;
import org.elasticsearch.test.rest.RestTestCandidate;
import org.elasticsearch.test.rest.parser.RestTestParseException;
import java.io.IOException;
public class Netty3RestIT extends ESRestTestCase {
public Netty3RestIT(@Name("yaml") RestTestCandidate testCandidate) {
super(testCandidate);
}
@ParametersFactory
public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
return ESRestTestCase.createParameters(0, 1);
}
}