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
6 changes: 4 additions & 2 deletions docs/plugins/authors.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

The Elasticsearch repository contains examples of:

* a https://github.com/elastic/elasticsearch/tree/master/plugins/jvm-example[Java plugin]
which contains Java code.
* a https://github.com/elastic/elasticsearch/tree/master/plugins/custom-settings[Java plugin]
which contains a plugin with custom settings.
* a https://github.com/elastic/elasticsearch/tree/master/plugins/rest-handler[Java plugin]
which contains a plugin that registers a Rest handler.
* a https://github.com/elastic/elasticsearch/tree/master/plugins/examples/rescore[Java plugin]
which contains a rescore plugin.
* a https://github.com/elastic/elasticsearch/tree/master/plugins/examples/script-expert-scoring[Java plugin]
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/cat/plugins.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ U7321H6 discovery-gce {version} The Google Compute Engine (GCE) Discov
U7321H6 ingest-attachment {version} Ingest processor that uses Apache Tika to extract contents
U7321H6 ingest-geoip {version} Ingest processor that uses looksup geo data based on ip adresses using the Maxmind geo database
U7321H6 ingest-user-agent {version} Ingest processor that extracts information from a user agent
U7321H6 jvm-example {version} Demonstrates all the pluggable Java entry points in Elasticsearch
U7321H6 mapper-murmur3 {version} The Mapper Murmur3 plugin allows to compute hashes of a field's values at index-time and to store them in the index.
U7321H6 mapper-size {version} The Mapper Size plugin allows document to record their uncompressed size at index time.
U7321H6 store-smb {version} The Store SMB plugin adds support for SMB stores.
U7321H6 transport-nio {version} The nio transport.
------------------------------------------------------------------------------
// TESTRESPONSE[s/([.()])/\\$1/ s/U7321H6/.+/ _cat]

Expand Down
31 changes: 31 additions & 0 deletions plugins/examples/custom-settings/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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.
*/

apply plugin: 'elasticsearch.esplugin'

esplugin {
name 'custom-settings'
description 'An example plugin showing how to register custom settings'
classname 'org.elasticsearch.example.customsettings.ExampleCustomSettingsPlugin'
}

integTestCluster {
// Adds a setting in the Elasticsearch keystore before running the integration tests
keystoreSetting 'custom.secured', 'password'
}
6 changes: 6 additions & 0 deletions plugins/examples/custom-settings/src/main/bin/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

# Plugin can contain executable files that are copied by the plugin manager
# to a <plugin-name>/bin folder.

echo test
4 changes: 4 additions & 0 deletions plugins/examples/custom-settings/src/main/bin/test.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
REM Plugin can contain executable files that are copied by the plugin manager
REM to a <plugin-name>/bin folder.

echo test
5 changes: 5 additions & 0 deletions plugins/examples/custom-settings/src/main/config/custom.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Custom configuration file for the custom-settings plugin
custom:
simple: foo
list: [0, 1, 1, 2, 3, 5, 8, 13, 21]
filtered: secret
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* 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.example.customsettings;

import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.settings.SecureSetting;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;

/**
* {@link ExampleCustomSettingsConfig} contains the custom settings values and their static declarations.
*/
public class ExampleCustomSettingsConfig {

/**
* A simple string setting
*/
static final Setting<String> SIMPLE_SETTING = Setting.simpleString("custom.simple", Property.NodeScope);

/**
* A simple boolean setting that can be dynamically updated using the Cluster Settings API and that is {@code "false"} by default
*/
static final Setting<Boolean> BOOLEAN_SETTING = Setting.boolSetting("custom.bool", false, Property.NodeScope, Property.Dynamic);

/**
* A string setting that can be dynamically updated and that is validated by some logic
*/
static final Setting<String> VALIDATED_SETTING = Setting.simpleString("custom.validated", (value, settings) -> {
if (value != null && value.contains("forbidden")) {
throw new IllegalArgumentException("Setting must not contain [forbidden]");
}
}, Property.NodeScope, Property.Dynamic);

/**
* A setting that is filtered out when listing all the cluster's settings
*/
static final Setting<String> FILTERED_SETTING = Setting.simpleString("custom.filtered", Property.NodeScope, Property.Filtered);

/**
* A setting which contains a sensitive string. This may be any sensitive string, e.g. a username, a password, an auth token, etc.
*/
static final Setting<SecureString> SECURED_SETTING = SecureSetting.secureString("custom.secured", null);

/**
* A setting that consists of a list of integers
*/
static final Setting<List<Integer>> LIST_SETTING =
Setting.listSetting("custom.list", Collections.emptyList(), Integer::valueOf, Property.NodeScope);


private final String simple;
private final String validated;
private final Boolean bool;
private final List<Integer> list;
private final String filtered;

public ExampleCustomSettingsConfig(final Environment environment) {
// Elasticsearch config directory
final Path configDir = environment.configFile();

// Resolve the plugin's custom settings file
final Path customSettingsYamlFile = configDir.resolve("custom-settings/custom.yml");

// Load the settings from the plugin's custom settings file
final Settings customSettings;
try {
customSettings = Settings.builder().loadFromPath(customSettingsYamlFile).build();
assert customSettings != null;
} catch (IOException e) {
throw new ElasticsearchException("Failed to load settings", e);
}

this.simple = SIMPLE_SETTING.get(customSettings);
this.bool = BOOLEAN_SETTING.get(customSettings);
this.validated = VALIDATED_SETTING.get(customSettings);
this.filtered = FILTERED_SETTING.get(customSettings);
this.list = LIST_SETTING.get(customSettings);

// Loads the secured setting from the keystore
final SecureString secured = SECURED_SETTING.get(environment.settings());
assert secured != null;
}

public String getSimple() {
return simple;
}

public Boolean getBool() {
return bool;
}

public String getValidated() {
return validated;
}

public String getFiltered() {
return filtered;
}

public List<Integer> getList() {
return list;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* 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.example.customsettings;

import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.plugins.Plugin;

import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;

import static java.util.stream.Collectors.toList;

public class ExampleCustomSettingsPlugin extends Plugin {

private final ExampleCustomSettingsConfig config;

public ExampleCustomSettingsPlugin(final Settings settings, final Path configPath) {
this.config = new ExampleCustomSettingsConfig(new Environment(settings, configPath));

// asserts that the setting has been correctly loaded from the custom setting file
assert "secret".equals(config.getFiltered());
}

/**
* @return the plugin's custom settings
*/
@Override
public List<Setting<?>> getSettings() {
return Arrays.asList(ExampleCustomSettingsConfig.SIMPLE_SETTING,
ExampleCustomSettingsConfig.BOOLEAN_SETTING,
ExampleCustomSettingsConfig.VALIDATED_SETTING,
ExampleCustomSettingsConfig.FILTERED_SETTING,
ExampleCustomSettingsConfig.SECURED_SETTING,
ExampleCustomSettingsConfig.LIST_SETTING);
}

@Override
public Settings additionalSettings() {
final Settings.Builder builder = Settings.builder();

// Exposes SIMPLE_SETTING and LIST_SETTING as a node settings
builder.put(ExampleCustomSettingsConfig.SIMPLE_SETTING.getKey(), config.getSimple());

final List<String> values = config.getList().stream().map(integer -> Integer.toString(integer)).collect(toList());
builder.putList(ExampleCustomSettingsConfig.LIST_SETTING.getKey(), values);

return builder.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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.example.customsettings;

import com.carrotsearch.randomizedtesting.annotations.Name;
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;

/**
* {@link ExampleCustomSettingsClientYamlTestSuiteIT} executes the plugin's REST API integration tests.
* <p>
* The tests can be executed using the command: ./gradlew :example-plugins:custom-settings:check
* <p>
* This class extends {@link ESClientYamlSuiteTestCase}, which takes care of parsing the YAML files
* located in the src/test/resources/rest-api-spec/test/ directory and validates them against the
* custom REST API definition files located in src/test/resources/rest-api-spec/api/.
* <p>
* Once validated, {@link ESClientYamlSuiteTestCase} executes the REST tests against a single node
* integration cluster which has the plugin already installed by the Gradle build script.
* </p>
*/
public class ExampleCustomSettingsClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {

public ExampleCustomSettingsClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
super(testCandidate);
}

@ParametersFactory
public static Iterable<Object[]> parameters() throws Exception {
// The test executes all the test candidates by default
// see ESClientYamlSuiteTestCase.REST_TESTS_SUITE
return ESClientYamlSuiteTestCase.createParameters();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.example.customsettings;

import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase;

import static org.elasticsearch.example.customsettings.ExampleCustomSettingsConfig.VALIDATED_SETTING;

/**
* {@link ExampleCustomSettingsConfigTests} is a unit test class for {@link ExampleCustomSettingsConfig}.
* <p>
* It's a JUnit test class that extends {@link ESTestCase} which provides useful methods for testing.
* <p>
* The tests can be executed in the IDE or using the command: ./gradlew :example-plugins:custom-settings:test
*/
public class ExampleCustomSettingsConfigTests extends ESTestCase {

public void testValidatedSetting() {
final String expected = randomAlphaOfLengthBetween(1, 5);
final String actual = VALIDATED_SETTING.get(Settings.builder().put(VALIDATED_SETTING.getKey(), expected).build());
assertEquals(expected, actual);

final IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () ->
VALIDATED_SETTING.get(Settings.builder().put("custom.validated", "it's forbidden").build()));
assertEquals("Setting must not contain [forbidden]", exception.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"Test that the custom-settings plugin is loaded in Elasticsearch":

# Use the Cat Plugins API to retrieve the list of plugins
- do:
cat.plugins:
local: true
h: component

- match:
$body: /^custom-settings\n$/
Loading