/*
* ModeShape (http://www.modeshape.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.modeshape.jcr.index.elasticsearch.client;
import java.io.IOException;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.modeshape.schematic.document.Document;
import org.modeshape.jcr.index.elasticsearch.query.MatchAllQuery;
/**
* HTTP-based interface for the Elasticsearch engine.
*
* @author kulikov
*/
public class EsClient {
private final String host;
private final int port;
/**
* Creates new instance.
*
* @param host the address of the ES engine.
* @param port the port number of ES engine.
*/
public EsClient(String host, int port) {
this.host = host;
this.port = port;
}
/**
* Tests for the index existence with specified name.
*
* @param name the name of the index to test.
* @return true if index with given name exists and false otherwise.
* @throws IOException communication exception.
*/
public boolean indexExists(String name) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpHead head = new HttpHead(String.format("http://%s:%d/%s", host, port, name));
try {
CloseableHttpResponse response = client.execute(head);
return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
} finally {
head.releaseConnection();
}
}
/**
* Creates new index.
*
* @param name the name of the index to test.
* @param type index type
* @param mappings field mapping definition.
* @return true if index was created.
* @throws IOException communication exception.
*/
public boolean createIndex(String name, String type, EsRequest mappings) throws IOException {
if (indexExists(name)) {
return true;
}
CloseableHttpClient client = HttpClients.createDefault();
HttpPost method = new HttpPost(String.format("http://%s:%d/%s", host, port, name));
try {
StringEntity requestEntity = new StringEntity(mappings.toString(), ContentType.APPLICATION_JSON);
method.setEntity(requestEntity);
CloseableHttpResponse resp = client.execute(method);
return resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
} finally {
method.releaseConnection();
}
}
/**
* Deletes index.
*
* @param name the name of the index to be deleted.
* @return true if index was deleted.
* @throws IOException
*/
public boolean deleteIndex(String name) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpDelete delete = new HttpDelete(String.format("http://%s:%d/%s", host, port, name));
try {
CloseableHttpResponse resp = client.execute(delete);
return resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
} finally {
delete.releaseConnection();
}
}
/**
* Indexes document.
*
* @param name the name of the index.
* @param type index type
* @param id document id
* @param doc document
* @return true if document was indexed.
* @throws IOException
*/
public boolean storeDocument(String name, String type, String id,
EsRequest doc) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost method = new HttpPost(String.format("http://%s:%d/%s/%s/%s", host, port, name, type, id));
try {
StringEntity requestEntity = new StringEntity(doc.toString(), ContentType.APPLICATION_JSON);
method.setEntity(requestEntity);
CloseableHttpResponse resp = client.execute(method);
int statusCode = resp.getStatusLine().getStatusCode();
return statusCode == HttpStatus.SC_CREATED || statusCode == HttpStatus.SC_OK;
} finally {
method.releaseConnection();
}
}
/**
* Searches indexed document.
*
* @param name index name.
* @param type index type.
* @param id document identifier.
* @return document if it was found or null.
* @throws IOException
*/
public EsRequest getDocument(String name, String type, String id) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpGet method = new HttpGet(String.format("http://%s:%d/%s/%s/%s", host, port, name, type, id));
try {
CloseableHttpResponse resp = client.execute(method);
int status = resp.getStatusLine().getStatusCode();
switch (status) {
case HttpStatus.SC_OK :
EsResponse doc = EsResponse.read(resp.getEntity().getContent());
return new EsRequest((Document) doc.get("_source"));
case HttpStatus.SC_NOT_ACCEPTABLE:
case HttpStatus.SC_NOT_FOUND:
return null;
default:
throw new IOException(resp.getStatusLine().getReasonPhrase());
}
} finally {
method.releaseConnection();
}
}
/**
* Deletes document.
*
* @param name index name.
* @param type index type.
* @param id document id
* @return true if it was deleted.
* @throws IOException
*/
public boolean deleteDocument(String name, String type, String id) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpDelete delete = new HttpDelete(String.format("http://%s:%d/%s/%s/%s", host, port, name, type, id));
try {
return client.execute(delete).getStatusLine().getStatusCode() == HttpStatus.SC_OK;
} finally {
delete.releaseConnection();
}
}
/**
* Deletes all documents.
*
* @param name index name
* @param type index type.
* @throws IOException
*/
public void deleteAll(String name, String type) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost method = new HttpPost(String.format("http://%s:%d/%s/%s", host, port, name, type));
try {
EsRequest query = new EsRequest();
query.put("query", new MatchAllQuery().build());
StringEntity requestEntity = new StringEntity(query.toString(), ContentType.APPLICATION_JSON);
method.setEntity(requestEntity);
method.setHeader(" X-HTTP-Method-Override", "DELETE");
CloseableHttpResponse resp = client.execute(method);
int status = resp.getStatusLine().getStatusCode();
if (status != HttpStatus.SC_OK) {
throw new IOException(resp.getStatusLine().getReasonPhrase());
}
} finally {
method.releaseConnection();
}
}
/**
* Flushes index data.
*
* @param name index name.
* @throws IOException
*/
public void flush(String name) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost method = new HttpPost(String.format("http://%s:%d/%s/_flush", host, port, name));
try {
CloseableHttpResponse resp = client.execute(method);
int status = resp.getStatusLine().getStatusCode();
if (status != HttpStatus.SC_OK) {
throw new IOException(resp.getStatusLine().getReasonPhrase());
}
} finally {
method.releaseConnection();
}
}
/**
* Refreshes index data.
*
* @param name index name.
* @throws IOException
*/
public void refresh(String name) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost method = new HttpPost(String.format("http://%s:%d/%s/_refresh", host, port, name));
try {
CloseableHttpResponse resp = client.execute(method);
int status = resp.getStatusLine().getStatusCode();
if (status != HttpStatus.SC_OK) {
throw new IOException(resp.getStatusLine().getReasonPhrase());
}
} finally {
method.releaseConnection();
}
}
/**
* Executes query.
*
* @param name index name.
* @param type index type.
* @param query query to be executed
* @return search results in json format.
* @throws IOException
*/
public EsResponse search(String name, String type, EsRequest query) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost method = new HttpPost(String.format("http://%s:%d/%s/%s/_search", host, port, name, type));
try {
StringEntity requestEntity = new StringEntity(query.toString(), ContentType.APPLICATION_JSON);
method.setEntity(requestEntity);
CloseableHttpResponse resp = client.execute(method);
int status = resp.getStatusLine().getStatusCode();
if (status != HttpStatus.SC_OK) {
throw new IOException(resp.getStatusLine().getReasonPhrase());
}
return EsResponse.read(resp.getEntity().getContent());
} finally {
method.releaseConnection();
}
}
/**
* Counts entries.
*
* @param name index name.
* @param type index type.
* @return number of indexed entries.
* @throws IOException
*/
public long count(String name, String type) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost method = new HttpPost(String.format("http://%s:%d/%s/%s/_count", host, port, name, type));
try {
EsRequest query = new EsRequest();
query.put("query", new MatchAllQuery().build());
StringEntity requestEntity = new StringEntity(query.toString(), ContentType.APPLICATION_JSON);
method.setEntity(requestEntity);
CloseableHttpResponse resp = client.execute(method);
int status = resp.getStatusLine().getStatusCode();
if (status != HttpStatus.SC_OK) {
throw new IOException(resp.getStatusLine().getReasonPhrase());
}
return (Integer) EsResponse.read(resp.getEntity().getContent()).get("count");
} finally {
method.releaseConnection();
}
}
}