Merge branch 'master' into immutable_set_be_gone
Original commit: elastic/x-pack-elasticsearch@faa212ffbd
This commit is contained in:
commit
c6e7c9c1d6
|
@ -1,6 +0,0 @@
|
||||||
eclipse.preferences.version=1
|
|
||||||
encoding//src/main/java=UTF-8
|
|
||||||
encoding//src/main/resources=UTF-8
|
|
||||||
encoding//src/test/java=UTF-8
|
|
||||||
encoding//src/test/resources=UTF-8
|
|
||||||
encoding/<project>=UTF-8
|
|
|
@ -1,18 +0,0 @@
|
||||||
eclipse.preferences.version=1
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.nullable=org.elasticsearch.common.Nullable
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
|
||||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
|
||||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
|
|
||||||
org.eclipse.jdt.core.compiler.source=1.8
|
|
||||||
org.eclipse.jdt.core.formatter.lineSplit=140
|
|
||||||
org.eclipse.jdt.core.formatter.tabulation.char=space
|
|
||||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
|
File diff suppressed because one or more lines are too long
|
@ -43,7 +43,7 @@ public class MarvelSettingTests extends ESTestCase {
|
||||||
String description = randomAsciiOfLength(20);
|
String description = randomAsciiOfLength(20);
|
||||||
TimeValue defaultValue = null;
|
TimeValue defaultValue = null;
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
defaultValue = randomTimeValue();
|
defaultValue = randomParsedTimeValue();
|
||||||
}
|
}
|
||||||
boolean dynamic = randomBoolean();
|
boolean dynamic = randomBoolean();
|
||||||
|
|
||||||
|
@ -59,11 +59,11 @@ public class MarvelSettingTests extends ESTestCase {
|
||||||
setting.onRefresh(settingsBuilder().put(name, 15000L).build());
|
setting.onRefresh(settingsBuilder().put(name, 15000L).build());
|
||||||
assertThat(setting.getValue().millis(), equalTo(15000L));
|
assertThat(setting.getValue().millis(), equalTo(15000L));
|
||||||
|
|
||||||
TimeValue updated = randomTimeValue();
|
TimeValue updated = randomParsedTimeValue();
|
||||||
setting.onRefresh(settingsBuilder().put(name, updated.toString()).build());
|
setting.onRefresh(settingsBuilder().put(name, updated.toString()).build());
|
||||||
assertThat(setting.getValue().millis(), equalTo(updated.millis()));
|
assertThat(setting.getValue().millis(), equalTo(updated.millis()));
|
||||||
|
|
||||||
updated = randomTimeValue();
|
updated = randomParsedTimeValue();
|
||||||
setting.onRefresh(settingsBuilder().put(name, updated.toString()).build());
|
setting.onRefresh(settingsBuilder().put(name, updated.toString()).build());
|
||||||
assertThat(setting.getValue().millis(), equalTo(updated.millis()));
|
assertThat(setting.getValue().millis(), equalTo(updated.millis()));
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ public class MarvelSettingTests extends ESTestCase {
|
||||||
assertArrayEquals(setting.getValue(), updated);
|
assertArrayEquals(setting.getValue(), updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeValue randomTimeValue() {
|
private TimeValue randomParsedTimeValue() {
|
||||||
return TimeValue.parseTimeValue(randomFrom("10ms", "1.5s", "1.5m", "1.5h", "1.5d", "1000d"), null, getClass().getSimpleName() + ".unit");
|
return TimeValue.parseTimeValue(randomFrom("10ms", "1.5s", "1.5m", "1.5h", "1.5d", "1000d"), null, getClass().getSimpleName() + ".unit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,13 @@ import static org.hamcrest.Matchers.*;
|
||||||
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 1)
|
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 1)
|
||||||
public class MarvelSettingsTests extends ESIntegTestCase {
|
public class MarvelSettingsTests extends ESIntegTestCase {
|
||||||
|
|
||||||
private final TimeValue startUp = randomTimeValue();
|
private final TimeValue startUp = randomParsedTimeValue();
|
||||||
private final TimeValue interval = randomTimeValue();
|
private final TimeValue interval = randomParsedTimeValue();
|
||||||
private final TimeValue indexStatsTimeout = randomTimeValue();
|
private final TimeValue indexStatsTimeout = randomParsedTimeValue();
|
||||||
private final String[] indices = randomStringArray();
|
private final String[] indices = randomStringArray();
|
||||||
private final TimeValue clusterStateTimeout = randomTimeValue();
|
private final TimeValue clusterStateTimeout = randomParsedTimeValue();
|
||||||
private final TimeValue clusterStatsTimeout = randomTimeValue();
|
private final TimeValue clusterStatsTimeout = randomParsedTimeValue();
|
||||||
private final TimeValue recoveryTimeout = randomTimeValue();
|
private final TimeValue recoveryTimeout = randomParsedTimeValue();
|
||||||
private final Boolean recoveryActiveOnly = randomBoolean();
|
private final Boolean recoveryActiveOnly = randomBoolean();
|
||||||
private final String[] collectors = randomStringArray();
|
private final String[] collectors = randomStringArray();
|
||||||
private final TimeValue licenseGracePeriod = randomExpirationDelay();
|
private final TimeValue licenseGracePeriod = randomExpirationDelay();
|
||||||
|
@ -99,7 +99,7 @@ public class MarvelSettingsTests extends ESIntegTestCase {
|
||||||
Object updated = null;
|
Object updated = null;
|
||||||
Settings.Builder transientSettings = Settings.builder();
|
Settings.Builder transientSettings = Settings.builder();
|
||||||
if (setting instanceof MarvelSetting.TimeValueSetting) {
|
if (setting instanceof MarvelSetting.TimeValueSetting) {
|
||||||
updated = randomTimeValue();
|
updated = randomParsedTimeValue();
|
||||||
transientSettings.put(setting.getName(), updated);
|
transientSettings.put(setting.getName(), updated);
|
||||||
|
|
||||||
} else if (setting instanceof MarvelSetting.BooleanSetting) {
|
} else if (setting instanceof MarvelSetting.BooleanSetting) {
|
||||||
|
@ -156,7 +156,7 @@ public class MarvelSettingsTests extends ESIntegTestCase {
|
||||||
return requestBuilder;
|
return requestBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeValue randomTimeValue() {
|
private TimeValue randomParsedTimeValue() {
|
||||||
return TimeValue.parseTimeValue(randomFrom("30m", "1h", "3h", "5h", "7h", "10h", "1d"), null, getClass().getSimpleName());
|
return TimeValue.parseTimeValue(randomFrom("30m", "1h", "3h", "5h", "7h", "10h", "1d"), null, getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +171,6 @@ public class MarvelSettingsTests extends ESIntegTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeValue randomExpirationDelay() {
|
private TimeValue randomExpirationDelay() {
|
||||||
return randomBoolean() ? randomTimeValue() : TimeValue.timeValueHours(randomIntBetween(-10, 10) * 24);
|
return randomBoolean() ? randomParsedTimeValue() : TimeValue.timeValueHours(randomIntBetween(-10, 10) * 24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
eclipse.preferences.version=1
|
|
||||||
encoding//src/main/java=UTF-8
|
|
||||||
encoding//src/main/resources=UTF-8
|
|
||||||
encoding//src/test/java=UTF-8
|
|
||||||
encoding//src/test/resources=UTF-8
|
|
||||||
encoding/<project>=UTF-8
|
|
|
@ -1,18 +0,0 @@
|
||||||
eclipse.preferences.version=1
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.nullable=org.elasticsearch.common.Nullable
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
|
||||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
|
||||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
|
|
||||||
org.eclipse.jdt.core.compiler.source=1.8
|
|
||||||
org.eclipse.jdt.core.formatter.lineSplit=140
|
|
||||||
org.eclipse.jdt.core.formatter.tabulation.char=space
|
|
||||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
|
File diff suppressed because one or more lines are too long
|
@ -10,6 +10,7 @@ import org.elasticsearch.action.index.IndexRequest;
|
||||||
import org.elasticsearch.action.search.SearchPhaseExecutionException;
|
import org.elasticsearch.action.search.SearchPhaseExecutionException;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
|
import org.elasticsearch.indices.cache.query.terms.TermsLookup;
|
||||||
import org.elasticsearch.script.ScriptService;
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.script.Template;
|
import org.elasticsearch.script.Template;
|
||||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||||
|
@ -77,11 +78,7 @@ public class ShieldCachePermissionTests extends ShieldIntegTestCase {
|
||||||
@Test
|
@Test
|
||||||
public void testThatTermsFilterQueryDoesntLeakData() {
|
public void testThatTermsFilterQueryDoesntLeakData() {
|
||||||
SearchResponse response = client().prepareSearch("data").setTypes("a").setQuery(QueryBuilders.constantScoreQuery(
|
SearchResponse response = client().prepareSearch("data").setTypes("a").setQuery(QueryBuilders.constantScoreQuery(
|
||||||
QueryBuilders.termsLookupQuery("token")
|
QueryBuilders.termsLookupQuery("token", new TermsLookup("tokens", "tokens", "1", "tokens"))))
|
||||||
.lookupIndex("tokens")
|
|
||||||
.lookupType("tokens")
|
|
||||||
.lookupId("1")
|
|
||||||
.lookupPath("tokens")))
|
|
||||||
.execute().actionGet();
|
.execute().actionGet();
|
||||||
assertThat(response.isTimedOut(), is(false));
|
assertThat(response.isTimedOut(), is(false));
|
||||||
assertThat(response.getHits().hits().length, is(1));
|
assertThat(response.getHits().hits().length, is(1));
|
||||||
|
@ -89,11 +86,7 @@ public class ShieldCachePermissionTests extends ShieldIntegTestCase {
|
||||||
// Repeat with unauthorized user!!!!
|
// Repeat with unauthorized user!!!!
|
||||||
try {
|
try {
|
||||||
response = client().prepareSearch("data").setTypes("a").setQuery(QueryBuilders.constantScoreQuery(
|
response = client().prepareSearch("data").setTypes("a").setQuery(QueryBuilders.constantScoreQuery(
|
||||||
QueryBuilders.termsLookupQuery("token")
|
QueryBuilders.termsLookupQuery("token", new TermsLookup("tokens", "tokens", "1", "tokens"))))
|
||||||
.lookupIndex("tokens")
|
|
||||||
.lookupType("tokens")
|
|
||||||
.lookupId("1")
|
|
||||||
.lookupPath("tokens")))
|
|
||||||
.putHeader("Authorization", basicAuthHeaderValue(READ_ONE_IDX_USER, new SecuredString("changeme".toCharArray())))
|
.putHeader("Authorization", basicAuthHeaderValue(READ_ONE_IDX_USER, new SecuredString("changeme".toCharArray())))
|
||||||
.execute().actionGet();
|
.execute().actionGet();
|
||||||
fail("search phase exception should have been thrown! response was:\n" + response.toString());
|
fail("search phase exception should have been thrown! response was:\n" + response.toString());
|
||||||
|
|
|
@ -4,40 +4,7 @@ This document details the steps used to create the certificate and keystore file
|
||||||
== Instructions on generating self-signed certificates
|
== Instructions on generating self-signed certificates
|
||||||
The certificates in this directory have been generated using the following openssl configuration and commands.
|
The certificates in this directory have been generated using the following openssl configuration and commands.
|
||||||
|
|
||||||
OpenSSL Configuration File
|
OpenSSL Configuration File is located in this directory as `openssl_config.cnf`.
|
||||||
[source,shell]
|
|
||||||
-----------------------------------------------------------------------------------------------------------
|
|
||||||
[ req ]
|
|
||||||
default_bits = 2048 # Size of keys
|
|
||||||
default_keyfile = key.pem # name of generated keys
|
|
||||||
default_md = sha256 # message digest algorithm
|
|
||||||
string_mask = nombstr # permitted characters
|
|
||||||
distinguished_name = req_distinguished_name
|
|
||||||
req_extensions = v3_req
|
|
||||||
|
|
||||||
[ req_distinguished_name ]
|
|
||||||
0.organizationName = Organization Name (company)
|
|
||||||
organizationalUnitName = Organizational Unit Name (department, division)
|
|
||||||
emailAddress = Email Address
|
|
||||||
emailAddress_max = 40
|
|
||||||
localityName = Locality Name (city, district)
|
|
||||||
stateOrProvinceName = State or Province Name (full name)
|
|
||||||
countryName = Country Name (2 letter code)
|
|
||||||
countryName_min = 2
|
|
||||||
countryName_max = 2
|
|
||||||
commonName = Common Name (hostname, IP, or your name)
|
|
||||||
commonName_max = 64
|
|
||||||
|
|
||||||
[ v3_req ]
|
|
||||||
basicConstraints = CA:FALSE
|
|
||||||
subjectKeyIdentifier = hash
|
|
||||||
#subjectAltName = @alt_names
|
|
||||||
|
|
||||||
[ alt_names ]
|
|
||||||
DNS.1 = localhost
|
|
||||||
IP.1 = 127.0.0.1
|
|
||||||
IP.2 = ::2
|
|
||||||
-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NOTE: The `alt_names` section provides the Subject Alternative Names for each certificate. This is necessary for testing
|
NOTE: The `alt_names` section provides the Subject Alternative Names for each certificate. This is necessary for testing
|
||||||
with hostname verification enabled.
|
with hostname verification enabled.
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
[ req ]
|
||||||
|
default_bits = 2048 # Size of keys
|
||||||
|
default_keyfile = key.pem # name of generated keys
|
||||||
|
default_md = sha256 # message digest algorithm
|
||||||
|
string_mask = nombstr # permitted characters
|
||||||
|
distinguished_name = req_distinguished_name
|
||||||
|
req_extensions = v3_req
|
||||||
|
|
||||||
|
[ req_distinguished_name ]
|
||||||
|
0.organizationName = Organization Name (company)
|
||||||
|
organizationalUnitName = Organizational Unit Name (department, division)
|
||||||
|
emailAddress = Email Address
|
||||||
|
emailAddress_max = 40
|
||||||
|
localityName = Locality Name (city, district)
|
||||||
|
stateOrProvinceName = State or Province Name (full name)
|
||||||
|
countryName = Country Name (2 letter code)
|
||||||
|
countryName_min = 2
|
||||||
|
countryName_max = 2
|
||||||
|
commonName = Common Name (hostname, IP, or your name)
|
||||||
|
commonName_max = 64
|
||||||
|
|
||||||
|
[ v3_req ]
|
||||||
|
basicConstraints = CA:FALSE
|
||||||
|
subjectKeyIdentifier = hash
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
|
||||||
|
[ alt_names ]
|
||||||
|
DNS.1 = localhost
|
||||||
|
DNS.2 = localhost.localdomain
|
||||||
|
DNS.3 = localhost4
|
||||||
|
DNS.4 = localhost4.localdomain4
|
||||||
|
DNS.5 = localhost6
|
||||||
|
DNS.6 = localhost6.localdomain6
|
||||||
|
IP.1 = 127.0.0.1
|
||||||
|
IP.2 = ::1
|
|
@ -1,19 +1,21 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIDATCCAemgAwIBAgIJAKpUXNetXSgGMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV
|
MIIDizCCAnOgAwIBAgIJANif+/9AeRBYMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNV
|
||||||
BAoTB1Vua25vd24wHhcNMTQxMjE2MTY0OTE1WhcNMTgxMjE1MTY0OTE1WjASMRAw
|
BAMTGXRlc3RjbGllbnQtY2xpZW50LXByb2ZpbGUwHhcNMTUwOTIzMTg1MjU0WhcN
|
||||||
DgYDVQQKEwdVbmtub3duMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
MTkwOTIyMTg1MjU0WjAkMSIwIAYDVQQDExl0ZXN0Y2xpZW50LWNsaWVudC1wcm9m
|
||||||
ud/8Cbdao73CWXX4hP5yIOAvxOz1CSJN4RukrZz8EDqf2ZO5dcsceA0hSNbjjuxI
|
aWxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2g9jTDeAZMjXygm4
|
||||||
6sck8BlbAWGRLpg0RK6ObzyrQi6O56NxQlAazl95dE5to2rD4rcoWzp8uncfXjH/
|
Cb9CkBhSGN738ZOBiTGDH0q/3inE/qKJj/SF6RjHrVx5v9QUlqVTBX/NPd0VSFy7
|
||||||
6ix1z1Ph8HUJyWpZrciZa1KEotyElUhoVRkI8n956ayi6VFejRQOVFcByozr8jyM
|
jbYtab8mlaYEAhatYQhHlEjcre1hjK3MW2oHhk+T9ScnIBeArBjUSUzwPAUM8FOj
|
||||||
bgnvVUnaitkAipohNiOybrSgz/rNI+fZykoOz0OcmNGJ4saDuaIn/EW8ZazUUxPL
|
0qGSK6QifrCf/5dQyq9D1WynwhGwUqp3WcZEvvaEl66QnBugViY7JRsuWOfIiJ7j
|
||||||
Z7CsuLe3a7cIe4aK7vgSGP67EDX9ORTakABwMhmoPPNh2oroRrnJQmEQcbAFnIgO
|
xkFv74Qm3yfCpQR+5TPAWd2ipRZZinwn9M0u0txiffZo7jemdpK5aiNAgJCGn/Sw
|
||||||
qt0xP/pldehgPBLBt9SHKQIDAQABo1owWDAJBgNVHRMEAjAAMB0GA1UdDgQWBBT/
|
jlOzFU5pKxIIHeaR3rLWZ4P0WgMu+kqVPoy66UKBA6kXK4eMk1Wla7dG1gtp+OmQ
|
||||||
avMSDSZe+l3YAR2lvD86cET4/TAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8AAAGH
|
TQGqhwIDAQABo4G/MIG8MAkGA1UdEwQCMAAwHQYDVR0OBBYEFGgAgQUFrcvEOeed
|
||||||
EAAAAAAAAAAAAAAAAAAAAAIwDQYJKoZIhvcNAQELBQADggEBAJMF8pEdDAkJlQ8g
|
swWf+D5DRoj9MIGPBgNVHREEgYcwgYSCCWxvY2FsaG9zdIIVbG9jYWxob3N0Lmxv
|
||||||
E3BC41JcmkXYZbv7uieF7088kW13UzJhKMS1c0GOyMM0QKqj+Xt7WMcv0TjNPGtk
|
Y2FsZG9tYWluggpsb2NhbGhvc3Q0ghdsb2NhbGhvc3Q0LmxvY2FsZG9tYWluNIIK
|
||||||
xs4kmcgyQzITdbu3Wri9xARdgtl2roC/KUzqygLk6h+yKECpDBEMRSgR9eO+Kha2
|
bG9jYWxob3N0NoIXbG9jYWxob3N0Ni5sb2NhbGRvbWFpbjaHBH8AAAGHEAAAAAAA
|
||||||
EJo0kr4IW4hqKrhncxM7YKKjSMgGcD+QdZNAQkY0Jk7JvzDzvGxiBYzJbHB3Ye6c
|
AAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQADggEBAKrKuUTmZ3WymiG6jRhLA5DA
|
||||||
cb/Uz5ydk0unCACOlrPjOLRBY4EW08tCgFJBUSTjWJjSnrJxvo6kr/dFq2YksfUs
|
36k7Hey8rvHZ6wbdnUseO+JJbItGEoEd0Js2syjghOnMf+M686prv0tWpaqA3ySh
|
||||||
c6a3e6vUoG5JXqIK8iIn3MnF5RLwQjMG0KSUCMRnH8wkzWx2yPv+urvUixIs+vbV
|
uEcKSwy063eMmmTPXR9HfEK/QkdfC6otOvR/elgs1t0R45JFbHWSS1tJLOU/HU2i
|
||||||
hTWLIhU=
|
3jwqy8Gwp+XJG9yrwC4OsJ1pAp7vCIoXrcq6glueiq9vjdAMYCtlrNIlDhmB+rYD
|
||||||
|
K8mf4S1AygSsZNUmh04oj8kBRacH4vdoKYkxvixPvo1F5VaoJcr+hh2xL4AyuqLc
|
||||||
|
gdoJmOv6Fk2UCUI2aI4nn0pXwkyOlx0t8B3Hp/TZY2Yn0x+uIIkKGJRm0CuKzNQ=
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,30 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: DES-EDE3-CBC,02BA9C3E433F0711
|
||||||
|
|
||||||
|
M3Ds1K8/cp5v9BKj9SstoXWlyj+CmasLfvPlz6O5Ootdai/wTirhxyAcYcsgjuQA
|
||||||
|
FIMuQiAaKC+W/DOP52+ilY3FZKw09DptdkaU7IFvSQvJ5SeiJIGLZ9REUWIPwRKV
|
||||||
|
qCHpKFCS4//mitnykjSu2HhTM+BjbXuytLJtxFJuodr8YhJGgtwfETAmbVlwWG3M
|
||||||
|
mhEsfdr0kOJGwT/z3dZbCxnGkjOY1FZCdMU/ggeYx93NP0c4yzNU6/A0idZRMlHE
|
||||||
|
BuSIkDhn3BXxgxYxTOgHzCkxaZ0T7kNv0MvTXrrcQf2WrMaG1FfTzCzF78YDBn7+
|
||||||
|
kg5HI8wfxjGjDTnHH9KSuN5gi14DiEEUN45Ba3ChH75SjGwBbUjnHsGIp6Ch8mh8
|
||||||
|
5ZgldgUOff0atEBaMpvoZAzxGbY5PhC5/Pfiq+enzvmICxszFNIRMhhLxWWBWuH9
|
||||||
|
v04OOKZJ4v+ygZHvPJEFNc/XznGb39ELn4Y6P26fqNfPmv5/yHcenQPNZgGkKQEJ
|
||||||
|
SYTPxct+yDi3lul1WBPrvZwCOAjUtcCf4tBC6uOqlRjd7VREk5hKUlXTtxJLbaoB
|
||||||
|
FH1VKn9xZITBqk3g292KGbpZsGP5HtYAbB/gJUcOXZZbr8blMmpeIXXFWfPbvUcv
|
||||||
|
d1fokqHSrlclNt+h2pENqjJTc2iKKKlkNY0ol+cDej7fOgNH0sNOjuESrofdaXfa
|
||||||
|
4CPuvMxeQFKnjQFBLM14CFUyseZsAqnLjneUnk5qTPE5twCN0pkJx0y095pEGdrF
|
||||||
|
2UQ4HfdghnKxWQK50iGUhCgBfqeI3O3cfi76ZdeJYM+7CluGNb/0sybjF6kNiAME
|
||||||
|
m5PfaSXk7A+a/FteFThW52E8W8Sekf2/lOMdbdQa26/oUfcMWzBj+aMcJBwcOaq4
|
||||||
|
lIY6IPHySQIakLGCLLOkYHAG+Kp8AldjcwfpOZ3Jk1HrjOmx9CfonXvdVQmS2BQZ
|
||||||
|
8+V2ECd0uw9EbD+i4VIIHy6H1a57W9gikshXsv4K5vQsl0s6GjbioN1JFFC78XKS
|
||||||
|
XohDMDmR2Ty3LU9TLoS9K2fLcgtoJmnEtJ1cs5Cw9+T1s+ILFgoBTXzePnDKK78T
|
||||||
|
4uNw7a8CRAKW++dHtwHEnHOIDJ0rx+4Y+V7e5Cr0nT4Idv5P9xe9knTghb34vwBw
|
||||||
|
SBfEn0sCQoly4DGsKlPz8xhLRCX7euXsbPcTy3owpTFywJsfjR5e/jtxa6C5NmNI
|
||||||
|
LmGJb6TpsAl9mULfSRlGjynqU9T0EzOdcbPs8z1cLFQl7QRi63tlZ9jWh+7eV+dR
|
||||||
|
NaN6f0jY0me0D7OzvoD19e3ESFARV7MGQ5U0OaZOAcLdx3CYjs777AQ1S2q6ra+p
|
||||||
|
gr4oqenWqYkbY8/z8AALiWPO59Rl00GcUJqwYXlJANCtK4ikwQPG2+YIYrclBW/d
|
||||||
|
ZQplHShy0AayYPguLI9ts0XLulIrcsJ0zlEDPf3b8+Gr6yONiYpOtA0ZtwE3w+Q5
|
||||||
|
5byhoYoBQPtLXyLff31ozRs/MhJd8+gIIReKSE5sGMwbVX2ZfjWOXzDHp6+CQIKD
|
||||||
|
OhIfgnyG6tPQ2N4DhSrE/cEITPlSOv55NUnLQUCgfAHvAslgWwmVDk1ikznij/Zj
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -1,21 +1,23 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIDcTCCAlmgAwIBAgIJANA/+zUU47fOMA0GCSqGSIb3DQEBCwUAMEoxDDAKBgNV
|
MIID1zCCAr+gAwIBAgIJALnUl/KSS74pMA0GCSqGSIb3DQEBCwUAMEoxDDAKBgNV
|
||||||
BAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEiMCAGA1UEAxMZRWxhc3Rp
|
BAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEiMCAGA1UEAxMZRWxhc3Rp
|
||||||
Y3NlYXJjaCBUZXN0IENsaWVudDAeFw0xNDEyMTYxNzAyNTRaFw0xODEyMTUxNzAy
|
Y3NlYXJjaCBUZXN0IENsaWVudDAeFw0xNTA5MjMxODUyNTVaFw0xOTA5MjIxODUy
|
||||||
NTRaMEoxDDAKBgNVBAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEiMCAG
|
NTVaMEoxDDAKBgNVBAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEiMCAG
|
||||||
A1UEAxMZRWxhc3RpY3NlYXJjaCBUZXN0IENsaWVudDCCASIwDQYJKoZIhvcNAQEB
|
A1UEAxMZRWxhc3RpY3NlYXJjaCBUZXN0IENsaWVudDCCASIwDQYJKoZIhvcNAQEB
|
||||||
BQADggEPADCCAQoCggEBALceMGq3C3QP6uuCE/93MlwDP3NBVwl5eNL3JvygwQoU
|
BQADggEPADCCAQoCggEBAMKm+P6vDAff0c6BWKGdhnYoNl9HijLIgfU3d9CQcqKt
|
||||||
YpoABTU51+3JWjHkWxMbinUFEQV67EMa+5Uja8m39MoHC2hlTuECufe17bAFN23I
|
wT+yUW3DPSVjIfaLmDIGj6Hl8jTHWPB7ZP4fzhrPi6m4qlRGclJMECBuNASZFiPD
|
||||||
SE/x8qaBPECvjR1Rf3Dt+rfJ7/n76aObIt7exsR1uxB/O2eRMNGXZSCsQrQy+n/o
|
tEDv3msoeqOKQet6n7PZvgpWM7hxYZO4P1aMKJtRsFAdvBAdZUnv0spR5G4UZTHz
|
||||||
T45gFDkY1CeMthsUxj4TkmeHK+wcDx00Te1mfA4J3Ef5ykIxAwDJxEBIaqGAv077
|
SKmMeanIKFkLaD0XVKiLQu9/z9M6roDQeAEoCJ/8JsanG8ih2ymfPHIZuNyYIOrV
|
||||||
+02RdG1IHGEvJeTGwZ+GFem9U8zF3UVBX/jyqHY82YyBaXrwjlhDz4dmHVqTVQYC
|
ekHN2zU6bnVn8/PCeZSjS6h5xYw+Jl5gzGI/n+F5CZ+THoH8pM4pGp6xRVzpiH12
|
||||||
Qn/SkrQyJknggnWCrCoGS31GfKyFbmrUWjhAtVkreRkCAwEAAaNaMFgwCQYDVR0T
|
gvERGwgSIDXdn/+uZZj+4lE7n2ENRSOt5KcOGG99r60CAwEAAaOBvzCBvDAJBgNV
|
||||||
BAIwADAdBgNVHQ4EFgQU4QdRaaIGD6uyQk/WiwEtExBI7hgwLAYDVR0RBCUwI4IJ
|
HRMEAjAAMB0GA1UdDgQWBBSSFhBXNp7AaNrHdlgCV0mCEzt7ajCBjwYDVR0RBIGH
|
||||||
bG9jYWxob3N0hwR/AAABhxAAAAAAAAAAAAAAAAAAAAACMA0GCSqGSIb3DQEBCwUA
|
MIGEgglsb2NhbGhvc3SCFWxvY2FsaG9zdC5sb2NhbGRvbWFpboIKbG9jYWxob3N0
|
||||||
A4IBAQAexhtJBZ2jQrJ1M7HRFCFRVP6oi/5D139/0t8qG9KL9oQXlY//gQweSPk9
|
NIIXbG9jYWxob3N0NC5sb2NhbGRvbWFpbjSCCmxvY2FsaG9zdDaCF2xvY2FsaG9z
|
||||||
gCPywfQjBfY6Fck2iliCw6YR3K/Bax9lOX/rKJ/jWrcUUBKzP9ap8ijKa/1EJchp
|
dDYubG9jYWxkb21haW42hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3
|
||||||
VVf7M2g7V00pSR63fl+EnMzv8H/uTK4BMWiE9sl01oK/kyVDR/wd/GktnQpZYF5B
|
DQEBCwUAA4IBAQANvAkddfLxn4/BCY4LY/1ET3d7ZRldjFTyjjHRYJ3CYBXWVahM
|
||||||
5FvuMi2ocM+hSpbejLVi4yW6/wN6rcjofon/u3ngzicwou59r99IavlW/qk5DHbI
|
skLxIcFNca8YjKfXoX8mcK+NQK/dAbGHXqk76yMlkrKjh1OQiZ1YAX5ryYerGrZ9
|
||||||
HD2pK4tOqQX06pzdc8MHKQ16JxSt3dk/aljmvDUf93e/KNI9RSoZpydBqXlpaACi
|
9N3E9wnbn72bW3iumoLlqmTWlHEpMI0Ql6J75BQLTgKHxCPupVA5sTbWkKwGjXXA
|
||||||
52lEcHwQJVoe6L5VdHc6090U09K7
|
i84rUlzhDJOR8jk3/7ct0iZO8Hk6AWMcNix5Wka3IDGUXuEVevYRlxgVyCxcnZWC
|
||||||
|
7JWREpar5aIPQFkY6VCEglxwUyXbHZw5T/u6XaKKnS7gz8RiwRh68ddSQJeEHi5e
|
||||||
|
4onUD7bOCJgfsiUwdiCkDbfN9Yum8OIpmBRs
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,30 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: DES-EDE3-CBC,C98A45E4AFC263C2
|
||||||
|
|
||||||
|
wLuUEXldYc54r4ryWd6jw6UMGYwn6+ibGKHp4sD92l42lmI2UrCT/Mb/E0O+KMMy
|
||||||
|
pHgc5/dBWkXgMiqDyLIhHk4kgT40rdw5W5lZkAA4Qt/Yzd+rbscTvzp09zrF6Fll
|
||||||
|
czgoE7FrvhOKiEOakerTit4pIPYosdX606cpVQE2lq9oZs9HVMcLzdAZj8A/P/4g
|
||||||
|
fo4X3+zqVYC/LH4n00bhNoeeej2o1lEJ+l9u9hptT2ATXle6pANa83Ldg4OxJyj8
|
||||||
|
dkR9ahnAMCvYTSjEU7nwmGNPeFX0PIUjJKQivr410cYG104DC30Yy+XrIUfjTVUi
|
||||||
|
agwlMpHoBq79/ZRUJR3xPLkIGgw4g+RPt45D9eKsEsV4vqy8SFlgaoJ2mKUKleZy
|
||||||
|
i7D9ouzMKQ3sYE4eQVQ5o3K8ZPn5eozCwCVIp7jGSsuvDpLA9peZSwWPfc5y8JFD
|
||||||
|
/64usCt1J8Mv/e9NVllC8ZA+ZmDitTiwLZysczpMOaFqqeUbk9EJst38n4nBzRV2
|
||||||
|
quxvg9W/iveQIydFyftCtNfRkpbp0NCsLz293dBYwZacHsPcY27IBCwXHiICjiAW
|
||||||
|
q7bnisXsgSaQMhMNRGW9YElZGb7ZWxoIzcyNBisGI8zxn48ObERVOmkOFxY/gs9T
|
||||||
|
YmpVMliWtmRG6hb6iCh9b7z8THRquxgTGE9ZFBwtLUKg33aubtgAfnUh/Xq2Ue5K
|
||||||
|
l+ZCqDGEi/FSIjVENUNNntAx/vXeNPbkoGLb/HSJwAh+sjpaLGQ54xixCtE9l3NY
|
||||||
|
o2QAiZ804KLPaGtbbOv7wPumxQ+8mxG5FN0hTRrsMW9t8pBXw47iMy/T2H21TD5D
|
||||||
|
E5XbM6kFeBrnsWnZJ2/ieXqDE4SX0tm3WEvZlDg7N7jV8QDM/D3Xdkb/sqJRabMG
|
||||||
|
tQRgwkLiB+mZ5MAfGLogI2/lOEayrBVz4qYdXojewxY4LtaZ5HiUIlyA9CJelMvD
|
||||||
|
nS52I6+FpaFhvuZC10qaM9Ph9TNyx+XKRUsPILuDiBRnYiHUKs1qASl5tjn2yyjM
|
||||||
|
71WSo7A7btOckzhDZdMVf1T472f0LGsRYoQebMhotqCuR7yArZHzTeWB0CjL3tOz
|
||||||
|
j3QlhKt2E1jx43bSK5tBasd9Bpmn2onvdwu1RRP8cyQBsXJSDy4/8t/g63+C3wod
|
||||||
|
8VPrlKhK+TenK9EoEqJ2mNuNq+duOjTXfK/7GM5s0BFKv+i2ckpDi1NPckd2gXjF
|
||||||
|
yUFZhmK6k0WC4jjWloMt+WQpi1rXMEXwCypgTrqWbvD0p6+X3uQmP57L4yHQcZoW
|
||||||
|
Qcs5GnihJ0DIhw9vYDhBhNo0WY1oBO20nVCN3R/JIpp3uDtg64WvfvMSXzJIPBCY
|
||||||
|
s+/GM5TtuD6mERDu3+qXxWwiy4PMQRcgjRTMEZ3A4Iv77YfQRkcd6S9qjUUuR/5D
|
||||||
|
xs+J4ryb1biz9ofW7I+Dbz4SArWSgwcuh14AV9RBv6Rh9m83rjT2K0yvbe/+7hHW
|
||||||
|
R8nzRMqJcGNGCHmRjA/cwoiv6+k2J/RbCJqnR3RmNex/85XaXBfZwRfHXVbzZQfa
|
||||||
|
SrFaaNLf1hMwGLAJjIcQRxa3yZbjFXVx1Bp4hh8rKNWaOItjavNtNg==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -1,19 +1,21 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIDATCCAemgAwIBAgIJAJeYaRLTW4+8MA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV
|
MIIDhzCCAm+gAwIBAgIJAMDqQhbo/w/YMA0GCSqGSIb3DQEBCwUAMCIxIDAeBgNV
|
||||||
BAoTB1Vua25vd24wHhcNMTQxMjE2MTY1NTUyWhcNMTgxMjE1MTY1NTUyWjASMRAw
|
BAMTF3Rlc3Rub2RlLWNsaWVudC1wcm9maWxlMB4XDTE1MDkyMzE4NTI1NloXDTE5
|
||||||
DgYDVQQKEwdVbmtub3duMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
MDkyMjE4NTI1NlowIjEgMB4GA1UEAxMXdGVzdG5vZGUtY2xpZW50LXByb2ZpbGUw
|
||||||
rQJqeEjkzz0VaxzvApx5CFTFNm31tKtYQrs3hKJmuVNBKOmj6NpKN3e/JSp9e9YA
|
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDh9VWS5kI7Sf1tJSCP3F+l
|
||||||
N8cylF5btGGEDQLufWdiwmPcWMH5yFBiMQZqAMPIseO5XSkqIf2QB6VJ676JiwSL
|
F1Ve2w9GgoRYjOz7jTWm8h8WPoMSGoCIEQqxm+Eo+AGCd58tacKO4ANxZbjh33hP
|
||||||
Hi2mfeoX8l8Kor2ZKaoUNQMHBUIupyBWUyXq6d9Xxtq/P2IGtbOABPzxQDjCvwFs
|
7bh7jYmj3qDZlwnTaM4RIvzPSgYzlgx7iBWXJZoxWi9jlEBehg/bB6+2tK0/4CJJ
|
||||||
wGZtkDMsYCaMsHlMNBbc1JhX9pKRmbUHCMOnoQpxSJdEbi8radH+6SPRE0Hjf1Sh
|
27Xi2cjJDTcctyLEhuQEH6oLf0pBfK2UXv9LkoOkrnRzY+x4YBOlrPmho+5jU2iw
|
||||||
eki4l7dpI7Za599ffR5XZXtddPswK3yUDxJ7Ci1WzUeVoj5eeWoPUpSs6vdp671I
|
5DnFNKw4Cxdd9XnDpAprU2E02pCXN3mpcvDk2MdnzWvDh14j1eisxmAl7wbU5fdF
|
||||||
ysuklEop7h2h9nTQ4psj7wIDAQABo1owWDAJBgNVHRMEAjAAMB0GA1UdDgQWBBT4
|
P50v5m8cOPreWUlS2WYIJ+nHLnbnmVE8F2FpXDupF5WK5BU/QHVnE6i5kwvMITsJ
|
||||||
fb9ffBf0NdyQzDzzaQk97cFceDAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8AAAGH
|
AgMBAAGjgb8wgbwwCQYDVR0TBAIwADAdBgNVHQ4EFgQU08G5lM8hL/8f61uAkl3n
|
||||||
EAAAAAAAAAAAAAAAAAAAAAIwDQYJKoZIhvcNAQELBQADggEBAAv4PFpgJnzNm/38
|
vJzyEv4wgY8GA1UdEQSBhzCBhIIJbG9jYWxob3N0ghVsb2NhbGhvc3QubG9jYWxk
|
||||||
6ps1e8tdMMW+Luoz58UJpax5ysKfFdAkinKiR5YbUIFouLXHUHWvTVOUcUkGRkxy
|
b21haW6CCmxvY2FsaG9zdDSCF2xvY2FsaG9zdDQubG9jYWxkb21haW40ggpsb2Nh
|
||||||
ge2alErk1ai7xvqGR+GwweoF52yAI/P6fBcStll1ZcjtfRxWyyLceBkctIbftosb
|
bGhvc3Q2ghdsb2NhbGhvc3Q2LmxvY2FsZG9tYWluNocEfwAAAYcQAAAAAAAAAAAA
|
||||||
+l6IfWNlScR71R/BtlZ+3SVpBfxHGf/SKjyrt4zUb/8DHmGhNJYwaKCNqOS6rRlO
|
AAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAQEAq84Eku8yLOcaxfBb7pHWaHHsaxXZ
|
||||||
DzKpysVXjcbWS3ljf9ZIxOhEoERc1RLhkcvjHz49UOw2F3o21529wlB08pDumr6W
|
k1lK3SZm49VTuwtMrGCYY7TBt4Kz1mnpQZd9KVyE4BzhpvUmD2ybSsyK/w1nYGVw
|
||||||
TvJY9lB5b1mJ+MoHFxudDoiA0iqNPVMHWJz2EJrJX9skCLZRJSkPzQIG3IIeVxRO
|
VyFEnutlIsYWs4rWwrvYoX1/B86WvNMBa+XFBnlO0HR5yTc/m5LKkNsZ3p2CGPfN
|
||||||
dF+PXJw=
|
PCaok0NwS7cKIsWIgBaFlIYMYjZM+cL5qAWeOOgQoxPKi5uzZ/YqJbWf0jwpA/8s
|
||||||
|
M9QuqJzJMSGvwn0i74ulbubjnit2dMbrUUm6W65snw5qLDSqZzDH02EYYG4yMkmP
|
||||||
|
/S/SZFvw7fuOHFeJBoO3oej+ilEuYPkjkysr3Ys6xmprqExdDHUMElEycA==
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,30 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: DES-EDE3-CBC,AA1E05F81F24B5E3
|
||||||
|
|
||||||
|
Axn5ritl59GJQ4PLJDIk/IRvYSPsk+5JygqjZc4oeewhpbWqOjzVYROMD65DqN4k
|
||||||
|
sZw9vhDSm8TjhmuMWP+n1oJWZtAEKBcXbAhoG8lErsJPYx5xq9SYrbK6LWXYlVN2
|
||||||
|
fbf5o77vQDqLiZf2QeXyufgLbEZ7yslYPBSMiOQfp2jwpHOQrlWIg7awheTpd8Dv
|
||||||
|
PQ/Jy45mGJ2gl5n1Yn+nZbIO/S+3Wy0AX0MmS7nBU4ogOkIMq4ZBFALnfmcdGZHJ
|
||||||
|
pfi2riNF6lTeMgHrGtCRY3yp9Hyu0Ve/2fYdfECcG2BUQ0TweZynMqE3kJokwwC6
|
||||||
|
ua3T3WBnQws1MYxvYjy8WaSriuAfNvnu80rdiJRRcp8wBjbSYrxHq2BtYMrVuekt
|
||||||
|
lFdDCBAnmbTzYVFCez4K5l1Tbd0ilc7D8dFhHP07dkkcm57P2cm3u76O0pIqjzEx
|
||||||
|
DvYs33vdxiFq4Z4QPDbFh6Xz9uaDhy1gxlm8/giHd+JBPJlcoHD5C2Wtd0pI0tz/
|
||||||
|
5n1bdFeejqItmfy45IFFrRn/jb7Q59olVNSbWH9RojLx9HQct4w6MScmv8n8J/r9
|
||||||
|
PUrapSwwLEV6lYDBMsO5RXXDDUTJHcXVbr1nuU6BTCTTe1nMIK1+8pS1m4Cizjcg
|
||||||
|
9J3FWLktCqiCx8NI9O/QzIsbyA6R/NjmvYPOx0/nqtMCPNYJHuZyExMiVMMaPNly
|
||||||
|
Ic0HfnZyiwJPj52l67xzm4KwJH57piwldRGjVCj7IkVbHs2MRVsT0+j/QKGSU0uY
|
||||||
|
DTHIOSToCrzorh0j01fmG4zpMFkU/rtCmT3STkSFdsEsy9EORGx2C9t4mVth3V6e
|
||||||
|
Rc0y9TUcKGdtW13OiZN4o12aToC7yhg0aIpseWm8I0nnRg/TVtzoltOv85I0Lelr
|
||||||
|
vcQ8/jZ5Go8JZbTrMFmCdIPYvx+m7lL7kGx9Zt3hDpj+EBm0g5Gp44KUkxtI7Bs8
|
||||||
|
1sUvSTyNKW8mixkiS4Bq4dGDqHIuvwW1x9PVoJODbHzTip5aAzJWmXA5rOxVp2kz
|
||||||
|
keA73TUpJo2UZkME8SiDGVlcnZAGx0odxe1tMBkc2GPpQVmz8Xmi75aEuvzBlAEh
|
||||||
|
2LWGnBhgN1T6cwvkJKgdbVHUlt3fUIPHzZhItMKrPbATMl5Rtf8Fkj4TYGvoxJZh
|
||||||
|
QPLuD7ngTORv84W0xnxlt2KO8hEkpKjTImu20n4FIb/YPlVxbYULnt9xRl/QaEol
|
||||||
|
7jjpZJ7zmuZBAEevOlQk/Jc05TbdttPoWU6zVsSswjuAn3lVRIK9Ad0iXzPDWkWU
|
||||||
|
Du41QXpkCXCoIdky1WZjmZPqLd/nnSdKSBt52ZtMimFix7uer/u9f+933lETSK7U
|
||||||
|
ImUFAP/pnlmCzll1Rmublb+WDyFV2lIZ2rZURIQUuQMCCcAFo9XmWgdTjJAOUdwX
|
||||||
|
qLvYUNIVb2B5uAUgm8Wn/vxUW04Jn1aQrPSPGBCo9KSy16DbkslSWpJeCHwS+FBP
|
||||||
|
Z8CedsnajbUnAa3HebykjlhOkob7wTCogzLjaPj07XYa/O2Dwmiv1GOnXrdie9Wi
|
||||||
|
ul0/CAm53ZtLOrgHmi1cPq9FtYAYJLboLu7eW2jZz2MjcugGG+0eGdzSoKSfWfOX
|
||||||
|
-----END RSA PRIVATE KEY-----
|
Binary file not shown.
Binary file not shown.
|
@ -1,21 +1,23 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIDbTCCAlWgAwIBAgIJAJ+K5mGS3n/AMA0GCSqGSIb3DQEBCwUAMEgxDDAKBgNV
|
MIID0zCCArugAwIBAgIJALi5bDfjMszLMA0GCSqGSIb3DQEBCwUAMEgxDDAKBgNV
|
||||||
BAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEgMB4GA1UEAxMXRWxhc3Rp
|
BAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEgMB4GA1UEAxMXRWxhc3Rp
|
||||||
Y3NlYXJjaCBUZXN0IE5vZGUwHhcNMTQxMjE2MTcwNDQ1WhcNMTgxMjE1MTcwNDQ1
|
Y3NlYXJjaCBUZXN0IE5vZGUwHhcNMTUwOTIzMTg1MjU3WhcNMTkwOTIyMTg1MjU3
|
||||||
WjBIMQwwCgYDVQQKEwNvcmcxFjAUBgNVBAsTDWVsYXN0aWNzZWFyY2gxIDAeBgNV
|
WjBIMQwwCgYDVQQKEwNvcmcxFjAUBgNVBAsTDWVsYXN0aWNzZWFyY2gxIDAeBgNV
|
||||||
BAMTF0VsYXN0aWNzZWFyY2ggVGVzdCBOb2RlMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
BAMTF0VsYXN0aWNzZWFyY2ggVGVzdCBOb2RlMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||||
AQ8AMIIBCgKCAQEAzhpW7iwkm+Og+HP7U00nbmh0Hy9Z2Ldp5i8tJSlSQwTxCCvO
|
AQ8AMIIBCgKCAQEA3rGZ1QbsW0+MuyrSLmMfDFKtLBkIFW8V0gRuurFg1PUKKNR1
|
||||||
rse6jwJQN98Dk1ApaSzimZrlKOotFyPV1L3fnOzJbTp1Yq/VsYP4zJkjWtID0qUf
|
Mq2tMVwjjYETAU/UY0iKZOzjgvYPKhDTYBTte/WHR1ZK4CYVv7TQX/gtFQG/ge/c
|
||||||
8Rg8bLhjKAG+ZlLuai5XZqnLkdmqvQeR61VhpXWFm0Om153tWmAiHL18ywY71gXN
|
7u0sLch9p7fbd+/HZiLS/rBEZDIohvgUvzvnA8+OIYnw4kuxKo/5iboAIS41klMg
|
||||||
EnkeFo9OW4fDqkz6h7NJziYvU6URSKErZDEixk5GIPv9K9hiIfi0KQM6xaHp0d2w
|
/lATm8V71LMY68inht71/ZkQoAHKgcR9z4yNYvQ1WqKG8DG8KROXltll3sTrKbl5
|
||||||
VCyFVC0OUdugz6untURzJVx4U3X1bQcv/o2BoUotWh/5h8o5eeiiv2OGZ1XlO+33
|
zJhn660es/1ZnR6nvwt6xnSTl/mNHMjkfv1bs4rJ/py3qPxicdoSIn/KyojUcgHV
|
||||||
1tweYI4wFjDwnAyHHRr/rk2ZIBiBYGaSzHnuhQIDAQABo1owWDAJBgNVHRMEAjAA
|
F38fuAy2CQTdjVG5fWj9iz+mQvLm3+qsIYQdFwIDAQABo4G/MIG8MAkGA1UdEwQC
|
||||||
MB0GA1UdDgQWBBTwGg2LF8+mzsvBBWxJKv6VXv3dMTAsBgNVHREEJTAjgglsb2Nh
|
MAAwHQYDVR0OBBYEFEMMWLWQi/g83PzlHYqAVnty5L7HMIGPBgNVHREEgYcwgYSC
|
||||||
bGhvc3SHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAIwDQYJKoZIhvcNAQELBQADggEB
|
CWxvY2FsaG9zdIIVbG9jYWxob3N0LmxvY2FsZG9tYWluggpsb2NhbGhvc3Q0ghds
|
||||||
ABP4ufLToJhcUselVxV9LPD5VGPEHGLdIFqsUEix7DMsiNpR76X6a8qNQbZpdbd6
|
b2NhbGhvc3Q0LmxvY2FsZG9tYWluNIIKbG9jYWxob3N0NoIXbG9jYWxob3N0Ni5s
|
||||||
+qPKqoaMgC7znX7qZtCqRbIXTWbudZPxFkcHdiWx3SiALMQYabeUGetClX3sCndU
|
b2NhbGRvbWFpbjaHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQEL
|
||||||
SUoV8f34i8dJxfNcqhLcsh4zpgxtmwsvs5OLMTBvm0Xo2zUFUjlmrt41pBrWEuq9
|
BQADggEBAMjGGXT8Nt1tbl2GkiKtmiuGE2Ej66YuZ37WSJViaRNDVHLlg87TCcHe
|
||||||
nkObc/cr6Syiz3sy4pYVJO1/YwHaZgE/URqjVlari70DR3ES4YnIUnLQajKx2Q0/
|
k2rdO+6sFqQbbzEfwQ05T7xGmVu7tm54HwKMRugoQ3wct0bQC5wEWYN+oMDvSyO6
|
||||||
gXVgzjbe68KPOUGCz6GYiWq+d4tcWdHzLv1GsaqQ1MD9P21ArfrX4DpzgPDrO6MP
|
M28mZwWb4VtR2IRyWP+ve5DHwTM9mxWa6rBlGzsQqH6YkJpZojzqk/mQTug+Y8aE
|
||||||
9Ppq5DQGa2q4mz3kipd5RIs=
|
mVoqRIPMHq9ob+S9qd5lp09+MtYpwPfTPx/NN+xMEooXWW/ARfpGhWPkg/FuCu4z
|
||||||
|
1tFmCqHgNcWirzMm3dQpF78muE9ng6OB2MXQwL4VgnVkxmlZNHbkR2v/t8MyZJxC
|
||||||
|
y4g6cTMM3S/UMt5/+aIB2JAuMKyuD+A=
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,30 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: DES-EDE3-CBC,9D867F7E0C94D013
|
||||||
|
|
||||||
|
dVoVCjPeg1wgS7rVtOvGfQcrZyLkx393aWRnFq45tbjKBVuITtJ9vI7o4QXOV/15
|
||||||
|
Gnb6WhXGIdWrzsxEAd46K6hIuNSISd4Emsx6c2Q5hTqWXXfexbOZBNfTtXtdJPnJ
|
||||||
|
1jAaikhtztLo3JSLTKNY5sNxd+XbaQyYVUWvueK6zOaIIMETvB+VPVFd9i1ROibk
|
||||||
|
Sgdtyj01KjkoalifqK/tA0CIYNKL0S6/eoK3UhAlpIprlpV+cnXa940C6bjLeJPt
|
||||||
|
PMAGGp5RrplxSgrSerw3I9DOWkHGtpqzIka3XneNUXJP8k4HUJ+aZkGH2ZILKS8d
|
||||||
|
4KMIb+KZSpHEGn+6uGccWLtZZmAjWJrDw56JbQtSHdRYLBRSOjLbTvQoPu/2Hpli
|
||||||
|
7HOxbotlvjptMunncq5aqK57SHA1dh0cwF7J3LUmGFJ67eoz+VV3b5qMn4MopSeI
|
||||||
|
mS16Ydd3nGpjSrln/elM0CQxqWfcOAXRZpDpFUQoXcBrLVzvz2DBl/0CrTRLhgzi
|
||||||
|
CO+5/IVcBWRlYpRNGgjjP7q0j6URID3jk5J06fYQXmBiwQT5j+GZqqzpMCJ9mIy2
|
||||||
|
1O9SN1hebJnIcEU+E0njn/MGjlYdPywhaCy8pqElp6Q8TUEJpwLRFO/owCoBet/n
|
||||||
|
ZmCXUjfCGhc1pWHufFcDEQ6xMgEWWY/tdwCZeSU7EhErTjCbfupg+55A5fpDml0m
|
||||||
|
3wH4CFcuRjlqyx6Ywixm1ATeitDtJl5HQTw6b8OtEXwSgRmZ0eSqSRVk9QbVS7gu
|
||||||
|
IpQe09/Zimb5HzjZqZ3fdqHlcW4xax8hyJeyIvF5ZJ57eY8CBvu/wP2GDn26QnvF
|
||||||
|
xQqdfDbq1H4JmpwUHpbFwBoQK4Q6WFd1z4EA9bRQeo3H9PoqoOwMDjzajwLRF7b7
|
||||||
|
q6tYH/n9PyHwdf1c4fFwgSmL1toXGfKlA9hjIaLsRSDD6srT5EdUk78bsnddwI51
|
||||||
|
tu7C7P4JG+h1VdRNMNTlqtileWsIE7Nn2A1OkcUxZdF5mamENpDpJcHePLto6c8q
|
||||||
|
FKiwyFMsxhgsj6HK2HqO+UA4sX5Ni4oHwiPmb//EZLn045M5i1AN26KosJmb8++D
|
||||||
|
sgR5reWRy+UqJCTYblVg+7Dx++ggUnfxVyQEsWmw5r5f4KU5wXBkvoVMGtPNa9DE
|
||||||
|
n/uLtObD1qkNL38pRsr2OGRchYCgEoKGqEISBP4knfGXLOlWiW/246j9QzI97r1u
|
||||||
|
tvy7fKg28G7AUz9l6bpewsPHefBUeRQeieP9eJINaEpxkF/w2RpKDLpQjWxwDDOM
|
||||||
|
s+D0mrBMJve17AmJ8rMw6dIQPZYNZ88/jz1uQuUwQ2YlbmtZbCG81k9YMFGEU9XS
|
||||||
|
cyhJxj8hvYnt2PR5Z9/cJPyWOs0m/ufOeeQQ8SnU/lzmrQnpzUd2Z6p5i/B7LdRP
|
||||||
|
n1kX+l1qynuPnjvBz4nJQE0p6nzW8RyCDSniC9mtYtZmhgC8icqxgbvS7uEOBIYJ
|
||||||
|
NbK+0bEETTO34iY/JVTIqLOw3iQZYMeUpxpj6Phgx/oooxMTquMecPKNgeVtaBst
|
||||||
|
qjTNPX0ti1/HYpZqzYi8SV8YjHSJWCVMsZjKPr3W/HIcCKqYoIfgzi83Ha2KMQx6
|
||||||
|
-----END RSA PRIVATE KEY-----
|
Binary file not shown.
|
@ -1,6 +0,0 @@
|
||||||
eclipse.preferences.version=1
|
|
||||||
encoding//src/main/java=UTF-8
|
|
||||||
encoding//src/main/resources=UTF-8
|
|
||||||
encoding//src/test/java=UTF-8
|
|
||||||
encoding//src/test/resources=UTF-8
|
|
||||||
encoding/<project>=UTF-8
|
|
|
@ -1,18 +0,0 @@
|
||||||
eclipse.preferences.version=1
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.nullable=org.elasticsearch.common.Nullable
|
|
||||||
org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
|
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
|
||||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
|
||||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
|
|
||||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
|
|
||||||
org.eclipse.jdt.core.compiler.source=1.8
|
|
||||||
org.eclipse.jdt.core.formatter.lineSplit=140
|
|
||||||
org.eclipse.jdt.core.formatter.tabulation.char=space
|
|
||||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
|
File diff suppressed because one or more lines are too long
|
@ -423,5 +423,3 @@ name in the `file` field. For example, the following snippet references the scri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
include::how-watcher-works/dynamic-index-names.asciidoc[]
|
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
[[dynamic-index-names]]
|
|
||||||
=== Dynamic Index Names
|
|
||||||
|
|
||||||
Several watch constructs deal with indices, including <<actions-index, `index` action>>,
|
|
||||||
the <<transform-search, `search` transform>> and the <<input-search, `search` input>>.
|
|
||||||
When configuring these constructs you can set the index names to static values. In addition
|
|
||||||
to specifying static index names, Watcher enables you to specify indexes using dynamic
|
|
||||||
time-aware templates. These templates resolve to specific index names during the watch
|
|
||||||
execution according to the execution time.
|
|
||||||
|
|
||||||
Dynamic index name resolution enables you to search a range of time-series indices, rather
|
|
||||||
than searching all of your time-series indices and filtering the the results. Limiting the
|
|
||||||
number of indices that are searched reduces the load on the cluster and improves watch
|
|
||||||
execution performance. For example, if you are using a watch to monitor errors in your
|
|
||||||
daily logs, you can use a dynamic index name template to restrict the search to the past
|
|
||||||
two days.
|
|
||||||
|
|
||||||
A dynamic index name takes the following form:
|
|
||||||
|
|
||||||
[source,txt]
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
<static_name{date_math_expr{date_format}}>
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Where:
|
|
||||||
|
|
||||||
* `static_name` is the static text part of the name
|
|
||||||
* `date_math_expr` is a dynamic date math expression that computes the date dynamically
|
|
||||||
* `date_format` is the format in which the computed date should be rendered
|
|
||||||
|
|
||||||
NOTE: You must enclose dynamic index name templates within angle brackets. For example,
|
|
||||||
`<logstash-{now/d-2d}>`
|
|
||||||
|
|
||||||
The following example shows different forms of dynamic index names and the final index names
|
|
||||||
they resolve to given the execution date is 22rd March 2024.
|
|
||||||
|
|
||||||
[options="header"]
|
|
||||||
|======
|
|
||||||
| Expression |Resolves to
|
|
||||||
| `<logstash-{now/d}>` | `logstash-2024.03.22`
|
|
||||||
| `<logstash-{now/M}>` | `logstash-2024.03.01`
|
|
||||||
| `<logstash-{now/M{YYYY.MM}}>` | `logstash-2024.03`
|
|
||||||
| `<logstash-{now/M-1M{YYYY.MM}}>` | `logstash-2024.02`
|
|
||||||
|======
|
|
||||||
|
|
||||||
To use the characters `{` and `}` in the static part of an index name template, escape them
|
|
||||||
with a backslash, `\`:
|
|
||||||
|
|
||||||
* `<elastic\\{ON\\}-{now/M}>` resolves to `elastic{ON}-2024.03.01`
|
|
||||||
|
|
||||||
The following example shows a search input that searches the Logstash indices for the past
|
|
||||||
three days, assuming the indices use the default Logstash index name format,
|
|
||||||
`logstash-YYYY.MM.dd`.
|
|
||||||
|
|
||||||
[source,json]
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
{
|
|
||||||
...
|
|
||||||
"input" : {
|
|
||||||
"search" : {
|
|
||||||
"request" : {
|
|
||||||
"indices" : [
|
|
||||||
"<logstash-{now/d-2d}>",
|
|
||||||
"<logstash-{now/d-1d}>",
|
|
||||||
"<logstash-{now/d}>"
|
|
||||||
],
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
[[dynamic-index-name-timezone]]
|
|
||||||
|
|
||||||
By default, the index names are resolved base on `UTC` time zone. You can change this default at
|
|
||||||
multiple levels:
|
|
||||||
|
|
||||||
Configuring the following setting set the default dynamic index name time zone in watcher:
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
watcher.dynamic_indices.time_zone: '+01:00'
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
You can also configure the default time zone separately on each of the construct that make
|
|
||||||
use of it (`search` input/transform and `index` action):
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
watcher.input.search.dynamic_indices.time_zone: '+01:00'
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
watcher.transform.search.dynamic_indices.time_zone: '+01:00'
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
watcher.actions.index.dynamic_indices.time_zone: '+01:00'
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
Alternatively, each of these construct can define their own time zone within the watch
|
|
||||||
definition.
|
|
|
@ -33,7 +33,7 @@ The following snippet shows a simple `index` action definition:
|
||||||
|Name |Required | Default | Description
|
|Name |Required | Default | Description
|
||||||
|
|
||||||
| `index` | yes | - | The Elasticsearch index to
|
| `index` | yes | - | The Elasticsearch index to
|
||||||
index into. <<dynamic-index-names, Dynamic index names>>
|
index into.
|
||||||
are supported
|
are supported
|
||||||
|
|
||||||
| `doc_type` | yes | - | The type of the document
|
| `doc_type` | yes | - | The type of the document
|
||||||
|
@ -51,10 +51,6 @@ The following snippet shows a simple `index` action definition:
|
||||||
the default internal index/bulk operations
|
the default internal index/bulk operations
|
||||||
<<default-internal-ops-timeouts, timeouts>>.
|
<<default-internal-ops-timeouts, timeouts>>.
|
||||||
|
|
||||||
| `dynamic_name_timezone` | no | - | The time zone to use for resolving the index name based on
|
|
||||||
<<dynamic-index-names, Dynamic Index Names>>. The default
|
|
||||||
time zone also can be <<dynamic-index-name-timezone, configured>>
|
|
||||||
globally.
|
|
||||||
|======
|
|======
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ holds an object where the keys serve as the header names and the values serve as
|
||||||
| `request.scheme` | no | http | The connection scheme. Valid values are: `http` or `https`.
|
| `request.scheme` | no | http | The connection scheme. Valid values are: `http` or `https`.
|
||||||
| `request.host` | yes | - | The host to connect to.
|
| `request.host` | yes | - | The host to connect to.
|
||||||
| `request.port` | yes | - | The port the HTTP service is listening on.
|
| `request.port` | yes | - | The port the HTTP service is listening on.
|
||||||
| `request.path` | no | - | The URL path. The path can be static text or include Mustache <<templates, templates>>.
|
| `request.path` | no | - | The URL path. The path can be static text or include Mustache <<templates, templates>>. URL query string parameters must be specified via the `request.params` attribute.
|
||||||
| `request.method` | no | get | The HTTP method. Valid values are: `head`, `get`, `post`, `put` and `delete`.
|
| `request.method` | no | get | The HTTP method. Valid values are: `head`, `get`, `post`, `put` and `delete`.
|
||||||
| `request.headers` | no | - | The HTTP request headers. The header values can be static text or include Mustache <<templates, templates>>.
|
| `request.headers` | no | - | The HTTP request headers. The header values can be static text or include Mustache <<templates, templates>>.
|
||||||
| `request.params` | no | - | The URL query string parameters. The parameter values can be static text or include Mustache <<templates, templates>>.
|
| `request.params` | no | - | The URL query string parameters. The parameter values can be static text or include Mustache <<templates, templates>>.
|
||||||
|
|
|
@ -30,7 +30,7 @@ NOTE: If the body of the response from the HTTP endpoint is in the JSON or YAM
|
||||||
| `request.scheme` | no | http | Url scheme. Valid values are: `http` or `https`.
|
| `request.scheme` | no | http | Url scheme. Valid values are: `http` or `https`.
|
||||||
| `request.host` | yes | - | The host to connect to.
|
| `request.host` | yes | - | The host to connect to.
|
||||||
| `request.port` | yes | - | The port the http service is listening on.
|
| `request.port` | yes | - | The port the http service is listening on.
|
||||||
| `request.path` | no | - | The URL path. The path can be static text or contain `mustache` <<templates, templates>>.
|
| `request.path` | no | - | The URL path. The path can be static text or contain `mustache` <<templates, templates>>. URL query string parameters must be specified via the `request.params` attribute.
|
||||||
| `request.method` | no | get | The HTTP method. Supported values are: `head`, `get`, `post`, `put` and `delete`.
|
| `request.method` | no | get | The HTTP method. Supported values are: `head`, `get`, `post`, `put` and `delete`.
|
||||||
| `request.headers` | no | - | The HTTP request headers. The header values can be static text or include `mustache` <<templates, templates>>.
|
| `request.headers` | no | - | The HTTP request headers. The header values can be static text or include `mustache` <<templates, templates>>.
|
||||||
| `request.params` | no | - | The URL query string parameters. The parameter values can be static text or contain `mustache` <<templates, templates>>.
|
| `request.params` | no | - | The URL query string parameters. The parameter values can be static text or contain `mustache` <<templates, templates>>.
|
||||||
|
|
|
@ -19,7 +19,7 @@ example, to get the message field from the first hit, use `ctx.payload.hits.hits
|
||||||
|======
|
|======
|
||||||
| Name |Required | Default | Description
|
| Name |Required | Default | Description
|
||||||
| `request.search_type` | no | count | The {ref}/search-request-search-type.html#search-request-search-type[type] of search request to perform. Valid values are: `count`, `dfs_query_and_fetch`, `dfs_query_then_fetch`, `query_and_fetch`, `query_then_fetch`, and `scan`. The Elasticsearch default is `query_then_fetch`.
|
| `request.search_type` | no | count | The {ref}/search-request-search-type.html#search-request-search-type[type] of search request to perform. Valid values are: `count`, `dfs_query_and_fetch`, `dfs_query_then_fetch`, `query_and_fetch`, `query_then_fetch`, and `scan`. The Elasticsearch default is `query_then_fetch`.
|
||||||
| `request.indices` | no | - | The indices to search. If omitted, all indices are searched, which is the default behaviour in Elasticsearch. <<dynamic-index-names, Dynamic index names>> are supported.
|
| `request.indices` | no | - | The indices to search. If omitted, all indices are searched, which is the default behaviour in Elasticsearch.
|
||||||
| `request.types` | no | - | The document types to search for. If omitted, all document types are are searched, which is the default behaviour in Elasticsearch.
|
| `request.types` | no | - | The document types to search for. If omitted, all document types are are searched, which is the default behaviour in Elasticsearch.
|
||||||
| `request.body` | no | - | The body of the request. The {ref}/search-request-body.html[request body] follows the same structure you normally send in the body of a REST `_search` request. The body can be static text or include `mustache` <<templates, templates>>.
|
| `request.body` | no | - | The body of the request. The {ref}/search-request-body.html[request body] follows the same structure you normally send in the body of a REST `_search` request. The body can be static text or include `mustache` <<templates, templates>>.
|
||||||
| `request.template` | no | - | The body of the search template. See <<templates, configure templates>> for more information.
|
| `request.template` | no | - | The body of the search template. See <<templates, configure templates>> for more information.
|
||||||
|
@ -29,7 +29,6 @@ example, to get the message field from the first hit, use `ctx.payload.hits.hits
|
||||||
| `extract` | no | - | A array of JSON keys to extract from the search response and load as the payload. When a search generates a large response, you can use `extract` to select the relevant fields instead of loading the entire response.
|
| `extract` | no | - | A array of JSON keys to extract from the search response and load as the payload. When a search generates a large response, you can use `extract` to select the relevant fields instead of loading the entire response.
|
||||||
| `timeout` | no | 30s | The timeout for waiting for the search api call to return. If no response is returned within this time, the search input times out and fails.
|
| `timeout` | no | 30s | The timeout for waiting for the search api call to return. If no response is returned within this time, the search input times out and fails.
|
||||||
This setting overrides the default internal search operations <<default-internal-ops-timeouts, timeouts>>.
|
This setting overrides the default internal search operations <<default-internal-ops-timeouts, timeouts>>.
|
||||||
| `dynamic_name_timezone` | no | - | The time zone to use for resolving the index name based on <<dynamic-index-names, Dynamic Index Names>>. The default time zone also can be <<dynamic-index-name-timezone, configured>> globally.
|
|
||||||
|======
|
|======
|
||||||
|
|
||||||
You can reference the following variables in the execution context when specifying the request `body`:
|
You can reference the following variables in the execution context when specifying the request `body`:
|
||||||
|
|
|
@ -56,7 +56,7 @@ The following table lists all available settings for the search transform:
|
||||||
|======
|
|======
|
||||||
| Name |Required | Default | Description
|
| Name |Required | Default | Description
|
||||||
| `request.search_type` | no | {ref}/search-request-search-type.html#query-then-fetch[query_then_fetch] | The search {ref}/search-request-search-type.html[search type]
|
| `request.search_type` | no | {ref}/search-request-search-type.html#query-then-fetch[query_then_fetch] | The search {ref}/search-request-search-type.html[search type]
|
||||||
| `request.indices` | no | all indices | One or more indices to search on (may be a comma-delimited string or an array of indices names). <<dynamic-index-names, Dynamic index names>> are supported.
|
| `request.indices` | no | all indices | One or more indices to search on (may be a comma-delimited string or an array of indices names).
|
||||||
| `request.types` | no | all types | One or more document types to search on (may be a comma-delimited string or an array of document types names)
|
| `request.types` | no | all types | One or more document types to search on (may be a comma-delimited string or an array of document types names)
|
||||||
| `request.body` | no | `match_all` query | The body of the request. The {ref}/search-request-body.html[request body] follows the same structure you normally send in the body of a REST `_search` request. The body can be static text or include `mustache` <<templates, templates>>.
|
| `request.body` | no | `match_all` query | The body of the request. The {ref}/search-request-body.html[request body] follows the same structure you normally send in the body of a REST `_search` request. The body can be static text or include `mustache` <<templates, templates>>.
|
||||||
| `request.indices_options.expand_wildcards` | no | `open` | Determines how to expand indices wildcards. Can be one of `open`, `closed`, `none` or `all` (see {ref}/multi-index.html[multi-index support])
|
| `request.indices_options.expand_wildcards` | no | `open` | Determines how to expand indices wildcards. Can be one of `open`, `closed`, `none` or `all` (see {ref}/multi-index.html[multi-index support])
|
||||||
|
@ -65,7 +65,6 @@ The following table lists all available settings for the search transform:
|
||||||
| `request.template` | no | - | The body of the search template. See <<templates, configure templates>> for more information.
|
| `request.template` | no | - | The body of the search template. See <<templates, configure templates>> for more information.
|
||||||
| `timeout` | no | 30s | The timeout for waiting for the search api call to return. If no response is returned within this time, the search transform times out and fails.
|
| `timeout` | no | 30s | The timeout for waiting for the search api call to return. If no response is returned within this time, the search transform times out and fails.
|
||||||
This setting overrides the default internal search operations <<default-internal-ops-timeouts, timeouts>>.
|
This setting overrides the default internal search operations <<default-internal-ops-timeouts, timeouts>>.
|
||||||
| `dynamic_name_timezone` | no | - | The time zone to use for resolving the index name based on <<dynamic-index-names, Dynamic Index Names>>. The default time zone also can be <<dynamic-index-name-timezone, configured>> globally.
|
|
||||||
|======
|
|======
|
||||||
|
|
||||||
[[transform-search-template]]
|
[[transform-search-template]]
|
||||||
|
|
|
@ -36,6 +36,21 @@ bin/plugin remove watcher
|
||||||
[[change-list]]
|
[[change-list]]
|
||||||
=== Change List
|
=== Change List
|
||||||
|
|
||||||
|
[float]
|
||||||
|
==== 2.0.0-rc1
|
||||||
|
|
||||||
|
.Breaking
|
||||||
|
* The dynamic index names support has been removed and Elasticsearch's date math index names support should be used instead.
|
||||||
|
The only difference between Watcher's dynamic index names support and Elasticsearch's date math index names support is
|
||||||
|
how timezones are expressed. In Watcher this is done via node settings, in Elasticsearch the timezone is part of the
|
||||||
|
date math index names support. Only if you're using dynamic index names with timezones in Watcher then you need to
|
||||||
|
upgrade your watches after the upgrade, otherwise your watches will work as they did before the upgrade. For example if
|
||||||
|
`watcher.dynamic_indices.time_zone` setting was set to `+01:00` and a watch has the following index name `<logstash-{now/d}>`
|
||||||
|
then after the upgrade you need to update this watch to use the following index name `<logstash-{now/d{YYYY.MM.dd|+01:00}}>`.
|
||||||
|
|
||||||
|
.Bug Fixes
|
||||||
|
* Fixed url encoding issue in http input and webhook output. The url params were url encoded twice.
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
==== 2.0.0-beta2
|
==== 2.0.0-beta2
|
||||||
|
|
||||||
|
@ -73,7 +88,7 @@ been aligned with the Elasticsearch versioning.
|
||||||
==== 1.0.0
|
==== 1.0.0
|
||||||
|
|
||||||
.Enhancements
|
.Enhancements
|
||||||
* Added execution time aware <<dynamic-index-names, dynamic index names>> support to `index`
|
* Added execution time aware dynamic index names support to `index`
|
||||||
action, `search` input, and `search` transform.
|
action, `search` input, and `search` transform.
|
||||||
* You must now explicitly specify the unit when configuring any time value. (Numeric-only
|
* You must now explicitly specify the unit when configuring any time value. (Numeric-only
|
||||||
values are no longer supported.)
|
values are no longer supported.)
|
||||||
|
|
|
@ -20,7 +20,6 @@ import org.elasticsearch.watcher.actions.Action;
|
||||||
import org.elasticsearch.watcher.actions.ExecutableAction;
|
import org.elasticsearch.watcher.actions.ExecutableAction;
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.watcher.support.ArrayObjectIterator;
|
import org.elasticsearch.watcher.support.ArrayObjectIterator;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.WatcherDateTimeUtils;
|
import org.elasticsearch.watcher.support.WatcherDateTimeUtils;
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.watcher.support.xcontent.XContentSource;
|
import org.elasticsearch.watcher.support.xcontent.XContentSource;
|
||||||
|
@ -37,17 +36,11 @@ public class ExecutableIndexAction extends ExecutableAction<IndexAction> {
|
||||||
|
|
||||||
private final ClientProxy client;
|
private final ClientProxy client;
|
||||||
private final TimeValue timeout;
|
private final TimeValue timeout;
|
||||||
private final DynamicIndexName indexName;
|
|
||||||
|
|
||||||
public ExecutableIndexAction(IndexAction action, ESLogger logger, ClientProxy client, @Nullable TimeValue defaultTimeout, DynamicIndexName.Parser indexNameParser) {
|
public ExecutableIndexAction(IndexAction action, ESLogger logger, ClientProxy client, @Nullable TimeValue defaultTimeout) {
|
||||||
super(action, logger);
|
super(action, logger);
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.timeout = action.timeout != null ? action.timeout : defaultTimeout;
|
this.timeout = action.timeout != null ? action.timeout : defaultTimeout;
|
||||||
this.indexName = indexNameParser.parse(action.index, action.dynamicNameTimeZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicIndexName indexName() {
|
|
||||||
return indexName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,7 +64,7 @@ public class ExecutableIndexAction extends ExecutableAction<IndexAction> {
|
||||||
|
|
||||||
IndexRequest indexRequest = new IndexRequest();
|
IndexRequest indexRequest = new IndexRequest();
|
||||||
|
|
||||||
indexRequest.index(indexName.name(ctx.executionTime()));
|
indexRequest.index(action.index);
|
||||||
indexRequest.type(action.docType);
|
indexRequest.type(action.docType);
|
||||||
|
|
||||||
if (action.executionTimeField != null && !TimestampFieldMapper.NAME.equals(action.executionTimeField)) {
|
if (action.executionTimeField != null && !TimestampFieldMapper.NAME.equals(action.executionTimeField)) {
|
||||||
|
@ -104,7 +97,7 @@ public class ExecutableIndexAction extends ExecutableAction<IndexAction> {
|
||||||
}
|
}
|
||||||
Map<String, Object> doc = (Map<String, Object>) item;
|
Map<String, Object> doc = (Map<String, Object>) item;
|
||||||
IndexRequest indexRequest = new IndexRequest();
|
IndexRequest indexRequest = new IndexRequest();
|
||||||
indexRequest.index(indexName.name(ctx.executionTime()));
|
indexRequest.index(action.index);
|
||||||
indexRequest.type(action.docType);
|
indexRequest.type(action.docType);
|
||||||
if (action.executionTimeField != null && !TimestampFieldMapper.NAME.equals(action.executionTimeField)) {
|
if (action.executionTimeField != null && !TimestampFieldMapper.NAME.equals(action.executionTimeField)) {
|
||||||
if (!(doc instanceof HashMap)) {
|
if (!(doc instanceof HashMap)) {
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.watcher.actions.ActionFactory;
|
import org.elasticsearch.watcher.actions.ActionFactory;
|
||||||
import org.elasticsearch.watcher.actions.email.ExecutableEmailAction;
|
import org.elasticsearch.watcher.actions.email.ExecutableEmailAction;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -23,14 +22,12 @@ import java.io.IOException;
|
||||||
public class IndexActionFactory extends ActionFactory<IndexAction, ExecutableIndexAction> {
|
public class IndexActionFactory extends ActionFactory<IndexAction, ExecutableIndexAction> {
|
||||||
|
|
||||||
private final ClientProxy client;
|
private final ClientProxy client;
|
||||||
private final DynamicIndexName.Parser indexNamesParser;
|
|
||||||
private final TimeValue defaultTimeout;
|
private final TimeValue defaultTimeout;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public IndexActionFactory(Settings settings, ClientProxy client) {
|
public IndexActionFactory(Settings settings, ClientProxy client) {
|
||||||
super(Loggers.getLogger(ExecutableEmailAction.class, settings));
|
super(Loggers.getLogger(ExecutableEmailAction.class, settings));
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.indexNamesParser = new DynamicIndexName.Parser(settings, "watcher.actions.index");
|
|
||||||
this.defaultTimeout = settings.getAsTime("watcher.actions.index.default_timeout", null);
|
this.defaultTimeout = settings.getAsTime("watcher.actions.index.default_timeout", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +43,6 @@ public class IndexActionFactory extends ActionFactory<IndexAction, ExecutableInd
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutableIndexAction createExecutable(IndexAction action) {
|
public ExecutableIndexAction createExecutable(IndexAction action) {
|
||||||
return new ExecutableIndexAction(action, actionLogger, client, defaultTimeout, indexNamesParser);
|
return new ExecutableIndexAction(action, actionLogger, client, defaultTimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.watcher.input.ExecutableInput;
|
import org.elasticsearch.watcher.input.ExecutableInput;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.WatcherUtils;
|
import org.elasticsearch.watcher.support.WatcherUtils;
|
||||||
import org.elasticsearch.watcher.support.XContentFilterKeysUtils;
|
import org.elasticsearch.watcher.support.XContentFilterKeysUtils;
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
|
@ -37,24 +36,17 @@ public class ExecutableSearchInput extends ExecutableInput<SearchInput, SearchIn
|
||||||
|
|
||||||
private final ClientProxy client;
|
private final ClientProxy client;
|
||||||
private final @Nullable TimeValue timeout;
|
private final @Nullable TimeValue timeout;
|
||||||
private final @Nullable DynamicIndexName[] indexNames;
|
|
||||||
|
|
||||||
public ExecutableSearchInput(SearchInput input, ESLogger logger, ClientProxy client, @Nullable TimeValue defaultTimeout, DynamicIndexName.Parser indexNameParser) {
|
public ExecutableSearchInput(SearchInput input, ESLogger logger, ClientProxy client, @Nullable TimeValue defaultTimeout) {
|
||||||
super(input, logger);
|
super(input, logger);
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.timeout = input.getTimeout() != null ? input.getTimeout() : defaultTimeout;
|
this.timeout = input.getTimeout() != null ? input.getTimeout() : defaultTimeout;
|
||||||
String[] indices = input.getSearchRequest().indices();
|
|
||||||
indexNames = indices != null ? indexNameParser.parse(indices, input.getDynamicNameTimeZone()) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicIndexName[] indexNames() {
|
|
||||||
return indexNames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchInput.Result execute(WatchExecutionContext ctx) {
|
public SearchInput.Result execute(WatchExecutionContext ctx) {
|
||||||
SearchRequest request = null;
|
SearchRequest request = null;
|
||||||
try {
|
try {
|
||||||
request = WatcherUtils.createSearchRequestFromPrototype(input.getSearchRequest(), indexNames, ctx, null);
|
request = WatcherUtils.createSearchRequestFromPrototype(input.getSearchRequest(), ctx, null);
|
||||||
return doExecute(ctx, request);
|
return doExecute(ctx, request);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("failed to execute [{}] input for [{}]", e, SearchInput.TYPE, ctx.watch());
|
logger.error("failed to execute [{}] input for [{}]", e, SearchInput.TYPE, ctx.watch());
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.watcher.input.InputFactory;
|
import org.elasticsearch.watcher.input.InputFactory;
|
||||||
import org.elasticsearch.watcher.input.simple.ExecutableSimpleInput;
|
import org.elasticsearch.watcher.input.simple.ExecutableSimpleInput;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -23,14 +22,12 @@ import java.io.IOException;
|
||||||
public class SearchInputFactory extends InputFactory<SearchInput, SearchInput.Result, ExecutableSearchInput> {
|
public class SearchInputFactory extends InputFactory<SearchInput, SearchInput.Result, ExecutableSearchInput> {
|
||||||
|
|
||||||
private final ClientProxy client;
|
private final ClientProxy client;
|
||||||
private final DynamicIndexName.Parser indexNameParser;
|
|
||||||
private final TimeValue defaultTimeout;
|
private final TimeValue defaultTimeout;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SearchInputFactory(Settings settings, ClientProxy client) {
|
public SearchInputFactory(Settings settings, ClientProxy client) {
|
||||||
super(Loggers.getLogger(ExecutableSimpleInput.class, settings));
|
super(Loggers.getLogger(ExecutableSimpleInput.class, settings));
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.indexNameParser = new DynamicIndexName.Parser(settings, "watcher.input.search");
|
|
||||||
this.defaultTimeout = settings.getAsTime("watcher.input.search.default_timeout", null);
|
this.defaultTimeout = settings.getAsTime("watcher.input.search.default_timeout", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +43,6 @@ public class SearchInputFactory extends InputFactory<SearchInput, SearchInput.Re
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutableSearchInput createExecutable(SearchInput input) {
|
public ExecutableSearchInput createExecutable(SearchInput input) {
|
||||||
return new ExecutableSearchInput(input, inputLogger, client, defaultTimeout, indexNameParser);
|
return new ExecutableSearchInput(input, inputLogger, client, defaultTimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,339 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.watcher.support;
|
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.joda.DateMathParser;
|
|
||||||
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
import org.joda.time.format.DateTimeFormat;
|
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DynamicIndexName implements ToXContent {
|
|
||||||
|
|
||||||
public static final String DEFAULT_DATE_FORMAT = "YYYY.MM.dd";
|
|
||||||
|
|
||||||
private static final String EXPRESSION_LEFT_BOUND = "<";
|
|
||||||
private static final String EXPRESSION_RIGHT_BOUND = ">";
|
|
||||||
private static final char LEFT_BOUND = '{';
|
|
||||||
private static final char RIGHT_BOUND = '}';
|
|
||||||
private static final char ESCAPE_CHAR = '\\';
|
|
||||||
|
|
||||||
private final String text;
|
|
||||||
private final Expression expression;
|
|
||||||
|
|
||||||
private DynamicIndexName(String text, Expression expression) {
|
|
||||||
this.text = text;
|
|
||||||
this.expression = expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String text() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name(DateTime now) {
|
|
||||||
return expression.eval(now);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[] names(DynamicIndexName[] indexNames, DateTime now) {
|
|
||||||
String[] names = new String[indexNames.length];
|
|
||||||
for (int i = 0; i < names.length; i++) {
|
|
||||||
names[i] = indexNames[i].name(now);
|
|
||||||
}
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
DynamicIndexName that = (DynamicIndexName) o;
|
|
||||||
|
|
||||||
return text.equals(that.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return text.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return builder.value(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String defaultDateFormat(Settings settings, String componentPrefix) {
|
|
||||||
if (componentPrefix == null) {
|
|
||||||
return defaultDateFormat(settings);
|
|
||||||
}
|
|
||||||
return settings.get(componentPrefix + ".dynamic_indices.default_date_format", defaultDateFormat(settings));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String defaultDateFormat(Settings settings) {
|
|
||||||
return settings.get("watcher.dynamic_indices.default_date_format", DEFAULT_DATE_FORMAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DateTimeZone timeZone(Settings settings, String componentPrefix) {
|
|
||||||
if (componentPrefix == null) {
|
|
||||||
return timeZone(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
String timeZoneId = settings.get(componentPrefix + ".dynamic_indices.time_zone", DateTimeZone.UTC.getID());
|
|
||||||
return DateTimeZone.forID(timeZoneId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DateTimeZone timeZone(Settings settings) {
|
|
||||||
String timeZoneId = settings.get("watcher.dynamic_indices.time_zone", DateTimeZone.UTC.getID());
|
|
||||||
return DateTimeZone.forID(timeZoneId);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Expression {
|
|
||||||
|
|
||||||
String eval(DateTime now);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static class StaticExpression implements Expression {
|
|
||||||
|
|
||||||
private final String value;
|
|
||||||
|
|
||||||
public StaticExpression(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String eval(DateTime now) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class DateMathExpression implements Expression {
|
|
||||||
|
|
||||||
private final DateMathParser dateMathParser;
|
|
||||||
private final String mathExpression;
|
|
||||||
private final FormatDateTimeFormatter formatter;
|
|
||||||
private final DateTimeZone timeZone;
|
|
||||||
|
|
||||||
public DateMathExpression(String defaultFormat, DateTimeZone timeZone, String expression) {
|
|
||||||
this.timeZone = timeZone;
|
|
||||||
int i = expression.indexOf(LEFT_BOUND);
|
|
||||||
String format;
|
|
||||||
if (i < 0) {
|
|
||||||
mathExpression = expression;
|
|
||||||
format = defaultFormat;
|
|
||||||
} else {
|
|
||||||
if (expression.lastIndexOf(RIGHT_BOUND) != expression.length() - 1) {
|
|
||||||
throw new ElasticsearchParseException("invalid dynamic name expression [{}]. missing closing `}` for date math format", expression);
|
|
||||||
}
|
|
||||||
if (i == expression.length() - 2) {
|
|
||||||
throw new ElasticsearchParseException("invalid dynamic name expression [{}]. missing date format", expression);
|
|
||||||
}
|
|
||||||
mathExpression = expression.substring(0, i);
|
|
||||||
format = expression.substring(i + 1, expression.length() - 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
DateTimeFormatter parser = DateTimeFormat.forPattern(format).withZone(timeZone);
|
|
||||||
formatter = new FormatDateTimeFormatter(defaultFormat, parser, Locale.ROOT);
|
|
||||||
dateMathParser = new DateMathParser(formatter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String eval(final DateTime now) {
|
|
||||||
long millis = dateMathParser.parse(mathExpression, new Callable<Long>() {
|
|
||||||
@Override
|
|
||||||
public Long call() throws Exception {
|
|
||||||
return now.getMillis();
|
|
||||||
}
|
|
||||||
}, false, timeZone);
|
|
||||||
return formatter.printer().print(millis);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class CompoundExpression implements Expression {
|
|
||||||
|
|
||||||
private final Expression[] parts;
|
|
||||||
|
|
||||||
public CompoundExpression(Expression[] parts) {
|
|
||||||
this.parts = parts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String eval(DateTime now) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (Expression part : parts) {
|
|
||||||
sb.append(part.eval(now));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
static Expression parse(String defaultDateFormat, DateTimeZone timeZone, char[] text, int from, int length) {
|
|
||||||
boolean dynamic = false;
|
|
||||||
List<Expression> expressions = new ArrayList<>();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
boolean inPlaceHolder = false;
|
|
||||||
boolean inDateFormat = false;
|
|
||||||
boolean escape = false;
|
|
||||||
for (int i = from; i < length; i++) {
|
|
||||||
boolean escapedChar = escape;
|
|
||||||
if (escape) {
|
|
||||||
escape = false;
|
|
||||||
}
|
|
||||||
char c = text[i];
|
|
||||||
|
|
||||||
if (c == ESCAPE_CHAR) {
|
|
||||||
if (escapedChar) {
|
|
||||||
sb.append(c);
|
|
||||||
escape = false;
|
|
||||||
} else {
|
|
||||||
escape = true;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inPlaceHolder) {
|
|
||||||
switch (c) {
|
|
||||||
|
|
||||||
case LEFT_BOUND:
|
|
||||||
if (inDateFormat && escapedChar) {
|
|
||||||
sb.append(c);
|
|
||||||
} else if (!inDateFormat) {
|
|
||||||
inDateFormat = true;
|
|
||||||
sb.append(c);
|
|
||||||
} else {
|
|
||||||
throw new ElasticsearchParseException("invalid dynamic name expression [{}]. invalid character in placeholder at position [{}]", new String(text, from, length), i);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIGHT_BOUND:
|
|
||||||
if (inDateFormat && escapedChar) {
|
|
||||||
sb.append(c);
|
|
||||||
} else if (inDateFormat) {
|
|
||||||
inDateFormat = false;
|
|
||||||
sb.append(c);
|
|
||||||
} else {
|
|
||||||
expressions.add(new DateMathExpression(defaultDateFormat, timeZone, sb.toString()));
|
|
||||||
sb = new StringBuilder();
|
|
||||||
inPlaceHolder = false;
|
|
||||||
dynamic = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
sb.append(c);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (c) {
|
|
||||||
|
|
||||||
case LEFT_BOUND:
|
|
||||||
if (escapedChar) {
|
|
||||||
sb.append(c);
|
|
||||||
} else {
|
|
||||||
expressions.add(new StaticExpression(sb.toString()));
|
|
||||||
sb = new StringBuilder();
|
|
||||||
inPlaceHolder = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIGHT_BOUND:
|
|
||||||
if (!escapedChar) {
|
|
||||||
throw new ElasticsearchParseException("invalid dynamic name expression [{}]. invalid character at position [{}]. " +
|
|
||||||
"`{` and `}` are reserved characters and should be escaped when used as part of the index name using `\\` (e.g. `\\{text\\}`)", new String(text, from, length), i);
|
|
||||||
}
|
|
||||||
sb.append(c);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sb.append(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (inPlaceHolder) {
|
|
||||||
throw new ElasticsearchParseException("invalid dynamic name expression [{}]. date math placeholder is open ended", new String(text, from, length));
|
|
||||||
}
|
|
||||||
if (sb.length() > 0) {
|
|
||||||
expressions.add(new StaticExpression(sb.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dynamic) {
|
|
||||||
// if all the expressions are static... lets optimize to a single static expression
|
|
||||||
sb = new StringBuilder();
|
|
||||||
for (Expression expression : expressions) {
|
|
||||||
sb.append(((StaticExpression) expression).value);
|
|
||||||
}
|
|
||||||
return new StaticExpression(sb.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expressions.size() == 1) {
|
|
||||||
return expressions.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CompoundExpression(expressions.toArray(new Expression[expressions.size()]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Parser {
|
|
||||||
|
|
||||||
private final String defaultDateFormat;
|
|
||||||
private final DateTimeZone timeZone;
|
|
||||||
|
|
||||||
public Parser() {
|
|
||||||
this(DEFAULT_DATE_FORMAT, DateTimeZone.UTC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Parser(String defaultDateFormat, DateTimeZone timeZone) {
|
|
||||||
this.defaultDateFormat = defaultDateFormat;
|
|
||||||
this.timeZone = timeZone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Parser(Settings settings, String componentPrefix) {
|
|
||||||
this(defaultDateFormat(settings, componentPrefix), timeZone(settings, componentPrefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynamicIndexName parse(String template) {
|
|
||||||
return parse(template, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynamicIndexName parse(String template, @Nullable DateTimeZone timeZone) {
|
|
||||||
DateTimeZone tz = timeZone != null ? timeZone : this.timeZone;
|
|
||||||
if (template == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!template.startsWith(EXPRESSION_LEFT_BOUND) || !template.endsWith(EXPRESSION_RIGHT_BOUND)) {
|
|
||||||
return new DynamicIndexName(template, new StaticExpression(template));
|
|
||||||
}
|
|
||||||
return new DynamicIndexName(template, CompoundExpression.parse(defaultDateFormat, tz, template.toCharArray(), 1, template.length() - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynamicIndexName[] parse(String[] templates) {
|
|
||||||
return parse(templates, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynamicIndexName[] parse(String[] templates, @Nullable DateTimeZone timeZone) {
|
|
||||||
if (templates.length == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
DynamicIndexName[] dynamicIndexNames = new DynamicIndexName[templates.length];
|
|
||||||
for (int i = 0; i < dynamicIndexNames.length; i++) {
|
|
||||||
dynamicIndexNames[i] = parse(templates[i], timeZone);
|
|
||||||
}
|
|
||||||
return dynamicIndexNames;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -53,16 +53,11 @@ public final class WatcherUtils {
|
||||||
return XContentHelper.convertToMap(builder.bytes(), false).v2();
|
return XContentHelper.convertToMap(builder.bytes(), false).v2();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SearchRequest createSearchRequestFromPrototype(SearchRequest requestPrototype, @Nullable DynamicIndexName[] dynamicIndexNames, WatchExecutionContext ctx, Payload payload) throws IOException {
|
public static SearchRequest createSearchRequestFromPrototype(SearchRequest requestPrototype, WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||||
|
|
||||||
String[] indices = dynamicIndexNames == null ?
|
|
||||||
requestPrototype.indices() :
|
|
||||||
DynamicIndexName.names(dynamicIndexNames, ctx.executionTime());
|
|
||||||
|
|
||||||
SearchRequest request = new SearchRequest(requestPrototype)
|
SearchRequest request = new SearchRequest(requestPrototype)
|
||||||
.indicesOptions(requestPrototype.indicesOptions())
|
.indicesOptions(requestPrototype.indicesOptions())
|
||||||
.searchType(requestPrototype.searchType())
|
.searchType(requestPrototype.searchType())
|
||||||
.indices(indices)
|
.indices(requestPrototype.indices())
|
||||||
.types(requestPrototype.types());
|
.types(requestPrototype.types());
|
||||||
|
|
||||||
// TODO: Revise this search template conversion code once search templates in core have been refactored once ES 2.0 is released.
|
// TODO: Revise this search template conversion code once search templates in core have been refactored once ES 2.0 is released.
|
||||||
|
|
|
@ -107,9 +107,9 @@ public class HttpClient extends AbstractLifecycleComponent<HttpClient> {
|
||||||
if (builder.length() != 0) {
|
if (builder.length() != 0) {
|
||||||
builder.append('&');
|
builder.append('&');
|
||||||
}
|
}
|
||||||
builder.append(URLEncoder.encode(entry.getKey(), "utf-8"))
|
builder.append(entry.getKey())
|
||||||
.append('=')
|
.append('=')
|
||||||
.append(URLEncoder.encode(entry.getValue(), "utf-8"));
|
.append(entry.getValue());
|
||||||
}
|
}
|
||||||
queryString = builder.toString();
|
queryString = builder.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.WatcherUtils;
|
import org.elasticsearch.watcher.support.WatcherUtils;
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
|
@ -27,25 +26,18 @@ public class ExecutableSearchTransform extends ExecutableTransform<SearchTransfo
|
||||||
|
|
||||||
protected final ClientProxy client;
|
protected final ClientProxy client;
|
||||||
protected final @Nullable TimeValue timeout;
|
protected final @Nullable TimeValue timeout;
|
||||||
private final @Nullable DynamicIndexName[] indexNames;
|
|
||||||
|
|
||||||
public ExecutableSearchTransform(SearchTransform transform, ESLogger logger, ClientProxy client, @Nullable TimeValue defaultTimeout, DynamicIndexName.Parser indexNameParser) {
|
public ExecutableSearchTransform(SearchTransform transform, ESLogger logger, ClientProxy client, @Nullable TimeValue defaultTimeout) {
|
||||||
super(transform, logger);
|
super(transform, logger);
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.timeout = transform.getTimeout() != null ? transform.getTimeout() : defaultTimeout;
|
this.timeout = transform.getTimeout() != null ? transform.getTimeout() : defaultTimeout;
|
||||||
String[] indices = transform.getRequest().indices();
|
|
||||||
this.indexNames = indices != null ? indexNameParser.parse(indices, transform.getDynamicNameTimeZone()) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicIndexName[] indexNames() {
|
|
||||||
return indexNames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchTransform.Result execute(WatchExecutionContext ctx, Payload payload) {
|
public SearchTransform.Result execute(WatchExecutionContext ctx, Payload payload) {
|
||||||
SearchRequest request = null;
|
SearchRequest request = null;
|
||||||
try {
|
try {
|
||||||
request = WatcherUtils.createSearchRequestFromPrototype(transform.getRequest(), indexNames, ctx, payload);
|
request = WatcherUtils.createSearchRequestFromPrototype(transform.getRequest(), ctx, payload);
|
||||||
SearchResponse resp = client.search(request, timeout);
|
SearchResponse resp = client.search(request, timeout);
|
||||||
return new SearchTransform.Result(request, new Payload.XContent(resp));
|
return new SearchTransform.Result(request, new Payload.XContent(resp));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -10,7 +10,6 @@ import org.elasticsearch.common.logging.Loggers;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.watcher.transform.TransformFactory;
|
import org.elasticsearch.watcher.transform.TransformFactory;
|
||||||
|
|
||||||
|
@ -22,14 +21,12 @@ import java.io.IOException;
|
||||||
public class SearchTransformFactory extends TransformFactory<SearchTransform, SearchTransform.Result, ExecutableSearchTransform> {
|
public class SearchTransformFactory extends TransformFactory<SearchTransform, SearchTransform.Result, ExecutableSearchTransform> {
|
||||||
|
|
||||||
protected final ClientProxy client;
|
protected final ClientProxy client;
|
||||||
protected final DynamicIndexName.Parser indexNameParser;
|
|
||||||
private final TimeValue defaultTimeout;
|
private final TimeValue defaultTimeout;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SearchTransformFactory(Settings settings, ClientProxy client) {
|
public SearchTransformFactory(Settings settings, ClientProxy client) {
|
||||||
super(Loggers.getLogger(ExecutableSearchTransform.class, settings));
|
super(Loggers.getLogger(ExecutableSearchTransform.class, settings));
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.indexNameParser = new DynamicIndexName.Parser(settings, "watcher.transform.search");
|
|
||||||
this.defaultTimeout = settings.getAsTime("watcher.transform.search.default_timeout", null);
|
this.defaultTimeout = settings.getAsTime("watcher.transform.search.default_timeout", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +42,6 @@ public class SearchTransformFactory extends TransformFactory<SearchTransform, Se
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutableSearchTransform createExecutable(SearchTransform transform) {
|
public ExecutableSearchTransform createExecutable(SearchTransform transform) {
|
||||||
return new ExecutableSearchTransform(transform, transformLogger, client, defaultTimeout, indexNameParser);
|
return new ExecutableSearchTransform(transform, transformLogger, client, defaultTimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,12 @@ import org.elasticsearch.test.ESIntegTestCase;
|
||||||
import org.elasticsearch.watcher.actions.Action;
|
import org.elasticsearch.watcher.actions.Action;
|
||||||
import org.elasticsearch.watcher.actions.Action.Result.Status;
|
import org.elasticsearch.watcher.actions.Action.Result.Status;
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.WatcherDateTimeUtils;
|
import org.elasticsearch.watcher.support.WatcherDateTimeUtils;
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.watcher.support.xcontent.XContentSource;
|
import org.elasticsearch.watcher.support.xcontent.XContentSource;
|
||||||
import org.elasticsearch.watcher.test.WatcherTestUtils;
|
import org.elasticsearch.watcher.test.WatcherTestUtils;
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
import org.joda.time.format.DateTimeFormat;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -80,7 +77,7 @@ public class IndexActionTests extends ESIntegTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexAction action = new IndexAction("test-index", "test-type", timestampField, null, null);
|
IndexAction action = new IndexAction("test-index", "test-type", timestampField, null, null);
|
||||||
ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, ClientProxy.of(client()), null, new DynamicIndexName.Parser());
|
ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, ClientProxy.of(client()), null);
|
||||||
DateTime executionTime = DateTime.now(UTC);
|
DateTime executionTime = DateTime.now(UTC);
|
||||||
Payload payload = randomBoolean() ? new Payload.Simple("foo", "bar") : new Payload.Simple("_doc", ImmutableMap.of("foo", "bar"));
|
Payload payload = randomBoolean() ? new Payload.Simple("foo", "bar") : new Payload.Simple("_doc", ImmutableMap.of("foo", "bar"));
|
||||||
WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", executionTime, payload);
|
WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", executionTime, payload);
|
||||||
|
@ -143,7 +140,7 @@ public class IndexActionTests extends ESIntegTestCase {
|
||||||
);
|
);
|
||||||
|
|
||||||
IndexAction action = new IndexAction("test-index", "test-type", timestampField, null, null);
|
IndexAction action = new IndexAction("test-index", "test-type", timestampField, null, null);
|
||||||
ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, ClientProxy.of(client()), null, new DynamicIndexName.Parser());
|
ExecutableIndexAction executable = new ExecutableIndexAction(action, logger, ClientProxy.of(client()), null);
|
||||||
DateTime executionTime = DateTime.now(UTC);
|
DateTime executionTime = DateTime.now(UTC);
|
||||||
WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", executionTime, new Payload.Simple("_doc", list));
|
WatchExecutionContext ctx = WatcherTestUtils.mockExecutionContext("_id", executionTime, new Payload.Simple("_doc", list));
|
||||||
|
|
||||||
|
@ -224,47 +221,6 @@ public class IndexActionTests extends ESIntegTestCase {
|
||||||
assertThat(executable.action().timeout, equalTo(writeTimeout));
|
assertThat(executable.action().timeout, equalTo(writeTimeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testParser_DynamicIndex() throws Exception {
|
|
||||||
|
|
||||||
DateTime now = DateTime.now(UTC);
|
|
||||||
DateTimeZone timeZone = randomBoolean() ? DateTimeZone.forOffsetHours(-2) : null;
|
|
||||||
if (timeZone != null) {
|
|
||||||
now = now.withHourOfDay(0).withMinuteOfHour(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
XContentBuilder builder = jsonBuilder();
|
|
||||||
builder.startObject()
|
|
||||||
.field(IndexAction.Field.INDEX.getPreferredName(), "<idx-{now/d}>")
|
|
||||||
.field(IndexAction.Field.DOC_TYPE.getPreferredName(), "test-type");
|
|
||||||
|
|
||||||
boolean timeZoneInWatch = randomBoolean();
|
|
||||||
if (timeZone != null && timeZoneInWatch) {
|
|
||||||
builder.field(IndexAction.Field.DYNAMIC_NAME_TIMEZONE.getPreferredName(), timeZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.endObject();
|
|
||||||
|
|
||||||
Settings.Builder settings = Settings.builder();
|
|
||||||
if (timeZone != null && !timeZoneInWatch) {
|
|
||||||
settings.put("watcher.actions.index.dynamic_indices.time_zone", timeZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexActionFactory actionParser = new IndexActionFactory(settings.build(), ClientProxy.of(client()));
|
|
||||||
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
|
||||||
parser.nextToken();
|
|
||||||
|
|
||||||
ExecutableIndexAction executable = actionParser.parseExecutable(randomAsciiOfLength(5), randomAsciiOfLength(3), parser);
|
|
||||||
|
|
||||||
assertThat(executable, notNullValue());
|
|
||||||
assertThat(executable.action().index, is("<idx-{now/d}>"));
|
|
||||||
String indexName = executable.indexName().name(now);
|
|
||||||
if (timeZone != null) {
|
|
||||||
now = now.withZone(timeZone);
|
|
||||||
}
|
|
||||||
assertThat(indexName, is("idx-" + DateTimeFormat.forPattern("YYYY.MM.dd").print(now)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParser_Failure() throws Exception {
|
public void testParser_Failure() throws Exception {
|
||||||
XContentBuilder builder = jsonBuilder();
|
XContentBuilder builder = jsonBuilder();
|
||||||
|
|
|
@ -7,7 +7,6 @@ package org.elasticsearch.watcher.input.search;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptRequest;
|
import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptRequest;
|
||||||
import org.elasticsearch.action.search.SearchRequest;
|
import org.elasticsearch.action.search.SearchRequest;
|
||||||
import org.elasticsearch.action.search.SearchType;
|
import org.elasticsearch.action.search.SearchType;
|
||||||
|
@ -20,7 +19,6 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
import org.elasticsearch.search.sort.SortBuilders;
|
|
||||||
import org.elasticsearch.test.ESIntegTestCase;
|
import org.elasticsearch.test.ESIntegTestCase;
|
||||||
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
||||||
import org.elasticsearch.watcher.actions.ActionStatus;
|
import org.elasticsearch.watcher.actions.ActionStatus;
|
||||||
|
@ -31,7 +29,6 @@ import org.elasticsearch.watcher.execution.TriggeredExecutionContext;
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.watcher.input.simple.ExecutableSimpleInput;
|
import org.elasticsearch.watcher.input.simple.ExecutableSimpleInput;
|
||||||
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.watcher.support.text.TextTemplate;
|
import org.elasticsearch.watcher.support.text.TextTemplate;
|
||||||
import org.elasticsearch.watcher.trigger.schedule.IntervalSchedule;
|
import org.elasticsearch.watcher.trigger.schedule.IntervalSchedule;
|
||||||
|
@ -41,8 +38,6 @@ import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.watcher.watch.Watch;
|
import org.elasticsearch.watcher.watch.Watch;
|
||||||
import org.elasticsearch.watcher.watch.WatchStatus;
|
import org.elasticsearch.watcher.watch.WatchStatus;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
import org.joda.time.format.DateTimeFormat;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -116,7 +111,7 @@ public class SearchInputTests extends ESIntegTestCase {
|
||||||
.request()
|
.request()
|
||||||
.source(searchSourceBuilder);
|
.source(searchSourceBuilder);
|
||||||
|
|
||||||
ExecutableSearchInput searchInput = new ExecutableSearchInput(new SearchInput(request, null, null, null), logger, ClientProxy.of(client()), null, new DynamicIndexName.Parser());
|
ExecutableSearchInput searchInput = new ExecutableSearchInput(new SearchInput(request, null, null, null), logger, ClientProxy.of(client()), null);
|
||||||
WatchExecutionContext ctx = new TriggeredExecutionContext(
|
WatchExecutionContext ctx = new TriggeredExecutionContext(
|
||||||
new Watch("test-watch",
|
new Watch("test-watch",
|
||||||
new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))),
|
new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))),
|
||||||
|
@ -223,7 +218,7 @@ public class SearchInputTests extends ESIntegTestCase {
|
||||||
.request()
|
.request()
|
||||||
.source(searchSourceBuilder);
|
.source(searchSourceBuilder);
|
||||||
|
|
||||||
ExecutableSearchInput searchInput = new ExecutableSearchInput(new SearchInput(request, null, null, null), logger, ClientProxy.of(client()), null, new DynamicIndexName.Parser());
|
ExecutableSearchInput searchInput = new ExecutableSearchInput(new SearchInput(request, null, null, null), logger, ClientProxy.of(client()), null);
|
||||||
WatchExecutionContext ctx = new TriggeredExecutionContext(
|
WatchExecutionContext ctx = new TriggeredExecutionContext(
|
||||||
new Watch("test-watch",
|
new Watch("test-watch",
|
||||||
new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))),
|
new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))),
|
||||||
|
@ -266,57 +261,6 @@ public class SearchInputTests extends ESIntegTestCase {
|
||||||
assertThat(searchInput.getTimeout(), equalTo(timeout));
|
assertThat(searchInput.getTimeout(), equalTo(timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testParser_IndexNames() throws Exception {
|
|
||||||
SearchRequest request = client().prepareSearch()
|
|
||||||
.setSearchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE)
|
|
||||||
.setIndices("test", "<test-{now/d-1d}>")
|
|
||||||
.request()
|
|
||||||
.source(searchSource()
|
|
||||||
.query(boolQuery().must(matchQuery("event_type", "a")).filter(rangeQuery("_timestamp").from("{{ctx.trigger.scheduled_time}}||-30s").to("{{ctx.trigger.triggered_time}}"))));
|
|
||||||
|
|
||||||
DateTime now = DateTime.now(UTC);
|
|
||||||
DateTimeZone timeZone = randomBoolean() ? DateTimeZone.forOffsetHours(-2) : null;
|
|
||||||
if (timeZone != null) {
|
|
||||||
now = now.withHourOfDay(0).withMinuteOfHour(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean timeZoneInWatch = randomBoolean();
|
|
||||||
SearchInput input = timeZone != null && timeZoneInWatch ?
|
|
||||||
new SearchInput(request, null, null, timeZone) :
|
|
||||||
new SearchInput(request, null, null, null);
|
|
||||||
|
|
||||||
XContentBuilder builder = jsonBuilder().value(input);
|
|
||||||
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
|
||||||
parser.nextToken();
|
|
||||||
|
|
||||||
String dateFormat;
|
|
||||||
Settings.Builder settingsBuilder = Settings.builder();
|
|
||||||
if (randomBoolean()) {
|
|
||||||
dateFormat = DynamicIndexName.DEFAULT_DATE_FORMAT;
|
|
||||||
} else {
|
|
||||||
dateFormat = "YYYY-MM-dd";
|
|
||||||
settingsBuilder.put("watcher.input.search.dynamic_indices.default_date_format", dateFormat);
|
|
||||||
}
|
|
||||||
if (timeZone != null && !timeZoneInWatch) {
|
|
||||||
settingsBuilder.put("watcher.input.search.dynamic_indices.time_zone", timeZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchInputFactory factory = new SearchInputFactory(settingsBuilder.build(), ClientProxy.of(client()));
|
|
||||||
|
|
||||||
ExecutableSearchInput executable = factory.parseExecutable("_id", parser);
|
|
||||||
DynamicIndexName[] indexNames = executable.indexNames();
|
|
||||||
assertThat(indexNames, notNullValue());
|
|
||||||
|
|
||||||
String[] names = DynamicIndexName.names(indexNames, now);
|
|
||||||
assertThat(names, notNullValue());
|
|
||||||
assertThat(names.length, is(2));
|
|
||||||
if (timeZone != null) {
|
|
||||||
now = now.withZone(timeZone);
|
|
||||||
}
|
|
||||||
assertThat(names, arrayContaining("test", "test-" + DateTimeFormat.forPattern(dateFormat).print(now.minusDays(1))));
|
|
||||||
}
|
|
||||||
|
|
||||||
private WatchExecutionContext createContext() {
|
private WatchExecutionContext createContext() {
|
||||||
return new TriggeredExecutionContext(
|
return new TriggeredExecutionContext(
|
||||||
new Watch("test-watch",
|
new Watch("test-watch",
|
||||||
|
@ -340,7 +284,7 @@ public class SearchInputTests extends ESIntegTestCase {
|
||||||
|
|
||||||
SearchInput si = siBuilder.build();
|
SearchInput si = siBuilder.build();
|
||||||
|
|
||||||
ExecutableSearchInput searchInput = new ExecutableSearchInput(si, logger, ClientProxy.of(client()), null, new DynamicIndexName.Parser());
|
ExecutableSearchInput searchInput = new ExecutableSearchInput(si, logger, ClientProxy.of(client()), null);
|
||||||
return searchInput.execute(ctx);
|
return searchInput.execute(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,11 +83,12 @@ public class DynamicIndexNameIntegrationTests extends AbstractWatcherIntegration
|
||||||
flush();
|
flush();
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
|
String indexNameDateMathExpressions = "<idx-{now/d}>";
|
||||||
WatcherClient watcherClient = watcherClient();
|
WatcherClient watcherClient = watcherClient();
|
||||||
PutWatchResponse putWatchResponse = watcherClient.preparePutWatch("_id")
|
PutWatchResponse putWatchResponse = watcherClient.preparePutWatch("_id")
|
||||||
.setSource(watchBuilder()
|
.setSource(watchBuilder()
|
||||||
.trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS)))
|
.trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS)))
|
||||||
.input(searchInput(new SearchRequest("<idx-{now/d}>").types("type"))))
|
.input(searchInput(new SearchRequest(indexNameDateMathExpressions).types("type"))))
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
assertThat(putWatchResponse.isCreated(), is(true));
|
assertThat(putWatchResponse.isCreated(), is(true));
|
||||||
|
@ -96,23 +97,24 @@ public class DynamicIndexNameIntegrationTests extends AbstractWatcherIntegration
|
||||||
flush();
|
flush();
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
SearchResponse response = searchHistory(searchSource().query(matchQuery("result.input.search.request.indices", indexName)));
|
SearchResponse response = searchHistory(searchSource().query(matchQuery("result.input.search.request.indices", indexNameDateMathExpressions)));
|
||||||
assertThat(response.getHits().getTotalHits(), is(1L));
|
assertThat(response.getHits().getTotalHits(), is(1L));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDynamicIndexSearchTransform() throws Exception {
|
public void testDynamicIndexSearchTransform() throws Exception {
|
||||||
final String indexName = "idx-" + DateTimeFormat.forPattern("YYYY.MM.dd").print(timeWarp().clock().nowUTC());
|
String indexName = "idx-" + DateTimeFormat.forPattern("YYYY.MM.dd").print(timeWarp().clock().nowUTC());
|
||||||
createIndex(indexName);
|
createIndex(indexName);
|
||||||
index(indexName, "type", "1", "key", "value");
|
index(indexName, "type", "1", "key", "value");
|
||||||
flush();
|
flush();
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
|
final String indexNameDateMathExpressions = "<idx-{now/d}>";
|
||||||
WatcherClient watcherClient = watcherClient();
|
WatcherClient watcherClient = watcherClient();
|
||||||
PutWatchResponse putWatchResponse = watcherClient.preparePutWatch("_id")
|
PutWatchResponse putWatchResponse = watcherClient.preparePutWatch("_id")
|
||||||
.setSource(watchBuilder()
|
.setSource(watchBuilder()
|
||||||
.trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS)))
|
.trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS)))
|
||||||
.transform(searchTransform(new SearchRequest("<idx-{now/d}>").types("type")))
|
.transform(searchTransform(new SearchRequest(indexNameDateMathExpressions).types("type")))
|
||||||
.addAction("log", loggingAction("heya")))
|
.addAction("log", loggingAction("heya")))
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
|
@ -125,7 +127,7 @@ public class DynamicIndexNameIntegrationTests extends AbstractWatcherIntegration
|
||||||
SearchResponse response = searchWatchRecords(new Callback<SearchRequestBuilder>() {
|
SearchResponse response = searchWatchRecords(new Callback<SearchRequestBuilder>() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(SearchRequestBuilder builder) {
|
public void handle(SearchRequestBuilder builder) {
|
||||||
builder.setQuery(matchQuery("result.transform.search.request.indices", indexName));
|
builder.setQuery(matchQuery("result.transform.search.request.indices", indexNameDateMathExpressions));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
assertThat(response.getHits().getTotalHits(), is(1L));
|
assertThat(response.getHits().getTotalHits(), is(1L));
|
||||||
|
|
|
@ -1,266 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.watcher.support;
|
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
import org.joda.time.format.DateTimeFormat;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.nullValue;
|
|
||||||
import static org.hamcrest.Matchers.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DynamicIndexNameTests extends ESTestCase {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNormal() throws Exception {
|
|
||||||
String indexName = randomAsciiOfLength(10);
|
|
||||||
DateTime now = DateTime.now(DateTimeZone.UTC);
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
DynamicIndexName indexNames = parser.parse(indexName);
|
|
||||||
String name = indexNames.name(now);
|
|
||||||
assertThat(name, equalTo(indexName));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpression() throws Exception {
|
|
||||||
DateTime now = DateTime.now(DateTimeZone.UTC);
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
DynamicIndexName indexNames = parser.parse("<.marvel-{now}>");
|
|
||||||
String name = indexNames.name(now);
|
|
||||||
assertThat(name, equalTo(".marvel-" + DateTimeFormat.forPattern("YYYY.MM.dd").print(now)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNullOrEmpty() throws Exception {
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
DynamicIndexName indexName = parser.parse((String) null);
|
|
||||||
assertThat(indexName, nullValue());
|
|
||||||
DynamicIndexName[] indexNames = parser.parse(Strings.EMPTY_ARRAY);
|
|
||||||
assertThat(indexNames, nullValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpression_Static() throws Exception {
|
|
||||||
DateTime now = DateTime.now(DateTimeZone.UTC);
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
DynamicIndexName indexNames = parser.parse("<.marvel-test>");
|
|
||||||
String name = indexNames.name(now);
|
|
||||||
assertThat(name, equalTo(".marvel-test"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpression_MultiParts() throws Exception {
|
|
||||||
DateTime now = DateTime.now(DateTimeZone.UTC);
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
DynamicIndexName indexNames = parser.parse("<.text1-{now/d}-text2-{now/M}>");
|
|
||||||
String name = indexNames.name(now);
|
|
||||||
assertThat(name, equalTo(".text1-"
|
|
||||||
+ DateTimeFormat.forPattern("YYYY.MM.dd").print(now)
|
|
||||||
+ "-text2-"
|
|
||||||
+ DateTimeFormat.forPattern("YYYY.MM.dd").print(now.withDayOfMonth(1))));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpression_CustomFormat() throws Exception {
|
|
||||||
DateTime now = DateTime.now(DateTimeZone.UTC);
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
DynamicIndexName indexNames = parser.parse("<.marvel-{now/d{YYYY.MM.dd}}>");
|
|
||||||
String name = indexNames.name(now);
|
|
||||||
assertThat(name, equalTo(".marvel-" + DateTimeFormat.forPattern("YYYY.MM.dd").print(now)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpression_CustomTimeZone() throws Exception {
|
|
||||||
DateTimeZone timeZone;
|
|
||||||
int hoursOffset;
|
|
||||||
int minutesOffset = 0;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
hoursOffset = randomIntBetween(-12, 14);
|
|
||||||
timeZone = DateTimeZone.forOffsetHours(hoursOffset);
|
|
||||||
} else {
|
|
||||||
hoursOffset = randomIntBetween(-11, 13);
|
|
||||||
minutesOffset = randomIntBetween(0, 59);
|
|
||||||
timeZone = DateTimeZone.forOffsetHoursMinutes(hoursOffset, minutesOffset);
|
|
||||||
}
|
|
||||||
DateTime now;
|
|
||||||
if (hoursOffset >= 0) {
|
|
||||||
// rounding to next day 00:00
|
|
||||||
now = DateTime.now(DateTimeZone.UTC).plusHours(hoursOffset).plusMinutes(minutesOffset).withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0);
|
|
||||||
} else {
|
|
||||||
// rounding to today 00:00
|
|
||||||
now = DateTime.now(DateTimeZone.UTC).withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0);
|
|
||||||
}
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", timeZone);
|
|
||||||
DynamicIndexName indexNames = parser.parse("<.marvel-{now/d{YYYY.MM.dd}}>");
|
|
||||||
String name = indexNames.name(now);
|
|
||||||
logger.info("timezone: [{}], now [{}], name: [{}]", timeZone, now, name);
|
|
||||||
assertThat(name, equalTo(".marvel-" + DateTimeFormat.forPattern("YYYY.MM.dd").print(now.withZone(timeZone))));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpression_CustomTimeZone_OnParse() throws Exception {
|
|
||||||
DateTimeZone timeZone;
|
|
||||||
int hoursOffset;
|
|
||||||
int minutesOffset = 0;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
hoursOffset = randomIntBetween(-12, 14);
|
|
||||||
timeZone = DateTimeZone.forOffsetHours(hoursOffset);
|
|
||||||
} else {
|
|
||||||
hoursOffset = randomIntBetween(-11, 13);
|
|
||||||
minutesOffset = randomIntBetween(0, 59);
|
|
||||||
timeZone = DateTimeZone.forOffsetHoursMinutes(hoursOffset, minutesOffset);
|
|
||||||
}
|
|
||||||
DateTime now;
|
|
||||||
if (hoursOffset >= 0) {
|
|
||||||
// rounding to next day 00:00
|
|
||||||
now = DateTime.now(DateTimeZone.UTC).plusHours(hoursOffset).plusMinutes(minutesOffset).withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0);
|
|
||||||
} else {
|
|
||||||
// rounding to today 00:00
|
|
||||||
now = DateTime.now(DateTimeZone.UTC).withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0);
|
|
||||||
}
|
|
||||||
Settings settings = Settings.builder()
|
|
||||||
.put("watcher.dynamic_indices.default_date_format", "YYYY.MM.dd")
|
|
||||||
.put("watcher.dynamic_indices.time_zone", "-12")
|
|
||||||
.put("watcher.foo.dynamic_indices.time_zone", "-12")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser(settings, "watcher.foo");
|
|
||||||
DynamicIndexName indexNames = parser.parse("<.marvel-{now/d{YYYY.MM.dd}}>", timeZone);
|
|
||||||
String name = indexNames.name(now);
|
|
||||||
logger.info("timezone: [{}], now [{}], name: [{}]", timeZone, now, name);
|
|
||||||
assertThat(name, equalTo(".marvel-" + DateTimeFormat.forPattern("YYYY.MM.dd").print(now.withZone(timeZone))));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpression_EscapeStatic() throws Exception {
|
|
||||||
DateTime now = DateTime.now(DateTimeZone.UTC);
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
DynamicIndexName indexNames = parser.parse("<.mar\\{v\\}el-{now/d}>");
|
|
||||||
String name = indexNames.name(now);
|
|
||||||
assertThat(name, equalTo(".mar{v}el-" + DateTimeFormat.forPattern("YYYY.MM.dd").print(now)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpression_EscapeDateFormat() throws Exception {
|
|
||||||
DateTime now = DateTime.now(DateTimeZone.UTC);
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
DynamicIndexName indexNames = parser.parse("<.marvel-{now/d{'\\{year\\}'YYYY}}>");
|
|
||||||
String name = indexNames.name(now);
|
|
||||||
assertThat(name, equalTo(".marvel-" + DateTimeFormat.forPattern("'{year}'YYYY").print(now)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExpression_MixedArray() throws Exception {
|
|
||||||
DateTime now = DateTime.now(DateTimeZone.UTC);
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
DynamicIndexName[] indexNames = parser.parse(new String[] {
|
|
||||||
"name1",
|
|
||||||
"<.marvel-{now/d}>",
|
|
||||||
"name2",
|
|
||||||
"<.logstash-{now/M{YYYY.MM}}>"
|
|
||||||
});
|
|
||||||
String[] names = new String[indexNames.length];
|
|
||||||
for (int i = 0; i < names.length; i++) {
|
|
||||||
names[i] = indexNames[i].name(now);
|
|
||||||
}
|
|
||||||
assertThat(names.length, is(4));
|
|
||||||
assertThat(names, arrayContaining(
|
|
||||||
"name1",
|
|
||||||
".marvel-" + DateTimeFormat.forPattern("YYYY.MM.dd").print(now),
|
|
||||||
"name2",
|
|
||||||
".logstash-" + DateTimeFormat.forPattern("YYYY.MM").print(now.withDayOfMonth(1))));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = ElasticsearchParseException.class)
|
|
||||||
public void testExpression_Invalid_Unescaped() throws Exception {
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
parser.parse("<.mar}vel-{now/d}>");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = ElasticsearchParseException.class)
|
|
||||||
public void testExpression_Invalid_DateMathFormat() throws Exception {
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
parser.parse("<.marvel-{now/d{}>");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = ElasticsearchParseException.class)
|
|
||||||
public void testExpression_Invalid_EmptyDateMathFormat() throws Exception {
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
parser.parse("<.marvel-{now/d{}}>");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = ElasticsearchParseException.class)
|
|
||||||
public void testExpression_Invalid_OpenEnded() throws Exception {
|
|
||||||
DynamicIndexName.Parser parser = new DynamicIndexName.Parser("YYYY.MM.dd", DateTimeZone.UTC);
|
|
||||||
parser.parse("<.marvel-{now/d>");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefaultDateFormat_Default() throws Exception {
|
|
||||||
String dateFormat = DynamicIndexName.defaultDateFormat(Settings.EMPTY);
|
|
||||||
assertThat(dateFormat, is("YYYY.MM.dd"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefaultDateFormat() throws Exception {
|
|
||||||
Settings settings = Settings.builder()
|
|
||||||
.put("watcher.dynamic_indices.default_date_format", "YYYY.MM")
|
|
||||||
.build();
|
|
||||||
String dateFormat = randomBoolean() ?
|
|
||||||
DynamicIndexName.defaultDateFormat(settings) :
|
|
||||||
DynamicIndexName.defaultDateFormat(settings, null);
|
|
||||||
assertThat(dateFormat, is("YYYY.MM"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefaultDateFormat_Component() throws Exception {
|
|
||||||
Settings settings = Settings.builder()
|
|
||||||
.put("watcher.dynamic_indices.default_date_format", "YYYY.MM")
|
|
||||||
.put("watcher.foo.dynamic_indices.default_date_format", "YYY.MM")
|
|
||||||
.build();
|
|
||||||
String dateFormat = DynamicIndexName.defaultDateFormat(settings, "watcher.foo");
|
|
||||||
assertThat(dateFormat, is("YYY.MM"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTimeZone_Default() throws Exception {
|
|
||||||
DateTimeZone timeZone = DynamicIndexName.timeZone(Settings.EMPTY);
|
|
||||||
assertThat(timeZone, is(DateTimeZone.UTC));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTimeZone() throws Exception {
|
|
||||||
DateTimeZone timeZone = DateTimeZone.forOffsetHours(randomIntBetween(-12, 14));
|
|
||||||
Settings settings = Settings.builder()
|
|
||||||
.put("watcher.dynamic_indices.time_zone", timeZone)
|
|
||||||
.build();
|
|
||||||
DateTimeZone resolvedTimeZone = randomBoolean() ?
|
|
||||||
DynamicIndexName.timeZone(settings) :
|
|
||||||
DynamicIndexName.timeZone(settings, null);
|
|
||||||
assertThat(timeZone, is(resolvedTimeZone));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTimeZone_Component() throws Exception {
|
|
||||||
DateTimeZone timeZone = DateTimeZone.forOffsetHours(randomIntBetween(-11, 14));
|
|
||||||
Settings settings = Settings.builder()
|
|
||||||
.put("watcher.dynamic_indices.time_zone", "-12")
|
|
||||||
.put("watcher.foo.dynamic_indices.time_zone", timeZone)
|
|
||||||
.build();
|
|
||||||
DateTimeZone resolvedTimeZone = DynamicIndexName.timeZone(settings, "watcher.foo");
|
|
||||||
assertThat(resolvedTimeZone, is(timeZone));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -74,7 +74,6 @@ public class HttpClientTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
||||||
public void testBasics() throws Exception {
|
public void testBasics() throws Exception {
|
||||||
int responseCode = randomIntBetween(200, 203);
|
int responseCode = randomIntBetween(200, 203);
|
||||||
String body = randomAsciiOfLengthBetween(2, 8096);
|
String body = randomAsciiOfLengthBetween(2, 8096);
|
||||||
|
@ -127,6 +126,23 @@ public class HttpClientTests extends ESTestCase {
|
||||||
assertThat(recordedRequest.getBody().readUtf8Line(), nullValue());
|
assertThat(recordedRequest.getBody().readUtf8Line(), nullValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUrlEncoding() throws Exception{
|
||||||
|
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
|
||||||
|
HttpRequest.Builder requestBuilder = HttpRequest.builder("localhost", webPort)
|
||||||
|
.method(HttpMethod.GET)
|
||||||
|
.path("/test")
|
||||||
|
.setParam("key", "value 123:123");
|
||||||
|
|
||||||
|
HttpResponse response = httpClient.execute(requestBuilder.build());
|
||||||
|
assertThat(response.status(), equalTo(200));
|
||||||
|
assertThat(response.body().toUtf8(), equalTo("body"));
|
||||||
|
|
||||||
|
RecordedRequest recordedRequest = webServer.takeRequest();
|
||||||
|
assertThat(recordedRequest.getPath(), equalTo("/test?key=value%20123:123"));
|
||||||
|
assertThat(recordedRequest.getBody().readUtf8Line(), nullValue());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuth() throws Exception {
|
public void testBasicAuth() throws Exception {
|
||||||
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
|
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
|
||||||
|
|
|
@ -41,7 +41,6 @@ import org.elasticsearch.watcher.input.search.ExecutableSearchInput;
|
||||||
import org.elasticsearch.watcher.input.simple.ExecutableSimpleInput;
|
import org.elasticsearch.watcher.input.simple.ExecutableSimpleInput;
|
||||||
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
||||||
import org.elasticsearch.watcher.license.LicenseService;
|
import org.elasticsearch.watcher.license.LicenseService;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.Script;
|
import org.elasticsearch.watcher.support.Script;
|
||||||
import org.elasticsearch.watcher.support.WatcherUtils;
|
import org.elasticsearch.watcher.support.WatcherUtils;
|
||||||
import org.elasticsearch.watcher.support.http.HttpClient;
|
import org.elasticsearch.watcher.support.http.HttpClient;
|
||||||
|
@ -69,7 +68,6 @@ import org.joda.time.DateTime;
|
||||||
|
|
||||||
import javax.mail.internet.AddressException;
|
import javax.mail.internet.AddressException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -222,7 +220,7 @@ public final class WatcherTestUtils {
|
||||||
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? *")),
|
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? *")),
|
||||||
new ExecutableSimpleInput(new SimpleInput(new Payload.Simple(inputData)), logger),
|
new ExecutableSimpleInput(new SimpleInput(new Payload.Simple(inputData)), logger),
|
||||||
new ExecutableScriptCondition(new ScriptCondition(Script.inline("return true").build()), logger, scriptService),
|
new ExecutableScriptCondition(new ScriptCondition(Script.inline("return true").build()), logger, scriptService),
|
||||||
new ExecutableSearchTransform(new SearchTransform(transformRequest, null, null), logger, client, null, new DynamicIndexName.Parser()),
|
new ExecutableSearchTransform(new SearchTransform(transformRequest, null, null), logger, client, null),
|
||||||
new TimeValue(0),
|
new TimeValue(0),
|
||||||
new ExecutableActions(actions),
|
new ExecutableActions(actions),
|
||||||
metadata,
|
metadata,
|
||||||
|
|
|
@ -30,7 +30,6 @@ import org.elasticsearch.watcher.execution.TriggeredExecutionContext;
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.watcher.input.simple.ExecutableSimpleInput;
|
import org.elasticsearch.watcher.input.simple.ExecutableSimpleInput;
|
||||||
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.watcher.support.text.TextTemplate;
|
import org.elasticsearch.watcher.support.text.TextTemplate;
|
||||||
import org.elasticsearch.watcher.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
|
@ -42,8 +41,6 @@ import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.watcher.watch.Watch;
|
import org.elasticsearch.watcher.watch.Watch;
|
||||||
import org.elasticsearch.watcher.watch.WatchStatus;
|
import org.elasticsearch.watcher.watch.WatchStatus;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
import org.joda.time.format.DateTimeFormat;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -128,7 +125,7 @@ public class SearchTransformTests extends ESIntegTestCase {
|
||||||
.endObject()
|
.endObject()
|
||||||
.endObject().bytes());
|
.endObject().bytes());
|
||||||
SearchTransform searchTransform = TransformBuilders.searchTransform(request).build();
|
SearchTransform searchTransform = TransformBuilders.searchTransform(request).build();
|
||||||
ExecutableSearchTransform transform = new ExecutableSearchTransform(searchTransform, logger, ClientProxy.of(client()), null, new DynamicIndexName.Parser());
|
ExecutableSearchTransform transform = new ExecutableSearchTransform(searchTransform, logger, ClientProxy.of(client()), null);
|
||||||
|
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
||||||
|
|
||||||
|
@ -165,7 +162,7 @@ public class SearchTransformTests extends ESIntegTestCase {
|
||||||
.endObject()
|
.endObject()
|
||||||
.endObject().bytes());
|
.endObject().bytes());
|
||||||
SearchTransform searchTransform = TransformBuilders.searchTransform(request).build();
|
SearchTransform searchTransform = TransformBuilders.searchTransform(request).build();
|
||||||
ExecutableSearchTransform transform = new ExecutableSearchTransform(searchTransform, logger, ClientProxy.of(client()), null, new DynamicIndexName.Parser());
|
ExecutableSearchTransform transform = new ExecutableSearchTransform(searchTransform, logger, ClientProxy.of(client()), null);
|
||||||
|
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
||||||
|
|
||||||
|
@ -211,7 +208,7 @@ public class SearchTransformTests extends ESIntegTestCase {
|
||||||
.must(termQuery("value", "{{ctx.payload.value}}"))));
|
.must(termQuery("value", "{{ctx.payload.value}}"))));
|
||||||
|
|
||||||
SearchTransform searchTransform = TransformBuilders.searchTransform(request).build();
|
SearchTransform searchTransform = TransformBuilders.searchTransform(request).build();
|
||||||
ExecutableSearchTransform transform = new ExecutableSearchTransform(searchTransform, logger, ClientProxy.of(client()), null, new DynamicIndexName.Parser());
|
ExecutableSearchTransform transform = new ExecutableSearchTransform(searchTransform, logger, ClientProxy.of(client()), null);
|
||||||
|
|
||||||
ScheduleTriggerEvent event = new ScheduleTriggerEvent("_name", parseDate("2015-01-04T00:00:00", UTC), parseDate("2015-01-01T00:00:00", UTC));
|
ScheduleTriggerEvent event = new ScheduleTriggerEvent("_name", parseDate("2015-01-04T00:00:00", UTC), parseDate("2015-01-01T00:00:00", UTC));
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", parseDate("2015-01-04T00:00:00", UTC), event, EMPTY_PAYLOAD);
|
WatchExecutionContext ctx = mockExecutionContext("_name", parseDate("2015-01-04T00:00:00", UTC), event, EMPTY_PAYLOAD);
|
||||||
|
@ -303,68 +300,6 @@ public class SearchTransformTests extends ESIntegTestCase {
|
||||||
assertThat(executable.transform().getTimeout(), equalTo(readTimeout));
|
assertThat(executable.transform().getTimeout(), equalTo(readTimeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testParser_WithIndexNames() throws Exception {
|
|
||||||
SearchType searchType = getRandomSupportedSearchType();
|
|
||||||
XContentBuilder builder = jsonBuilder().startObject();
|
|
||||||
builder.startObject("request");
|
|
||||||
builder.array("indices", "idx", "<idx-{now/d-3d}>");
|
|
||||||
if (searchType != null) {
|
|
||||||
builder.field("search_type", searchType.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
DateTime now = DateTime.now(UTC);
|
|
||||||
DateTimeZone timeZone = randomBoolean() ? DateTimeZone.forOffsetHours(-2) : null;
|
|
||||||
if (timeZone != null) {
|
|
||||||
now = now.withHourOfDay(0).withMinuteOfHour(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.startObject("body")
|
|
||||||
.startObject("query")
|
|
||||||
.startObject("match_all")
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject();
|
|
||||||
builder.endObject();
|
|
||||||
|
|
||||||
boolean timeZoneInWatch = randomBoolean();
|
|
||||||
if (timeZone != null && timeZoneInWatch) {
|
|
||||||
builder.field(SearchTransform.Field.DYNAMIC_NAME_TIMEZONE.getPreferredName(), timeZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.endObject();
|
|
||||||
|
|
||||||
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
|
||||||
parser.nextToken();
|
|
||||||
|
|
||||||
String dateFormat;
|
|
||||||
Settings.Builder settingsBuilder = Settings.builder();
|
|
||||||
if (randomBoolean()) {
|
|
||||||
dateFormat = DynamicIndexName.DEFAULT_DATE_FORMAT;
|
|
||||||
} else {
|
|
||||||
dateFormat = "YYYY-MM";
|
|
||||||
settingsBuilder.put("watcher.transform.search.dynamic_indices.default_date_format", dateFormat);
|
|
||||||
}
|
|
||||||
if (timeZone != null && !timeZoneInWatch) {
|
|
||||||
settingsBuilder.put("watcher.transform.search.dynamic_indices.time_zone", timeZone);
|
|
||||||
}
|
|
||||||
Settings settings = settingsBuilder.build();
|
|
||||||
|
|
||||||
SearchTransformFactory transformFactory = new SearchTransformFactory(settings, ClientProxy.of(client()));
|
|
||||||
|
|
||||||
ExecutableSearchTransform executable = transformFactory.parseExecutable("_id", parser);
|
|
||||||
DynamicIndexName[] indexNames = executable.indexNames();
|
|
||||||
assertThat(indexNames, notNullValue());
|
|
||||||
|
|
||||||
String[] names = DynamicIndexName.names(indexNames, now);
|
|
||||||
assertThat(names, notNullValue());
|
|
||||||
assertThat(names.length, is(2));
|
|
||||||
if (timeZone != null) {
|
|
||||||
now = now.withZone(timeZone);
|
|
||||||
}
|
|
||||||
assertThat(names, arrayContaining("idx", "idx-" + DateTimeFormat.forPattern(dateFormat).print(now.minusDays(3))));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearch_InlineTemplate() throws Exception {
|
public void testSearch_InlineTemplate() throws Exception {
|
||||||
WatchExecutionContext ctx = createContext();
|
WatchExecutionContext ctx = createContext();
|
||||||
|
@ -501,7 +436,7 @@ public class SearchTransformTests extends ESIntegTestCase {
|
||||||
ensureGreen("test-search-index");
|
ensureGreen("test-search-index");
|
||||||
|
|
||||||
SearchTransform searchTransform = TransformBuilders.searchTransform(request).build();
|
SearchTransform searchTransform = TransformBuilders.searchTransform(request).build();
|
||||||
ExecutableSearchTransform executableSearchTransform = new ExecutableSearchTransform(searchTransform, logger, ClientProxy.of(client()), null, new DynamicIndexName.Parser());
|
ExecutableSearchTransform executableSearchTransform = new ExecutableSearchTransform(searchTransform, logger, ClientProxy.of(client()), null);
|
||||||
|
|
||||||
return executableSearchTransform.execute(ctx, Payload.Simple.EMPTY);
|
return executableSearchTransform.execute(ctx, Payload.Simple.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class IntervalScheduleTests extends ESTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParse_String() throws Exception {
|
public void testParse_String() throws Exception {
|
||||||
IntervalSchedule.Interval value = randomTimeValue();
|
IntervalSchedule.Interval value = randomTimeInterval();
|
||||||
XContentBuilder builder = jsonBuilder().value(value);
|
XContentBuilder builder = jsonBuilder().value(value);
|
||||||
BytesReference bytes = builder.bytes();
|
BytesReference bytes = builder.bytes();
|
||||||
XContentParser parser = JsonXContent.jsonXContent.createParser(bytes);
|
XContentParser parser = JsonXContent.jsonXContent.createParser(bytes);
|
||||||
|
@ -79,7 +79,7 @@ public class IntervalScheduleTests extends ESTestCase {
|
||||||
new IntervalSchedule.Parser().parse(parser);
|
new IntervalSchedule.Parser().parse(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IntervalSchedule.Interval randomTimeValue() {
|
private static IntervalSchedule.Interval randomTimeInterval() {
|
||||||
IntervalSchedule.Interval.Unit unit = IntervalSchedule.Interval.Unit.values()[randomIntBetween(0, IntervalSchedule.Interval.Unit.values().length - 1)];
|
IntervalSchedule.Interval.Unit unit = IntervalSchedule.Interval.Unit.values()[randomIntBetween(0, IntervalSchedule.Interval.Unit.values().length - 1)];
|
||||||
return new IntervalSchedule.Interval(randomIntBetween(1, 100), unit);
|
return new IntervalSchedule.Interval(randomIntBetween(1, 100), unit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,6 @@ import org.elasticsearch.watcher.input.simple.ExecutableSimpleInput;
|
||||||
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
import org.elasticsearch.watcher.input.simple.SimpleInput;
|
||||||
import org.elasticsearch.watcher.input.simple.SimpleInputFactory;
|
import org.elasticsearch.watcher.input.simple.SimpleInputFactory;
|
||||||
import org.elasticsearch.watcher.license.LicenseService;
|
import org.elasticsearch.watcher.license.LicenseService;
|
||||||
import org.elasticsearch.watcher.support.DynamicIndexName;
|
|
||||||
import org.elasticsearch.watcher.support.Script;
|
import org.elasticsearch.watcher.support.Script;
|
||||||
import org.elasticsearch.watcher.support.WatcherUtils;
|
import org.elasticsearch.watcher.support.WatcherUtils;
|
||||||
import org.elasticsearch.watcher.support.clock.Clock;
|
import org.elasticsearch.watcher.support.clock.Clock;
|
||||||
|
@ -149,7 +148,6 @@ public class WatchTests extends ESTestCase {
|
||||||
private SecretService secretService;
|
private SecretService secretService;
|
||||||
private LicenseService licenseService;
|
private LicenseService licenseService;
|
||||||
private ESLogger logger;
|
private ESLogger logger;
|
||||||
private DynamicIndexName.Parser indexNameParser;
|
|
||||||
private Settings settings = Settings.EMPTY;
|
private Settings settings = Settings.EMPTY;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -164,7 +162,6 @@ public class WatchTests extends ESTestCase {
|
||||||
licenseService = mock(LicenseService.class);
|
licenseService = mock(LicenseService.class);
|
||||||
authRegistry = new HttpAuthRegistry(ImmutableMap.of("basic", (HttpAuthFactory) new BasicAuthFactory(secretService)));
|
authRegistry = new HttpAuthRegistry(ImmutableMap.of("basic", (HttpAuthFactory) new BasicAuthFactory(secretService)));
|
||||||
logger = Loggers.getLogger(WatchTests.class);
|
logger = Loggers.getLogger(WatchTests.class);
|
||||||
indexNameParser = new DynamicIndexName.Parser();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -339,7 +336,7 @@ public class WatchTests extends ESTestCase {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SearchInput.TYPE:
|
case SearchInput.TYPE:
|
||||||
SearchInput searchInput = searchInput(WatcherTestUtils.newInputSearchRequest("idx")).build();
|
SearchInput searchInput = searchInput(WatcherTestUtils.newInputSearchRequest("idx")).build();
|
||||||
return new ExecutableSearchInput(searchInput, logger, client, null, indexNameParser);
|
return new ExecutableSearchInput(searchInput, logger, client, null);
|
||||||
default:
|
default:
|
||||||
SimpleInput simpleInput = InputBuilders.simpleInput(ImmutableMap.<String, Object>builder().put("_key", "_val")).build();
|
SimpleInput simpleInput = InputBuilders.simpleInput(ImmutableMap.<String, Object>builder().put("_key", "_val")).build();
|
||||||
return new ExecutableSimpleInput(simpleInput, logger);
|
return new ExecutableSimpleInput(simpleInput, logger);
|
||||||
|
@ -398,12 +395,12 @@ public class WatchTests extends ESTestCase {
|
||||||
case ScriptTransform.TYPE:
|
case ScriptTransform.TYPE:
|
||||||
return new ExecutableScriptTransform(new ScriptTransform(Script.inline("_script").build()), logger, scriptService);
|
return new ExecutableScriptTransform(new ScriptTransform(Script.inline("_script").build()), logger, scriptService);
|
||||||
case SearchTransform.TYPE:
|
case SearchTransform.TYPE:
|
||||||
return new ExecutableSearchTransform(new SearchTransform(matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS), timeout, timeZone), logger, client, null, indexNameParser);
|
return new ExecutableSearchTransform(new SearchTransform(matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS), timeout, timeZone), logger, client, null);
|
||||||
default: // chain
|
default: // chain
|
||||||
ChainTransform chainTransform = new ChainTransform(Arrays.asList(
|
ChainTransform chainTransform = new ChainTransform(Arrays.asList(
|
||||||
new SearchTransform(matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS), timeout, timeZone), new ScriptTransform(Script.inline("_script").build())));
|
new SearchTransform(matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS), timeout, timeZone), new ScriptTransform(Script.inline("_script").build())));
|
||||||
return new ExecutableChainTransform(chainTransform, logger, Arrays.<ExecutableTransform>asList(
|
return new ExecutableChainTransform(chainTransform, logger, Arrays.<ExecutableTransform>asList(
|
||||||
new ExecutableSearchTransform(new SearchTransform(matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS), timeout, timeZone), logger, client, null, indexNameParser),
|
new ExecutableSearchTransform(new SearchTransform(matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS), timeout, timeZone), logger, client, null),
|
||||||
new ExecutableScriptTransform(new ScriptTransform(Script.inline("_script").build()), logger, scriptService)));
|
new ExecutableScriptTransform(new ScriptTransform(Script.inline("_script").build()), logger, scriptService)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,7 +427,7 @@ public class WatchTests extends ESTestCase {
|
||||||
DateTimeZone timeZone = randomBoolean() ? DateTimeZone.UTC : null;
|
DateTimeZone timeZone = randomBoolean() ? DateTimeZone.UTC : null;
|
||||||
TimeValue timeout = randomBoolean() ? TimeValue.timeValueSeconds(30) : null;
|
TimeValue timeout = randomBoolean() ? TimeValue.timeValueSeconds(30) : null;
|
||||||
IndexAction action = new IndexAction("_index", "_type", null, timeout, timeZone);
|
IndexAction action = new IndexAction("_index", "_type", null, timeout, timeZone);
|
||||||
list.add(new ActionWrapper("_index_" + randomAsciiOfLength(8), randomThrottler(), randomTransform(), new ExecutableIndexAction(action, logger, client, null, indexNameParser)));
|
list.add(new ActionWrapper("_index_" + randomAsciiOfLength(8), randomThrottler(), randomTransform(), new ExecutableIndexAction(action, logger, client, null)));
|
||||||
}
|
}
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
HttpRequestTemplate httpRequest = HttpRequestTemplate.builder("test.host", randomIntBetween(8000, 9000))
|
HttpRequestTemplate httpRequest = HttpRequestTemplate.builder("test.host", randomIntBetween(8000, 9000))
|
||||||
|
|
Loading…
Reference in New Issue