ElasticSearch sollte nicht direkt aus dem Web erreichbar sein. Ein vorgeschalteter ApplicationServer sichert den Zugriff ab.
Grails ist schnell installiert, ein HowTo gibt es auf der Download-Seite.
Da für die aktuelle Version 3.x noch nicht alle/ausreichend Plugins verfügbar sind, sollte eine 2er Version installiert werden, z.B. 2.5.0.
apt-get install openjdk-7-jdk
export JAVA_HOME=/usr/lib/jvm/default-java
curl -s get.gvmtool.net | bash
source "$HOME/.gvm/bin/gvm-init.sh"
gvm install grails 2.5.0
export GRAILS_HOME="$HOME/.gvm/grails/current/"
export PATH=$GRAILS_HOME/bin:$PATH
grails -version
Ein neues Projekt ist schnell erstellt:
Da hier nur eine Art HTTP-Proxy erstellt wird, ist kein Daten-Backend notwendig:
Die Connection zu ElasticSearch soll das Grails-Rest-Plugin übernehmen:
Nun muss nur noch der Controller selbst geschrienen werden:
grails-app/controllers/elastic/ElasticController.groovy
package elastic
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.Method.POST
import static groovyx.net.http.ContentType.TEXT
import static groovyx.net.http.ContentType.JSON
@grails.validation.Validateable
class Elastic {
String query
Integer from = 0
Integer size = 5 // elasticsearch: size
static constraints = {
query size: 3..100, blank: false
from max:100
size max:10
}//constraints
}//Elastic
class ElasticController {
static allowedMethods = [index:['GET','POST']]
def search(Elastic elastic) {
if (!elastic.validate()) { render status:400; return; }
def http = new HTTPBuilder( 'http://localhost:9200' )
http.request( POST, JSON ) { req ->
uri.path = '/wiki/_search'//?size=0'
uri.query= [
size : elastic?.size,
pretty: 0,
from : elastic?.from,
fields: "abstract,author,date,keywords,title,url"
]
body = [
query : [
simple_query_string : [
query : elastic?.query,
default_operator: "and"
]
]
]
response.success = { resp, json ->
render(contentType: "application/json"){ json.hits }
}//response.success
}//http.request
}//index
}//ElasticController
Um das ganze zu testen, muss der Grails-App-Server gestartet werden:
Testen kann man nun z.B. mit curl
:
# JSON POST:
curl -H 'Content-Type: application/json' -H'X-Requested-With: XMLHttpRequest' -i -XPOST http://localhost:8080/elastic/elastic/search -d '{"query":"foo +bar"}'
# URL-encoded POST
curl -i -XPOST http://localhost:8080/elastic/elastic/search -d 'query=foo +bar&size=5&from=0'
# GET
curl -i -XGET 'http://localhost:8080/elastic/elastic/search?query=foo%20+bar&from=1&size=1'
Wenn alles funktioniert, nur noch ein WAR-File für den Tomcat bauen und auf den Produktiv-Server deployen:
Natürlich soll auch der Application-Server nicht direkt aus dem Web erreichbar sein. Einfach einen NginX oder ähnliches aul Proxy vorschalten:
/etc/nginx/sites-enabled/mysite
...
location /search/ {
if ($request_method !~ ^(GET|HEAD|POST)$ ){ return 405; }
if ($request_method ~ ^(HEAD)$ ){ return 200 '{"status":200}'; }
disable_symlinks on;
include /etc/nginx/proxy_params;
proxy_intercept_errors on;
proxy_pass http://127.0.0.1:8080/elastic/elastic/search;
proxy_redirect default;
}
...