All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opensearch.script.ScriptContext Maven / Gradle / Ivy

There is a newer version: 2.18.0
Show newest version
/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * The OpenSearch Contributors require contributions made to
 * this file be licensed under the Apache-2.0 license or a
 * compatible open source license.
 */

/*
 * 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.
 */

/*
 * Modifications Copyright OpenSearch Contributors. See
 * GitHub history for details.
 */

package org.opensearch.script;

import org.opensearch.common.annotation.PublicApi;
import org.opensearch.common.collect.Tuple;
import org.opensearch.common.unit.TimeValue;

import java.lang.reflect.Method;

/**
 * The information necessary to compile and run a script.
 * 

* A {@link ScriptContext} contains the information related to a single use case and the interfaces * and methods necessary for a {@link ScriptEngine} to implement. *

* There are at least two (and optionally a third) related classes which must be defined. *

* The InstanceType is a class which users of the script api call to execute a script. It * may be stateful. Instances of * the InstanceType may be executed multiple times by a caller with different arguments. This * class must have an abstract method named {@code execute} which {@link ScriptEngine} implementations * will define. *

* The FactoryType is a factory class returned by the {@link ScriptService} when compiling * a script. This class must be stateless so it is cacheable by the {@link ScriptService}. It must * have one of the following: *

    *
  • An abstract method named {@code newInstance} which returns an instance of InstanceType
  • *
  • An abstract method named {@code newFactory} which returns an instance of StatefulFactoryType
  • *
*

* The StatefulFactoryType is an optional class which allows a stateful factory from the * stateless factory type required by the {@link ScriptService}. If defined, the StatefulFactoryType * must have a method named {@code newInstance} which returns an instance of InstanceType. *

* Both the FactoryType and StatefulFactoryType may have abstract methods to indicate * whether a variable is used in a script. These method should return a {@code boolean} and their name * should start with {@code needs}, followed by the variable name, with the first letter uppercased. * For example, to check if a variable {@code doc} is used, a method {@code boolean needsDoc()} should be added. * If the variable name starts with an underscore, for example, {@code _score}, the needs method would * be {@code boolean needs_score()}. * * @opensearch.api */ @PublicApi(since = "1.0.0") public final class ScriptContext { /** A unique identifier for this context. */ public final String name; /** A factory class for constructing script or stateful factory instances. */ public final Class factoryClazz; /** A factory class for construct script instances. */ public final Class statefulFactoryClazz; /** A class that is an instance of a script. */ public final Class instanceClazz; /** The default size of the cache for the context if not overridden */ public final int cacheSizeDefault; /** The default expiration of a script in the cache for the context, if not overridden */ public final TimeValue cacheExpireDefault; /** The default max compilation rate for scripts in this context. Script compilation is throttled if this is exceeded */ public final Tuple maxCompilationRateDefault; /** Construct a context with the related instance and compiled classes with caller provided cache defaults */ public ScriptContext( String name, Class factoryClazz, int cacheSizeDefault, TimeValue cacheExpireDefault, Tuple maxCompilationRateDefault ) { this.name = name; this.factoryClazz = factoryClazz; Method newInstanceMethod = findMethod("FactoryType", factoryClazz, "newInstance"); Method newFactoryMethod = findMethod("FactoryType", factoryClazz, "newFactory"); if (newFactoryMethod != null) { assert newInstanceMethod == null; statefulFactoryClazz = newFactoryMethod.getReturnType(); newInstanceMethod = findMethod("StatefulFactoryType", statefulFactoryClazz, "newInstance"); if (newInstanceMethod == null) { throw new IllegalArgumentException( "Could not find method newInstance StatefulFactoryType class [" + statefulFactoryClazz.getName() + "] for script context [" + name + "]" ); } } else if (newInstanceMethod != null) { assert newFactoryMethod == null; statefulFactoryClazz = null; } else { throw new IllegalArgumentException( "Could not find method newInstance or method newFactory on FactoryType class [" + factoryClazz.getName() + "] for script context [" + name + "]" ); } instanceClazz = newInstanceMethod.getReturnType(); this.cacheSizeDefault = cacheSizeDefault; this.cacheExpireDefault = cacheExpireDefault; this.maxCompilationRateDefault = maxCompilationRateDefault; } /** Construct a context with the related instance and compiled classes with defaults for cacheSizeDefault, cacheExpireDefault and * maxCompilationRateDefault */ public ScriptContext(String name, Class factoryClazz) { // cache size default, cache expire default, max compilation rate are defaults from ScriptService. this(name, factoryClazz, 100, TimeValue.timeValueMillis(0), new Tuple<>(75, TimeValue.timeValueMinutes(5))); } /** Returns a method with the given name, or throws an exception if multiple are found. */ private Method findMethod(String type, Class clazz, String methodName) { Method foundMethod = null; for (Method method : clazz.getMethods()) { if (method.getName().equals(methodName)) { if (foundMethod != null) { throw new IllegalArgumentException( "Cannot have multiple " + methodName + " methods on " + type + " class [" + clazz.getName() + "] for script context [" + name + "]" ); } foundMethod = method; } } return foundMethod; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy