Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.logspace.hq.solr.SolrEventService Maven / Gradle / Ivy
/**
* Logspace
* Copyright (c) 2015 Indoqa Software Design und Beratung GmbH. All rights reserved.
* This program and the accompanying materials are made available under the terms of
* the Eclipse Public License Version 1.0, which accompanies this distribution and
* is available at http://www.eclipse.org/legal/epl-v10.html.
*/
package io.logspace.hq.solr;
import static com.indoqa.lang.util.StringUtils.escapeSolr;
import static com.indoqa.lang.util.TimeUtils.formatSolrDate;
import static java.util.Calendar.*;
import static java.util.concurrent.TimeUnit.*;
import static org.apache.solr.common.params.CommonParams.SORT;
import static org.apache.solr.common.params.CursorMarkParams.CURSOR_MARK_PARAM;
import static org.apache.solr.common.params.ShardParams._ROUTE_;
import java.io.*;
import java.text.MessageFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.AutoCloseInputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest.METHOD;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.StreamingResponseCallback;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.InputStreamResponseParser;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.response.JSONResponseWriter;
import org.apache.solr.response.SolrQueryResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import com.indoqa.lang.util.TimeTracker;
import com.indoqa.lang.util.TimeUtils;
import com.indoqa.solr.facet.api.*;
import io.logspace.agent.api.event.Event;
import io.logspace.agent.api.event.EventProperty;
import io.logspace.agent.api.json.EventPage;
import io.logspace.agent.api.order.Aggregate;
import io.logspace.agent.api.order.PropertyDescription;
import io.logspace.agent.api.order.PropertyType;
import io.logspace.hq.core.api.capabilities.CapabilitiesService;
import io.logspace.hq.core.api.event.EventService;
import io.logspace.hq.core.api.event.NativeQueryResult;
import io.logspace.hq.core.api.event.StoredEvent;
import io.logspace.hq.rest.api.DataRetrievalException;
import io.logspace.hq.rest.api.EventStoreException;
import io.logspace.hq.rest.api.agentactivity.AgentActivities;
import io.logspace.hq.rest.api.agentactivity.AgentActivity;
import io.logspace.hq.rest.api.event.*;
import io.logspace.hq.rest.api.suggestion.AgentDescription;
import io.logspace.hq.rest.api.suggestion.Suggestion;
import io.logspace.hq.rest.api.suggestion.SuggestionInput;
import io.logspace.hq.rest.api.timeseries.InvalidTimeSeriesDefinitionException;
import io.logspace.hq.rest.api.timeseries.TimeSeriesDefinition;
import io.logspace.hq.rest.api.timeseries.TimeWindow;
@Named
public class SolrEventService implements EventService {
private static final String ALL_DOCS_QUERY = "*:*";
private static final String SORT_CRON_ASC = "timestamp ASC, id ASC";
private static final String SORT_CRON_DESC = "timestamp DESC, id ASC";
private static final long AGENT_DESCRIPTION_REFRESH_INTERVAL = 60000L;
private static final long SLICE_UPDATE_INTERVAL = 1000L;
private static final String VALUE_FACET_NAME = "val";
private static final String AGGREGATION_FACET_NAME = "agg";
private static final String COUNT_FACET_NAME = "count";
private static final String FIELD_ID = "id";
private static final String FIELD_SPACE = "space";
private static final String FIELD_SYSTEM = "system";
private static final String FIELD_AGENT_ID = "agent_id";
private static final String FIELD_GLOBAL_AGENT_ID = "global_agent_id";
private static final String FIELD_TYPE = "type";
private static final String FIELD_MARKER = "marker";
private static final String FIELD_GLOBAL_ID = "global_id";
private static final String FIELD_PARENT_ID = "parent_id";
private static final String FIELD_TIMESTAMP = "timestamp";
private static final String FIELD_PROPERTY_ID = "property_id";
private static final String FIELD_TOKENIZED_SEARCH_FIELD = "tokenized_search_field";
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Inject
@Qualifier("logspace-solr-client")
private SolrClient solrClient;
@Inject
private CapabilitiesService capabilitiesService;
@Value("${logspace.solr.fallback-shard}")
private String fallbackShard;
private boolean isCloud;
private Map activeSlicesMap;
private long nextSliceUpdate;
private final Map cachedAgentDescriptions = new ConcurrentHashMap<>();
private final JSONResponseWriter jsonResponseWriter = new JSONResponseWriter();
@Override
public NativeQueryResult executeNativeQuery(Map parameters) {
SolrParams params = this.createSolrParams(parameters);
try {
QueryRequest request = new QueryRequest(params, METHOD.POST);
request.setResponseParser(new InputStreamResponseParser("json"));
QueryResponse response = request.process(this.solrClient);
InputStream inputStream = (InputStream) response.getResponse().get("stream");
if (inputStream != null) {
return new SolrNativeQueryResult(inputStream);
}
return new SolrNativeQueryResult(this.serializeResponse(params, response));
} catch (SolrException | SolrServerException | IOException e) {
throw new DataRetrievalException("Could not execute direct query with parameters " + parameters.toString() + ".", e);
}
}
@SuppressWarnings("unchecked")
@Override
public AgentActivities getAgentActivities(int start, int count, int durationSeconds, int steps, String sort) {
SolrQuery solrQuery = new SolrQuery(ALL_DOCS_QUERY);
solrQuery.setRows(0);
Date endDate = new Date();
Date startDate = new Date(endDate.getTime() - SECONDS.toMillis(durationSeconds));
solrQuery.addFilterQuery(this.getTimestampRangeQuery(startDate, endDate));
TermsFacet agentFacet = new TermsFacet(FIELD_GLOBAL_AGENT_ID, FIELD_GLOBAL_AGENT_ID);
agentFacet.setOffset(start);
agentFacet.setLimit(count);
agentFacet.setMincount(0);
agentFacet.setNumBuckets(true);
agentFacet.setSort(sort);
agentFacet.addSubFacet(
new RangeFacet(FIELD_TIMESTAMP, FIELD_TIMESTAMP, startDate, endDate, GapUnit.SECONDS, durationSeconds / steps));
solrQuery.set("json.facet", FacetList.toJsonString(agentFacet));
try {
AgentActivities result = new AgentActivities();
QueryResponse response = this.solrClient.query(solrQuery, METHOD.POST);
Buckets agentBuckets = Buckets.fromResponse(response, FIELD_GLOBAL_AGENT_ID);
result.setOffset(start);
result.setTotalCount(agentBuckets.getNumBuckets());
int maxHistoryValue = 0;
for (NamedList eachAgentBucket : agentBuckets) {
AgentActivity agentActivity = new AgentActivity();
agentActivity.setGlobalAgentId((String) eachAgentBucket.get(VALUE_FACET_NAME));
agentActivity.setEventCount(Buckets.getInt(eachAgentBucket, COUNT_FACET_NAME));
int[] history = new int[steps];
Buckets historyBuckets = Buckets.fromFacet((NamedList) eachAgentBucket.get(FIELD_TIMESTAMP));
for (int i = 0; i < Math.min(historyBuckets.getBucketCount(), history.length); i++) {
NamedList historyBucket = historyBuckets.getBucket(i);
int historyValue = Buckets.getInt(historyBucket, COUNT_FACET_NAME);
history[i] = historyValue;
maxHistoryValue = Math.max(maxHistoryValue, historyValue);
}
agentActivity.setHistory(history);
result.add(agentActivity);
}
result.setMaxHistoryValue(maxHistoryValue);
return result;
} catch (SolrException | SolrServerException | IOException e) {
throw new DataRetrievalException("Could not retrieve Agent activities.", e);
}
}
@Override
public Suggestion getSuggestion(SuggestionInput input) {
TimeTracker timeTracker = new TimeTracker();
SolrQuery solrQuery = new SolrQuery(ALL_DOCS_QUERY);
solrQuery.setRows(0);
if (!StringUtils.isBlank(input.getText())) {
solrQuery.addFilterQuery(FIELD_TOKENIZED_SEARCH_FIELD + ":" + escapeSolr(input.getText()) + "*");
}
this.addFilterQuery(solrQuery, FIELD_PROPERTY_ID, input.getPropertyId());
this.addFilterQuery(solrQuery, FIELD_SPACE, input.getSpaceId());
this.addFilterQuery(solrQuery, FIELD_SYSTEM, input.getSystemId());
solrQuery.setFacetMinCount(1);
solrQuery.addFacetField(FIELD_GLOBAL_AGENT_ID);
try {
Suggestion result = new Suggestion();
QueryResponse response = this.solrClient.query(solrQuery);
FacetField globalAgentIdFacetField = response.getFacetField(FIELD_GLOBAL_AGENT_ID);
for (Count eachValue : globalAgentIdFacetField.getValues()) {
String globalAgentId = eachValue.getName();
result.addAgentDescription(this.getAgentDescription(globalAgentId));
}
result.setExecutionTime(timeTracker.getElapsed(MILLISECONDS));
return result;
} catch (SolrException | SolrServerException | IOException e) {
throw new DataRetrievalException("Failed to create suggestions", e);
}
}
@Override
public Object[] getTimeSeries(TimeSeriesDefinition dataDefinition) {
SolrQuery solrQuery = new SolrQuery(ALL_DOCS_QUERY);
solrQuery.setRows(0);
solrQuery.addFilterQuery(FIELD_GLOBAL_AGENT_ID + ":" + escapeSolr(dataDefinition.getGlobalAgentId()));
solrQuery.addFilterQuery(this.getTimestampRangeQuery(dataDefinition.getTimeWindow()));
solrQuery.addFilterQuery(dataDefinition.getPropertyId() + ":*");
solrQuery.set("json.facet", this.createTimeSeriesFacets(dataDefinition));
try {
QueryResponse response = this.solrClient.query(solrQuery, METHOD.POST);
List values = new ArrayList();
Buckets buckets = Buckets.fromResponse(response, FIELD_TIMESTAMP);
for (NamedList eachBucket : buckets) {
if (dataDefinition.getAggregate() == Aggregate.count) {
values.add(eachBucket.get(COUNT_FACET_NAME));
} else {
values.add(eachBucket.get(AGGREGATION_FACET_NAME));
}
}
return values.toArray();
} catch (SolrException | SolrServerException | IOException e) {
throw new DataRetrievalException("Could not retrieve data.", e);
}
}
@PostConstruct
public void initialize() {
this.isCloud = this.solrClient instanceof CloudSolrClient;
if (this.isCloud) {
((CloudSolrClient) this.solrClient).connect();
}
new Timer(true).schedule(new RefreshAgentDescriptionCacheTask(), AGENT_DESCRIPTION_REFRESH_INTERVAL,
AGENT_DESCRIPTION_REFRESH_INTERVAL);
}
@Override
public EventPage retrieve(EventFilter eventFilter, int count, String cursorMark) {
return this.retrieve(eventFilter, count, cursorMark, SORT_CRON_ASC);
}
@Override
public EventPage retrieveReversed(EventFilter eventFilter, int count, String cursorMark) {
return this.retrieve(eventFilter, count, cursorMark, SORT_CRON_DESC);
}
@Override
public void store(Collection extends Event> events, String space) {
if (events == null || events.isEmpty()) {
return;
}
String system = events.stream().findFirst().get().getSystem();
this.logger.debug("Storing {} event(s) for space '{}' from system {}", events.size(), space, system);
try {
Collection inputDocuments = this.createInputDocuments(events, space);
this.solrClient.add(inputDocuments);
this.logger.info("Successfully stored {} event(s) for space '{}' from system {}", events.size(), space, system);
} catch (SolrServerException | IOException e) {
String message = "Failed to store " + events.size() + " events.";
this.logger.error(message, e);
throw EventStoreException.storeFailed(message, e);
}
}
@Override
public void stream(EventFilter eventFilter, int count, int offset, EventStreamer eventStreamer) {
SolrQuery solrQuery = new SolrQuery(ALL_DOCS_QUERY);
solrQuery.setStart(offset);
solrQuery.setRows(count);
solrQuery.set(SORT, SORT_CRON_ASC);
for (EventFilterElement eachElement : eventFilter) {
solrQuery.addFilterQuery(this.createFilterQuery(eachElement));
}
try {
this.solrClient.queryAndStreamResponse(solrQuery, new EventStreamCallback(eventStreamer));
} catch (SolrServerException | IOException e) {
String message = "Failed to stream events.";
this.logger.error(message, e);
throw EventStoreException.retrieveFailed(message, e);
}
}
protected void refreshAgentDescriptionCache() {
for (String eachGlobalAgentId : this.cachedAgentDescriptions.keySet()) {
try {
this.cachedAgentDescriptions.put(eachGlobalAgentId, this.loadAgentDescription(eachGlobalAgentId));
} catch (Exception e) {
this.cachedAgentDescriptions.remove(eachGlobalAgentId);
}
}
}
private void addFilterQuery(SolrQuery solrQuery, String fieldName, String value) {
if (StringUtils.isBlank(value)) {
return;
}
solrQuery.addFilterQuery(fieldName + ":" + escapeSolr(value));
}
private void addProperties(SolrInputDocument document, Iterable extends EventProperty>> properties, String prefix) {
for (EventProperty> eachProperty : properties) {
String propertyId = prefix + eachProperty.getKey();
document.addField(propertyId, eachProperty.getValue());
document.addField(FIELD_PROPERTY_ID, propertyId);
}
}
private void appendSolrValue(StringBuilder stringBuilder, Object value) {
if (value == null) {
stringBuilder.append('*');
return;
}
if (value instanceof Date) {
stringBuilder.append(TimeUtils.formatSolrDate((Date) value));
}
String result = String.valueOf(value);
if (StringUtils.isBlank(result)) {
stringBuilder.append('*');
return;
}
stringBuilder.append('"');
stringBuilder.append(result);
stringBuilder.append('"');
}
private Event createEvent(SolrDocument solrDocument) {
StoredEvent result = new StoredEvent();
result.setId(this.getString(solrDocument, FIELD_ID));
result.setSystem(this.getString(solrDocument, FIELD_SYSTEM));
result.setAgentId(this.getString(solrDocument, FIELD_AGENT_ID));
result.setType(this.getString(solrDocument, FIELD_TYPE));
result.setMarker(this.getString(solrDocument, FIELD_MARKER));
result.setTimestamp(this.getDate(solrDocument, FIELD_TIMESTAMP));
result.setParentEventId(this.getString(solrDocument, FIELD_PARENT_ID));
result.setGlobalEventId(this.getString(solrDocument, FIELD_GLOBAL_ID));
for (Entry eachField : solrDocument) {
String fieldName = eachField.getKey();
if (fieldName.startsWith("boolean_property_")) {
result.addProperties(fieldName.substring("boolean_property_".length()), eachField.getValue());
}
if (fieldName.startsWith("date_property_")) {
result.addProperties(fieldName.substring("date_property_".length()), eachField.getValue());
}
if (fieldName.startsWith("double_property_")) {
result.addProperties(fieldName.substring("double_property_".length()), eachField.getValue());
}
if (fieldName.startsWith("float_property_")) {
result.addProperties(fieldName.substring("float_property_".length()), eachField.getValue());
}
if (fieldName.startsWith("integer_property_")) {
result.addProperties(fieldName.substring("integer_property_".length()), eachField.getValue());
}
if (fieldName.startsWith("long_property_")) {
result.addProperties(fieldName.substring("long_property_".length()), eachField.getValue());
}
if (fieldName.startsWith("string_property_")) {
result.addProperties(fieldName.substring("string_property_".length()), eachField.getValue());
}
}
return result;
}
private String createFilterQuery(EventFilterElement eventFilterElement) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(eventFilterElement.getProperty());
stringBuilder.append(':');
if (eventFilterElement instanceof EqualsEventFilterElement) {
EqualsEventFilterElement equalsEventFilterElement = (EqualsEventFilterElement) eventFilterElement;
this.appendSolrValue(stringBuilder, equalsEventFilterElement.getValue());
}
if (eventFilterElement instanceof RangeEventFilterElement) {
RangeEventFilterElement rangeEventFilterElement = (RangeEventFilterElement) eventFilterElement;
stringBuilder.append('[');
this.appendSolrValue(stringBuilder, rangeEventFilterElement.getFrom());
stringBuilder.append(" TO ");
this.appendSolrValue(stringBuilder, rangeEventFilterElement.getTo());
stringBuilder.append(']');
}
if (eventFilterElement instanceof MultiValueEventFilterElement) {
MultiValueEventFilterElement multiValueEventFilterElement = (MultiValueEventFilterElement) eventFilterElement;
stringBuilder.append('(');
for (Iterator iterator = multiValueEventFilterElement.getValues().iterator(); iterator.hasNext();) {
this.appendSolrValue(stringBuilder, iterator.next());
if (iterator.hasNext()) {
stringBuilder.append(' ');
stringBuilder.append(multiValueEventFilterElement.getOperator());
stringBuilder.append(' ');
}
}
stringBuilder.append(')');
}
return stringBuilder.toString();
}
private SolrInputDocument createInputDocument(Event event, String space) {
SolrInputDocument result = new SolrInputDocument();
result.addField(FIELD_ID, event.getId());
result.addField(FIELD_GLOBAL_AGENT_ID,
this.capabilitiesService.getGlobalAgentId(space, event.getSystem(), event.getAgentId()));
result.addField(FIELD_SPACE, space);
result.addField(FIELD_SYSTEM, event.getSystem());
result.addField(FIELD_AGENT_ID, event.getAgentId());
result.addField(FIELD_TYPE, event.getType());
result.addField(FIELD_MARKER, event.getMarker());
result.addField(FIELD_TIMESTAMP, event.getTimestamp());
result.addField(FIELD_PARENT_ID, event.getParentEventId());
result.addField(FIELD_GLOBAL_ID, event.getGlobalEventId());
this.addProperties(result, event.getBooleanProperties(), "boolean_property_");
this.addProperties(result, event.getDateProperties(), "date_property_");
this.addProperties(result, event.getDoubleProperties(), "double_property_");
this.addProperties(result, event.getFloatProperties(), "float_property_");
this.addProperties(result, event.getIntegerProperties(), "integer_property_");
this.addProperties(result, event.getLongProperties(), "long_property_");
this.addProperties(result, event.getStringProperties(), "string_property_");
if (this.isCloud) {
result.setField(_ROUTE_, this.getTargetShard(event.getTimestamp()));
}
return result;
}
private Collection createInputDocuments(Collection extends Event> events, String space) {
Collection result = new ArrayList();
for (Event eachEvent : events) {
result.add(this.createInputDocument(eachEvent, space));
}
return result;
}
private PropertyDescription createPropertyDescription(String propertyId) {
if (propertyId == null) {
return null;
}
Pattern propertyIdPattern = Pattern.compile("(\\w+)_property_(.*?)");
Matcher matcher = propertyIdPattern.matcher(propertyId);
if (!matcher.matches()) {
return null;
}
PropertyDescription result = new PropertyDescription();
result.setId(propertyId);
result.setPropertyType(PropertyType.get(matcher.group(1)));
result.setName(matcher.group(2));
return result;
}
private SolrParams createSolrParams(Map parameters) {
ModifiableSolrParams result = new ModifiableSolrParams();
for (Entry eachEntry : parameters.entrySet()) {
result.add(eachEntry.getKey(), eachEntry.getValue());
}
return result;
}
private String createTimeSeriesFacets(TimeSeriesDefinition dataDefinition) {
PropertyDescription propertyDescription = this.createPropertyDescription(dataDefinition.getPropertyId());
if (!propertyDescription.getPropertyType().isAllowed(dataDefinition.getAggregate())) {
throw InvalidTimeSeriesDefinitionException.illegalAggregate(propertyDescription.getPropertyType(),
dataDefinition.getAggregate());
}
Date startDate = dataDefinition.getTimeWindow().getStart();
Date endDate = dataDefinition.getTimeWindow().getEnd();
int gap = dataDefinition.getTimeWindow().getGap();
RangeFacet rangeFacet = new RangeFacet(FIELD_TIMESTAMP, FIELD_TIMESTAMP, startDate, endDate, GapUnit.SECONDS, gap);
if (dataDefinition.getAggregate() != Aggregate.count) {
rangeFacet.addSubFacet(new StatisticFacet(AGGREGATION_FACET_NAME, dataDefinition.getFacetFunction()));
}
return FacetList.toJsonString(rangeFacet);
}
private AgentDescription getAgentDescription(String globalAgentId) throws SolrServerException, IOException {
AgentDescription agentDescription = this.capabilitiesService.getAgentDescription(globalAgentId);
if (agentDescription == null || agentDescription.getPropertyDescriptions() == null
|| agentDescription.getPropertyDescriptions().isEmpty()) {
agentDescription = this.cachedAgentDescriptions.get(globalAgentId);
}
if (agentDescription == null) {
agentDescription = this.loadAgentDescription(globalAgentId);
this.cachedAgentDescriptions.put(globalAgentId, agentDescription);
}
return agentDescription;
}
private Date getDate(SolrDocument solrDocument, String fieldName) {
return (Date) solrDocument.getFieldValue(fieldName);
}
private String getFirstFacetValue(QueryResponse response, String fieldName) {
FacetField facetField = response.getFacetField(fieldName);
if (facetField == null) {
return null;
}
List values = facetField.getValues();
if (values == null || values.isEmpty()) {
return null;
}
return values.get(0).getName();
}
private String getString(SolrDocument solrDocument, String fieldName) {
return (String) solrDocument.getFieldValue(fieldName);
}
private String getTargetShard(Date timestamp) {
if (!this.isCloud) {
return null;
}
CloudSolrClient cloudSolrClient = (CloudSolrClient) this.solrClient;
if (System.currentTimeMillis() > this.nextSliceUpdate) {
this.nextSliceUpdate = System.currentTimeMillis() + SLICE_UPDATE_INTERVAL;
this.activeSlicesMap = cloudSolrClient
.getZkStateReader()
.getClusterState()
.getActiveSlicesMap(cloudSolrClient.getDefaultCollection());
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(timestamp);
String sliceName = MessageFormat.format("{0,number,0000}-{1,number,00}", calendar.get(YEAR), calendar.get(MONTH) + 1);
if (this.activeSlicesMap.containsKey(sliceName)) {
return sliceName;
}
return this.fallbackShard;
}
private String getTimestampRangeQuery(Date start, Date end) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(FIELD_TIMESTAMP);
stringBuilder.append(":[");
stringBuilder.append(formatSolrDate(start));
stringBuilder.append(" TO ");
stringBuilder.append(formatSolrDate(end));
stringBuilder.append("}");
return stringBuilder.toString();
}
private String getTimestampRangeQuery(TimeWindow timeWindow) {
return this.getTimestampRangeQuery(timeWindow.getStart(), timeWindow.getEnd());
}
private AgentDescription loadAgentDescription(String globalAgentId) throws SolrServerException, IOException {
SolrQuery query = new SolrQuery(ALL_DOCS_QUERY);
query.setRows(0);
query.setFilterQueries(FIELD_GLOBAL_AGENT_ID + ":\"" + globalAgentId + "\"");
query.setFacetMinCount(1);
query.addFacetField(FIELD_SPACE, FIELD_SYSTEM, FIELD_PROPERTY_ID);
QueryResponse response = this.solrClient.query(query);
AgentDescription result = new AgentDescription();
result.setGlobalId(globalAgentId);
result.setName(this.capabilitiesService.getAgentId(globalAgentId));
result.setSpace(this.getFirstFacetValue(response, FIELD_SPACE));
result.setSystem(this.getFirstFacetValue(response, FIELD_SYSTEM));
List propertyDescriptions = new ArrayList<>();
FacetField facetField = response.getFacetField(FIELD_PROPERTY_ID);
for (Count eachValue : facetField.getValues()) {
propertyDescriptions.add(this.createPropertyDescription(eachValue.getName()));
}
Collections.sort(propertyDescriptions);
result.setPropertyDescriptions(propertyDescriptions);
return result;
}
private EventPage retrieve(EventFilter eventFilter, int count, String cursorMark, String sort) {
SolrQuery solrQuery = new SolrQuery(ALL_DOCS_QUERY);
solrQuery.setRows(count);
solrQuery.set(CURSOR_MARK_PARAM, cursorMark);
solrQuery.set(SORT, sort);
for (EventFilterElement eachElement : eventFilter) {
solrQuery.addFilterQuery(this.createFilterQuery(eachElement));
}
try {
EventPage result = new EventPage();
QueryResponse response = this.solrClient.query(solrQuery);
for (SolrDocument eachSolrDocument : response.getResults()) {
result.addEvent(this.createEvent(eachSolrDocument));
}
result.setNextCursorMark(response.getNextCursorMark());
result.setTotalCount(response.getResults().getNumFound());
return result;
} catch (SolrServerException | IOException | SolrException e) {
String message = "Failed to retrieve events.";
this.logger.error(message, e);
throw EventStoreException.retrieveFailed(message, e);
}
}
private InputStream serializeResponse(SolrParams params, QueryResponse response) throws IOException {
LocalSolrQueryRequest solrQueryRequest = new LocalSolrQueryRequest(null, params);
SolrQueryResponse solrQueryResponse = new SolrQueryResponse();
solrQueryResponse.setAllValues(response.getResponse());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(baos, "UTF-8");
this.jsonResponseWriter.write(writer, solrQueryRequest, solrQueryResponse);
writer.flush();
return new ByteArrayInputStream(baos.toByteArray());
}
protected class RefreshAgentDescriptionCacheTask extends TimerTask {
@Override
public void run() {
SolrEventService.this.refreshAgentDescriptionCache();
}
}
private final class EventStreamCallback extends StreamingResponseCallback {
private final EventStreamer eventStreamer;
public EventStreamCallback(EventStreamer eventStreamer) {
this.eventStreamer = eventStreamer;
}
@Override
public void streamDocListInfo(long numFound, long start, Float maxScore) {
// do nothing
}
@Override
public void streamSolrDocument(SolrDocument solrDocument) {
try {
this.eventStreamer.streamEvent(SolrEventService.this.createEvent(solrDocument));
} catch (IOException e) {
throw EventStoreException.retrieveFailed("Failed to stream events.", e);
}
}
}
private static class SolrNativeQueryResult implements NativeQueryResult {
private final InputStream inputStream;
public SolrNativeQueryResult(InputStream inputStream) {
super();
this.inputStream = new AutoCloseInputStream(inputStream);
}
@Override
public String getContentType() {
return "application/json;charset=UTF-8";
}
@Override
public void writeTo(OutputStream outputStream) throws IOException {
IOUtils.copy(this.inputStream, outputStream);
}
}
}