Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.common.xcontent.json.JsonXContentParser;
import org.elasticsearch.ingest.AbstractProcessor;
Expand Down Expand Up @@ -95,8 +97,7 @@ public Factory(ScriptService scriptService) {
public ScriptProcessor create(Map<String, Processor.Factory> registry, String processorTag,
Map<String, Object> config) throws Exception {
XContentBuilder builder = XContentBuilder.builder(JsonXContent.jsonXContent).map(config);
JsonXContentParser parser = new JsonXContentParser(NamedXContentRegistry.EMPTY,
JSON_FACTORY.createParser(builder.bytes().streamInput()));
XContentParser parser = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, builder.bytes().streamInput());
Script script = Script.parse(parser);

Arrays.asList("id", "source", "inline", "lang", "params", "options").forEach(config::remove);
Expand Down
37 changes: 26 additions & 11 deletions server/src/main/java/org/elasticsearch/common/ParseField.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
import org.elasticsearch.common.xcontent.XContentParser;

import java.util.Collections;
import java.util.HashSet;
Expand All @@ -31,9 +34,6 @@
* variants, which may be deprecated.
*/
public class ParseField {

private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(Loggers.getLogger(ParseField.class));

private final String name;
private final String[] deprecatedNames;
private String allReplacedWith = null;
Expand Down Expand Up @@ -99,12 +99,31 @@ public ParseField withAllDeprecated(String allReplacedWith) {
}

/**
* Does {@code fieldName} match this field? Uses {@link LoggingDeprecationHandler}
* to prevent us from having to touch every call to {@code match} in the change
* that introduced {@linkplain LoggingDeprecationHandler}. In a followup this will
* be removed.
* @param fieldName
* the field name to match against this {@link ParseField}
* @return true if <code>fieldName</code> matches any of the acceptable
* names for this {@link ParseField}.
* @deprecated Use {@link #match(String, DeprecationHandler)} with
* {@link XContentParser#getDeprecationHandler()} instead.
*/
@Deprecated
public boolean match(String fieldName) {
return match(fieldName, LoggingDeprecationHandler.INSTANCE);
}

/**
* Does {@code fieldName} match this field?
* @param fieldName
* the field name to match against this {@link ParseField}
* @param deprecationHandler called if {@code fieldName} is deprecated
* @return true if <code>fieldName</code> matches any of the acceptable
* names for this {@link ParseField}.
*/
public boolean match(String fieldName, DeprecationHandler deprecationHandler) {
Objects.requireNonNull(fieldName, "fieldName cannot be null");
// if this parse field has not been completely deprecated then try to
// match the preferred name
Expand All @@ -114,17 +133,13 @@ public boolean match(String fieldName) {
// Now try to match against one of the deprecated names. Note that if
// the parse field is entirely deprecated (allReplacedWith != null) all
// fields will be in the deprecatedNames array
String msg;
for (String depName : deprecatedNames) {
if (fieldName.equals(depName)) {
msg = "Deprecated field [" + fieldName + "] used, expected [" + name + "] instead";
if (allReplacedWith != null) {
// If the field is entirely deprecated then there is no
// preferred name so instead use the `allReplaceWith`
// message to indicate what should be used instead
msg = "Deprecated field [" + fieldName + "] used, replaced by [" + allReplacedWith + "]";
if (allReplacedWith == null) {
deprecationHandler.usedDeprecatedName(fieldName, name);
} else {
deprecationHandler.usedDeprecatedField(fieldName, allReplacedWith);
}
DEPRECATION_LOGGER.deprecated(msg);
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.MemorySizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
Expand Down Expand Up @@ -1143,8 +1144,9 @@ public static <T> Setting<List<T>> listSetting(String key, Function<Settings, Li
}

private static List<String> parseableStringToList(String parsableString) {
// EMPTY is safe here because we never call namedObject
try (XContentParser xContentParser = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, parsableString)) {
// fromXContent doesn't use named xcontent or deprecation.
try (XContentParser xContentParser = XContentType.JSON.xContent()
.createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, parsableString)) {
XContentParser.Token token = xContentParser.nextToken();
if (token != XContentParser.Token.START_ARRAY) {
throw new IllegalArgumentException("expected START_ARRAY but got " + token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.elasticsearch.common.unit.RatioValue;
import org.elasticsearch.common.unit.SizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.ToXContentFragment;
import org.elasticsearch.common.xcontent.XContentBuilder;
Expand Down Expand Up @@ -1144,7 +1145,9 @@ public Builder loadFromStream(String resourceName, InputStream is, boolean accep
} else {
throw new IllegalArgumentException("unable to detect content type from resource name [" + resourceName + "]");
}
try (XContentParser parser = XContentFactory.xContent(xContentType).createParser(NamedXContentRegistry.EMPTY, is)) {
// fromXContent doesn't use named xcontent or deprecation.
try (XContentParser parser = XContentFactory.xContent(xContentType)
.createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, is)) {
if (parser.currentToken() == null) {
if (parser.nextToken() == null) {
return this; // empty file
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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.common.xcontent;

/**
* Callback for notifying the creator of the {@link XContentParser} that
* parsing hit a deprecated field.
*/
public interface DeprecationHandler {
/**
* Throws an {@link UnsupportedOperationException} when parsing hits a
* deprecated field. Use this when creating an {@link XContentParser}
* that won't interact with deprecation logic at all or when you want
* to fail fast when parsing deprecated fields.
*/
DeprecationHandler THROW_UNSUPPORTED_OPERATION = new DeprecationHandler() {
@Override
public void usedDeprecatedField(String usedName, String replacedWith) {
throw new UnsupportedOperationException("deprecated fields not supported here but got ["
+ usedName + "] which is a deprecated name for [" + replacedWith + "]");
}
@Override
public void usedDeprecatedName(String usedName, String modernName) {
throw new UnsupportedOperationException("deprecated fields not supported here but got ["
+ usedName + "] which has been replaced with [" + modernName + "]");
}
};

/**
* Called when the provided field name matches a deprecated name for the field.
* @param usedName the provided field name
* @param modernName the modern name for the field
*/
void usedDeprecatedName(String usedName, String modernName);

/**
* Called when the provided field name matches the current field but the entire
* field has been marked as deprecated.
* @param usedName the provided field name
* @param replacedWith the name of the field that replaced this field
*/
void usedDeprecatedField(String usedName, String replacedWith);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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.common.xcontent;

import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.logging.Loggers;

/**
* Logs deprecations to the {@link DeprecationLogger}.
* <p>
* This is core's primary implementation of {@link DeprecationHandler} and
* should <strong>absolutely</strong> be used everywhere where it parses
* requests. It is much less appropriate when parsing responses from external
* sources because it will report deprecated fields back to the user as
* though the user sent them.
*/
public class LoggingDeprecationHandler implements DeprecationHandler {
public static LoggingDeprecationHandler INSTANCE = new LoggingDeprecationHandler();
/**
* The logger to which to send deprecation messages.
*
* This uses ParseField's logger because that is the logger that
* we have been using for many releases for deprecated fields.
* Changing that will require some research to make super duper
* sure it is safe.
*/
private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(Loggers.getLogger(ParseField.class));

private LoggingDeprecationHandler() {
// Singleton
}

@Override
public void usedDeprecatedName(String usedName, String modernName) {
DEPRECATION_LOGGER.deprecated("Deprecated field [{}] used, expected [{}] instead", usedName, modernName);
}

@Override
public void usedDeprecatedField(String usedName, String replacedWith) {
DEPRECATION_LOGGER.deprecated("Deprecated field [{}] used, replaced by [{}]", usedName, replacedWith);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public Value parse(XContentParser parser, Value value, Context context) throws I
assert ignoreUnknownFields : "this should only be possible if configured to ignore known fields";
parser.skipChildren(); // noop if parser points to a value, skips children if parser is start object or start array
} else {
fieldParser.assertSupports(name, token, currentFieldName, parser.getTokenLocation());
fieldParser.assertSupports(name, parser, currentFieldName);
parseSub(parser, fieldParser, currentFieldName, value, context);
}
fieldParser = null;
Expand Down Expand Up @@ -362,13 +362,14 @@ private class FieldParser {
this.type = type;
}

void assertSupports(String parserName, XContentParser.Token token, String currentFieldName, XContentLocation location) {
void assertSupports(String parserName, XContentParser parser, String currentFieldName) {
if (parseField.match(currentFieldName) == false) {
throw new ParsingException(location, "[" + parserName + "] parsefield doesn't accept: " + currentFieldName);
throw new ParsingException(parser.getTokenLocation(),
"[" + parserName + "] parsefield doesn't accept: " + currentFieldName);
}
if (supportedTokens.contains(token) == false) {
throw new ParsingException(location,
"[" + parserName + "] " + currentFieldName + " doesn't support values of type: " + token);
if (supportedTokens.contains(parser.currentToken()) == false) {
throw new ParsingException(parser.getTokenLocation(),
"[" + parserName + "] " + currentFieldName + " doesn't support values of type: " + parser.currentToken());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,31 +83,102 @@ default XContentGenerator createGenerator(OutputStream os) throws IOException {
/**
* Creates a parser over the provided string content.
*/
XContentParser createParser(NamedXContentRegistry xContentRegistry, String content) throws IOException;
XContentParser createParser(NamedXContentRegistry xContentRegistry,
DeprecationHandler deprecationHandler, String content) throws IOException;

/**
* Creates a parser over the provided input stream.
*/
XContentParser createParser(NamedXContentRegistry xContentRegistry, InputStream is) throws IOException;
XContentParser createParser(NamedXContentRegistry xContentRegistry,
DeprecationHandler deprecationHandler, InputStream is) throws IOException;

/**
* Creates a parser over the provided bytes.
*/
XContentParser createParser(NamedXContentRegistry xContentRegistry, byte[] data) throws IOException;
XContentParser createParser(NamedXContentRegistry xContentRegistry,
DeprecationHandler deprecationHandler, byte[] data) throws IOException;

/**
* Creates a parser over the provided bytes.
*/
XContentParser createParser(NamedXContentRegistry xContentRegistry, byte[] data, int offset, int length) throws IOException;
XContentParser createParser(NamedXContentRegistry xContentRegistry,
DeprecationHandler deprecationHandler, byte[] data, int offset, int length) throws IOException;

/**
* Creates a parser over the provided bytes.
*/
XContentParser createParser(NamedXContentRegistry xContentRegistry, BytesReference bytes) throws IOException;
XContentParser createParser(NamedXContentRegistry xContentRegistry,
DeprecationHandler deprecationHandler, BytesReference bytes) throws IOException;

/**
* Creates a parser over the provided reader.
*/
XContentParser createParser(NamedXContentRegistry xContentRegistry, Reader reader) throws IOException;
XContentParser createParser(NamedXContentRegistry xContentRegistry,
DeprecationHandler deprecationHandler, Reader reader) throws IOException;

/**
* Creates a parser over the provided string content using
* {@link LoggingDeprecationHandler}.
* @deprecated This is a temporary shim so we can migrate all calls to createParser incrementally.
* Use {@link #createParser(NamedXContentRegistry, DeprecationHandler, String)} instead.
*/
@Deprecated
default XContentParser createParser(NamedXContentRegistry xContentRegistry, String content) throws IOException {
return createParser(xContentRegistry, LoggingDeprecationHandler.INSTANCE, content);
}

/**
* Creates a parser over the provided input stream using
* {@link LoggingDeprecationHandler}.
* @deprecated This is a temporary shim so we can migrate all calls to createParser incrementally.
* Use {@link #createParser(NamedXContentRegistry, DeprecationHandler, InputStream)} instead.
*/
@Deprecated
default XContentParser createParser(NamedXContentRegistry xContentRegistry, InputStream is) throws IOException {
return createParser(xContentRegistry, LoggingDeprecationHandler.INSTANCE, is);
}

/**
* Creates a parser over the provided bytes using
* {@link LoggingDeprecationHandler}.
* @deprecated This is a temporary shim so we can migrate all calls to createParser incrementally.
* Use {@link #createParser(NamedXContentRegistry, DeprecationHandler, byte[])} instead.
*/
@Deprecated
default XContentParser createParser(NamedXContentRegistry xContentRegistry, byte[] data) throws IOException {
return createParser(xContentRegistry, LoggingDeprecationHandler.INSTANCE, data);
}

/**
* Creates a parser over the provided bytes using
* {@link LoggingDeprecationHandler}.
* @deprecated This is a temporary shim so we can migrate all calls to createParser incrementally.
* Use {@link #createParser(NamedXContentRegistry, DeprecationHandler, byte[], int, int)} instead.
*/
@Deprecated
default XContentParser createParser(NamedXContentRegistry xContentRegistry, byte[] data, int offset, int length) throws IOException {
return createParser(xContentRegistry, LoggingDeprecationHandler.INSTANCE, data, offset, length);
}

/**
* Creates a parser over the provided bytes using
* {@link LoggingDeprecationHandler}.
* @deprecated This is a temporary shim so we can migrate all calls to createParser incrementally.
* Use {@link #createParser(NamedXContentRegistry, DeprecationHandler, BytesReference)} instead.
*/
@Deprecated
default XContentParser createParser(NamedXContentRegistry xContentRegistry, BytesReference bytes) throws IOException {
return createParser(xContentRegistry, LoggingDeprecationHandler.INSTANCE, bytes);
}

/**
* Creates a parser over the provided reader using
* {@link LoggingDeprecationHandler}.
* @deprecated This is a temporary shim so we can migrate all calls to createParser incrementally.
* Use {@link #createParser(NamedXContentRegistry, DeprecationHandler, Reader)} instead.
*/
@Deprecated
default XContentParser createParser(NamedXContentRegistry xContentRegistry, Reader reader) throws IOException {
return createParser(xContentRegistry, LoggingDeprecationHandler.INSTANCE, reader);
}
}
Loading