Skip to content
This repository was archived by the owner on Dec 11, 2024. It is now read-only.

Commit 357d171

Browse files
committed
Merge pull request #143 from marcoscarceles/elasticsearch-2.1.2
Elasticsearch 2.1.2
2 parents 23cb44c + edc4a31 commit 357d171

23 files changed

+337
-174
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@ web-app
88
*.log
99
*.zip
1010
plugin.xml
11-
/docs
11+
/docs
12+
13+
# Elasticsearch plugins installation
14+
test/resources/plugins

ElasticsearchGrailsPlugin.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class ElasticsearchGrailsPlugin {
3636

3737
private static final Logger LOG = LoggerFactory.getLogger(this)
3838

39-
def version = '0.0.4.x-SNAPSHOT'
39+
def version = '0.1.0'
4040
def grailsVersion = '2.2.0 > *'
4141

4242
def loadAfter = ['services', 'mongodb']

README.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Edit your project's +BuildConfig.groovy+ file, by adding the plugin's dependency
1616
----
1717
grails.project.dependency.resolution = {
1818
plugins {
19-
runtime ':elasticsearch:0.0.4.6'
19+
runtime ':elasticsearch:0.1.0'
2020
}
2121
}
2222
----

application.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#Grails Metadata file
2-
#Tue Apr 21 20:14:27 CST 2015
3-
app.grails.version=2.4.4
2+
#Wed Feb 17 12:24:47 CET 2016
3+
app.grails.version=2.4.5
44
app.name=elasticsearch

grails-app/conf/BuildConfig.groovy

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,25 @@ grails.project.dependency.resolution = {
4040
"org.grails:grails-datastore-core:$datastoreVersion",
4141
"org.grails:grails-datastore-web:$datastoreVersion", excludes)
4242

43-
runtime 'org.elasticsearch:elasticsearch-groovy:1.6.0', {
43+
runtime 'org.elasticsearch:elasticsearch-groovy:2.1.2', {
4444
excludes 'groovy-all'
4545
}
46-
runtime "org.elasticsearch:elasticsearch-mapper-attachments:2.6.0"
46+
runtime "org.elasticsearch:elasticsearch-mapper-attachments:3.1.2"
4747
runtime 'com.spatial4j:spatial4j:0.4.1'
4848

4949
compile 'com.vividsolutions:jts:1.13'
5050

5151
test 'com.googlecode.json-simple:json-simple:1.1.1'
52+
53+
//BUG: Elasticsearch 2.1.2 does not explictly sets a version of jackson libraries (but needs >2.6), so grails will pick up the latest from any other plugin/dependency
54+
def jacksonVersion = '2.6.2'
55+
compile "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}"
56+
compile "com.fasterxml.jackson.dataformat:jackson-dataformat-smile:${jacksonVersion}"
57+
compile "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${jacksonVersion}"
58+
compile "com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:${jacksonVersion}"
59+
60+
def nettyVersion = '3.10.5.Final'
61+
compile "io.netty:netty:${nettyVersion}"
5262
}
5363

5464
plugins {

grails-app/conf/Config.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ environments {
5151
datastoreImpl = 'hibernateDatastore'
5252

5353
index {
54-
store.type = 'memory'
54+
store.type = 'simplefs'
5555
analysis {
5656
filter {
5757
replace_synonyms {
@@ -78,6 +78,8 @@ environments {
7878
}
7979
}
8080
}
81+
82+
path.plugins = 'test/resources/plugins'
8183
}
8284
}
8385

grails-app/conf/DefaultElasticSearch.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ environments {
111111
test {
112112
elasticSearch {
113113
client.mode = 'local'
114-
index.store.type = 'memory' // store local node in memory and not on disk
114+
index.store.type = 'simplefs' // store local node in memory and not on disk
115115
}
116116
}
117117
production {

grails-app/domain/test/upperCase/UpperCase.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package test.upperCase
22

33
class UpperCase {
4-
def name;
4+
String name;
55
static mapping = {
66

77
autoImport(false)

grails-app/services/org/grails/plugins/elasticsearch/ElasticSearchAdminService.groovy

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ package org.grails.plugins.elasticsearch
22

33
import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest
44
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse
5+
import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus
56
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest
67
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder
78
import org.elasticsearch.action.admin.indices.exists.types.TypesExistsRequest
8-
import org.elasticsearch.action.admin.indices.mapping.delete.DeleteMappingRequest
99
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest
10-
import org.elasticsearch.action.support.broadcast.BroadcastOperationResponse
10+
import org.elasticsearch.action.support.broadcast.BroadcastResponse
1111
import org.elasticsearch.client.Client
1212
import org.elasticsearch.client.Requests
1313
import org.grails.plugins.elasticsearch.mapping.SearchableClassMapping
@@ -43,7 +43,7 @@ class ElasticSearchAdminService {
4343

4444
// Refresh ES
4545
elasticSearchHelper.withElasticSearch { Client client ->
46-
BroadcastOperationResponse response
46+
BroadcastResponse response
4747
if (!indices) {
4848
response = client.admin().indices().refresh(Requests.refreshRequest()).actionGet()
4949
} else {
@@ -134,21 +134,6 @@ class ElasticSearchAdminService {
134134
}
135135
}
136136

137-
/**
138-
* Deletes a mapping on an index
139-
* @param index The index the mapping will be deleted on
140-
* @param type The type which mapping will be deleted
141-
*/
142-
void deleteMapping(String index, String type) {
143-
log.info("Deleting Elasticsearch mapping for ${index} and type ${type} ...")
144-
elasticSearchHelper.withElasticSearch { Client client ->
145-
client.admin().indices().deleteMapping(
146-
new DeleteMappingRequest(index).
147-
types(type)
148-
).actionGet()
149-
}
150-
}
151-
152137
/**
153138
* Creates mappings on a type
154139
* @param index The index where the mapping is being created
@@ -167,7 +152,7 @@ class ElasticSearchAdminService {
167152
}
168153

169154
/**
170-
* Check whether a mpping exists
155+
* Check whether a mapping exists
171156
* @param index The name of the index to check on
172157
* @param type The type which mapping is being checked
173158
* @return true if the mapping exists
@@ -252,7 +237,7 @@ class ElasticSearchAdminService {
252237
String indexPointedBy(String alias) {
253238
elasticSearchHelper.withElasticSearch { Client client ->
254239
def index = client.admin().indices().getAliases(new GetAliasesRequest().aliases([alias] as String[])).actionGet().getAliases()?.find {
255-
it.value.element.alias() == alias
240+
alias in it.value*.alias()
256241
}?.key
257242
if (!index) {
258243
LOG.debug("Alias ${alias} does not exist")
@@ -362,31 +347,12 @@ class ElasticSearchAdminService {
362347
}
363348

364349
/**
365-
* Waits for an index to be on Yellow status
366-
* @param index
367-
* @return
368-
*/
369-
def waitForIndex(index) {
370-
elasticSearchHelper.withElasticSearch { Client client ->
371-
try {
372-
LOG.debug("Waiting at least yellow status on ${index}")
373-
client.admin().cluster().prepareHealth(index)
374-
.setWaitForYellowStatus()
375-
.execute().actionGet()
376-
} catch (Exception e) {
377-
// ignore any exceptions due to non-existing index.
378-
LOG.debug('Index health', e)
379-
}
380-
}
381-
}
382-
383-
/**
384-
* Waits for the cluster to be on Yellow status
350+
* Waits for the cluster to be on (Yellow) status
385351
*/
386-
void waitForClusterYellowStatus() {
352+
void waitForClusterStatus(ClusterHealthStatus status=ClusterHealthStatus.YELLOW) {
387353
elasticSearchHelper.withElasticSearch { Client client ->
388354
ClusterHealthResponse response = client.admin().cluster().health(
389-
new ClusterHealthRequest([] as String[]).waitForYellowStatus()).actionGet()
355+
new ClusterHealthRequest([] as String[]).waitForStatus(status)).actionGet()
390356
LOG.debug("Cluster status: ${response.status}")
391357
}
392358
}

grails-app/services/org/grails/plugins/elasticsearch/ElasticSearchService.groovy

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.grails.plugins.elasticsearch
1717

18+
import groovy.transform.CompileStatic
1819
import org.codehaus.groovy.grails.commons.GrailsApplication
1920
import org.codehaus.groovy.grails.plugins.support.aware.GrailsApplicationAware
2021
import org.elasticsearch.action.count.CountRequest
@@ -23,8 +24,8 @@ import org.elasticsearch.action.search.SearchType
2324
import org.elasticsearch.action.support.QuerySourceBuilder
2425
import org.elasticsearch.client.Client
2526
import org.elasticsearch.index.query.QueryBuilder
27+
import org.elasticsearch.index.query.QueryBuilders
2628
import org.elasticsearch.index.query.QueryStringQueryBuilder
27-
import org.elasticsearch.index.query.FilterBuilder
2829
import org.elasticsearch.search.SearchHit
2930
import org.elasticsearch.search.builder.SearchSourceBuilder
3031
import org.elasticsearch.search.highlight.HighlightBuilder
@@ -35,7 +36,7 @@ import org.grails.plugins.elasticsearch.util.GXContentBuilder
3536
import org.slf4j.Logger
3637
import org.slf4j.LoggerFactory
3738

38-
import static org.elasticsearch.index.query.QueryBuilders.queryString
39+
import static org.elasticsearch.index.query.QueryBuilders.queryStringQuery
3940
import static org.elasticsearch.index.query.QueryStringQueryBuilder.Operator
4041

4142
class ElasticSearchService implements GrailsApplicationAware {
@@ -336,7 +337,7 @@ class ElasticSearchService implements GrailsApplicationAware {
336337
request.source(new GXContentBuilder().buildAsBytes(query))
337338
} else {
338339
Operator defaultOperator = params['default_operator'] ?: Operator.AND
339-
QueryStringQueryBuilder builder = queryString(query).defaultOperator(defaultOperator)
340+
QueryStringQueryBuilder builder = queryStringQuery(query).defaultOperator(defaultOperator)
340341
if (params.analyzer) {
341342
builder.analyzer(params.analyzer)
342343
}
@@ -351,7 +352,7 @@ class ElasticSearchService implements GrailsApplicationAware {
351352
*
352353
* @param params The query parameters
353354
* @param query The search query, whether a String, a Closure or a QueryBuilder
354-
* @param filter The search filter, whether a Closure or a FilterBuilder
355+
* @param filter The search filter, whether a Closure or a QueryBuilder
355356
* @return The SearchRequest instance
356357
*/
357358
private SearchRequest buildSearchRequest(query, filter, Map params) {
@@ -404,7 +405,7 @@ class ElasticSearchService implements GrailsApplicationAware {
404405

405406
SearchSourceBuilder setQueryInSource(SearchSourceBuilder source, String query, Map params = [:]) {
406407
Operator defaultOperator = params['default_operator'] ?: Operator.AND
407-
QueryStringQueryBuilder builder = queryString(query).defaultOperator(defaultOperator)
408+
QueryStringQueryBuilder builder = queryStringQuery(query).defaultOperator(defaultOperator)
408409
if (params.analyzer) {
409410
builder.analyzer(params.analyzer)
410411
}
@@ -423,7 +424,7 @@ class ElasticSearchService implements GrailsApplicationAware {
423424
source.postFilter(new GXContentBuilder().buildAsBytes(filter))
424425
}
425426

426-
SearchSourceBuilder setFilterInSource(SearchSourceBuilder source, FilterBuilder filter, Map params = [:]){
427+
SearchSourceBuilder setFilterInSource(SearchSourceBuilder source, QueryBuilder filter, Map params = [:]){
427428
source.postFilter(filter)
428429
}
429430

scripts/_Events.groovy

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,54 @@
11
import org.apache.commons.io.FileUtils
22

3+
eventAllTestsStart = { msg ->
4+
File pluginsDir = new File('test/resources/plugins')
5+
6+
Map<String, String> elasticsearchPlugins = [
7+
'elasticsearch-mapper-attachments' : '3.1.2'
8+
]
9+
10+
if (!pluginsDir.exists()) {
11+
12+
println "Installing Elasticsearch Plugins ..."
13+
14+
pluginsDir.mkdirs()
15+
16+
elasticsearchPlugins.each { pluginName, pluginVersion ->
17+
18+
String versionedPluginName = "${pluginName}-${pluginVersion}"
19+
String artifactURL = "http://search.maven.org/remotecontent?filepath=org/elasticsearch/${pluginName}/${pluginVersion}/${versionedPluginName}.zip"
20+
21+
//Download handling redirects
22+
File tmpZip = new File(pluginsDir, "${versionedPluginName}.zip")
23+
while( artifactURL ) {
24+
artifactURL.toURL().openConnection().with { conn ->
25+
conn.instanceFollowRedirects = false
26+
artifactURL = conn.getHeaderField( "Location" )
27+
if( !artifactURL ) {
28+
tmpZip.withOutputStream { out ->
29+
conn.inputStream.with { inp ->
30+
out << inp
31+
inp.close()
32+
}
33+
}
34+
}
35+
}
36+
}
37+
38+
//Explode the plugin
39+
File explodedPlugin = new File(pluginsDir, versionedPluginName)
40+
explodedPlugin.mkdirs()
41+
new AntBuilder().unzip(src: tmpZip.path, dest: explodedPlugin.path, overwrite: false)
42+
43+
//Delete downloaded file
44+
tmpZip.delete()
45+
println "Elasticsearch Plugin : ${versionedPluginName} INSTALLED!"
46+
}
47+
48+
49+
}
50+
}
51+
352
eventTestCaseStart = { name ->
453
println '-' * 60
554
println "| $name : started"

src/docs/guide/introduction/history.gdoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
h4. History
22

3+
* February 24, 2016
4+
** 0.1.0
5+
*** Upgrade to ElasticSearch 2.1.2 - This is a breaking upgrade, please refer to:
6+
**** [Breaking changes in 2.1|https://www.elastic.co/guide/en/elasticsearch/reference/2.1/breaking-changes-2.1.html]
7+
**** [Breaking changes in 2.0|https://www.elastic.co/guide/en/elasticsearch/reference/2.1/breaking-changes-2.0.html]
8+
**** New @deleteIndex@ migration strategy (although @alias@ is still the recommended one)
9+
**** The @delete@ migration strategy has been deprecated and it not behaves as the @none@ migration strategy
310
* June 30, 2015
411
** 0.0.4.5
512
*** Upgrade to ElasticSearch 1.6.0

src/docs/guide/mapping/mappingMigrations.gdoc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ h3. Migration Strategies
66
The migration strategy is defined by the @elasticSearch.migration.strategy@ configuration property and it accepts three values:
77

88
- @'none'@
9-
- @'delete'@
9+
- @'deleteIndex'@
10+
- --@'delete'@-- _is no longer supported since the upgrade to Elasticsearch > 2.0_
1011
- @'alias'@
1112

1213
The default strategy is @'alias'@ as it is the only strategy that can achieve zero-downtime migrations and thus [recommended by Elasticsearch|http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/]
@@ -19,11 +20,11 @@ This option keeps the original behaviour the plugin used before the Migration St
1920
It will be responsability for the application administrator to manually fix the problem.
2021
This configuration was left as a backwards compatibility and it will prevent the application from booting successfully, therefore we *discourage teams from using this option*.
2122

22-
h4. Migration Strategy 'delete'
23+
h4. Migration Strategy 'deleteIndex'
2324

24-
When choosing this option, when a conflict occurs installing mapping, the application will delete the existing mapping for the type, alongside with all content indexed on that index and type and recreated the mapping. There are a couple of important details on this information:
25-
- Only documents indexed on the conflicting mapping will be deleted, any other document on a different mapping on the same (or other) index will remain untouched.
25+
When choosing this option, when a conflict occurs installing mapping, the application will delete the existing index for the type, *alongside with all content indexed on that index (including content from other mappings)* and it will recreate the index and all its mappings. There are a couple of important details on this information:
2626
- Deleted documents can be automatically reindexed on startup by using the @elasticSearch.bulkIndexOnStartup@ configuration property (See below)
27+
- New indices will be created with a version number and the rightaliases, to make them compatible with potential future 'alias' migrations (without requiring additional index deletions)
2728
- Using this configuration there will always be a time window (between deletion and reindexation) where documents can't be found by search, therefore this option cannot achieve a *zero-downtime* deployment
2829

2930
See [Dealing with deleted content] below for more details on automatic indexing.

0 commit comments

Comments
 (0)