/*
* Copyright 2013 Rackspace
*
* 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 com.rackspacecloud.blueflood.io;
import com.codahale.metrics.Timer;
import com.rackspacecloud.blueflood.service.ElasticClientManager;
import com.rackspacecloud.blueflood.service.RemoteElasticSearchServer;
import com.rackspacecloud.blueflood.types.Event;
import com.rackspacecloud.blueflood.utils.Metrics;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.SearchHit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
public class EventElasticSearchIO implements EventsIO {
private final Timer eventSearchTimer = Metrics.timer(EventElasticSearchIO.class,
"Search time for events");
private final Timer eventInsertTimer = Metrics.timer(EventElasticSearchIO.class,
"Insertion time for events");
public static final String EVENT_INDEX = "events";
public static final String ES_TYPE = "graphite_event";
private final Client client;
public EventElasticSearchIO() {
this(RemoteElasticSearchServer.getInstance());
}
public EventElasticSearchIO(Client client) {
this.client = client;
}
public EventElasticSearchIO(ElasticClientManager manager) {
this(manager.getClient());
}
@Override
public void insert(String tenant, List<Map<String, Object>> events) throws Exception {
final Timer.Context eventInsertTimerContext = eventInsertTimer.time();
BulkRequestBuilder bulk = client.prepareBulk();
for (Map<String, Object> event : events) {
event.put(Event.FieldLabels.tenantId.toString(), tenant);
IndexRequestBuilder requestBuilder = client.prepareIndex(EVENT_INDEX, ES_TYPE)
.setSource(event)
.setRouting(tenant);
bulk.add(requestBuilder);
}
bulk.execute().actionGet();
eventInsertTimerContext.stop();
}
@Override
public List<Map<String, Object>> search(String tenant, Map<String, List<String>> query) throws Exception {
final Timer.Context eventSearchTimerContext = eventSearchTimer.time();
BoolQueryBuilder qb = boolQuery()
.must(termQuery(Event.FieldLabels.tenantId.toString(), tenant));
if (query != null) {
qb = extractQueryParameters(query, qb);
}
SearchResponse response = client.prepareSearch(EVENT_INDEX)
.setRouting(tenant)
.setSize(100000)
.setVersion(true)
.setQuery(qb)
.execute()
.actionGet();
eventSearchTimerContext.stop();
List<Map<String, Object>> events = new ArrayList<Map<String, Object>>();
for (SearchHit hit : response.getHits().getHits()) {
events.add(hit.getSource());
}
return events;
}
private BoolQueryBuilder extractQueryParameters(Map<String, List<String>> query, BoolQueryBuilder qb) {
String tagsQuery = extractFieldFromQuery(Event.FieldLabels.tags.toString(), query);
String untilQuery = extractFieldFromQuery(Event.untilParameterName, query);
String fromQuery = extractFieldFromQuery(Event.fromParameterName, query);
if (!tagsQuery.equals(""))
qb = qb.must(termQuery(Event.FieldLabels.tags.toString(), tagsQuery));
if (!untilQuery.equals("") && !fromQuery.equals("")) {
qb = qb.must(rangeQuery(Event.FieldLabels.when.toString())
.to(Long.parseLong(untilQuery))
.from(Long.parseLong(fromQuery)));
} else if (!untilQuery.equals("")) {
qb = qb.must(rangeQuery(Event.FieldLabels.when.toString()).to(Long.parseLong(untilQuery)));
} else if (!fromQuery.equals("")) {
qb = qb.must(rangeQuery(Event.FieldLabels.when.toString()).from(Long.parseLong(fromQuery)));
}
return qb;
}
private String extractFieldFromQuery(String name, Map<String, List<String>> query) {
String result = "";
if (query.containsKey(name)) {
try {
result = query.get(name).get(0);
}
catch (IndexOutOfBoundsException e) {
result = "";
}
}
return result;
}
}