/** * Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com) * * 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.linkedin.pinot.common.response.broker; import com.linkedin.pinot.common.exception.QueryException; import com.linkedin.pinot.common.response.BrokerResponse; import com.linkedin.pinot.common.response.ProcessingException; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.annotate.JsonProperty; import org.codehaus.jackson.annotate.JsonPropertyOrder; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.annotate.JsonSerialize; import org.codehaus.jackson.type.TypeReference; import org.json.JSONException; import org.json.JSONObject; /** * This class implements pinot-broker's response format for any given query. * All fields either primitive data types, or native objects (as opposed to JSONObjects). * * Supports serialization via JSON. */ @JsonPropertyOrder({"selectionResults", "aggregationResults", "exceptions", "numServersQueried", "numServersResponded", "numDocsScanned", "numEntriesScannedInFilter", "numEntriesScannedPostFilter", "totalDocs", "timeUsedMs", "segmentStatistics", "traceInfo"}) public class BrokerResponseNative implements BrokerResponse { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); public static final BrokerResponseNative EMPTY_RESULT = BrokerResponseNative.empty(); public static final BrokerResponseNative NO_TABLE_RESULT = new BrokerResponseNative(QueryException.BROKER_RESOURCE_MISSING_ERROR); private int _numServersQueried = 0; private int _numServersResponded = 0; private long _numDocsScanned = 0L; private long _numEntriesScannedInFilter = 0L; private long _numEntriesScannedPostFilter = 0L; private long _totalDocs = 0L; private long _timeUsedMs = 0L; private SelectionResults _selectionResults; private List<AggregationResult> _aggregationResults; private Map<String, String> _traceInfo = new HashMap<>(); private List<QueryProcessingException> _processingExceptions = new ArrayList<>(); private List<String> _segmentStatistics = new ArrayList<>(); public BrokerResponseNative() { } public BrokerResponseNative(ProcessingException exception) { _processingExceptions.add(new QueryProcessingException(exception.getErrorCode(), exception.getMessage())); } public BrokerResponseNative(List<ProcessingException> exceptions) { for (ProcessingException exception : exceptions) { _processingExceptions.add(new QueryProcessingException(exception.getErrorCode(), exception.getMessage())); } } /** * Get a new empty {@link BrokerResponseNative}. */ public static BrokerResponseNative empty() { return new BrokerResponseNative(); } @JsonProperty("selectionResults") @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) public SelectionResults getSelectionResults() { return _selectionResults; } @JsonProperty("selectionResults") public void setSelectionResults(SelectionResults selectionResults) { _selectionResults = selectionResults; } @JsonProperty("aggregationResults") @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) public List<AggregationResult> getAggregationResults() { return _aggregationResults; } @JsonProperty("aggregationResults") public void setAggregationResults(List<AggregationResult> aggregationResults) { _aggregationResults = aggregationResults; } @JsonProperty("exceptions") public List<QueryProcessingException> getProcessingExceptions() { return _processingExceptions; } @JsonProperty("exceptions") public void setProcessingExceptions(List<QueryProcessingException> processingExceptions) { _processingExceptions = processingExceptions; } @JsonProperty("numServersQueried") public int getNumServersQueried() { return _numServersQueried; } @JsonProperty("numServersQueried") @Override public void setNumServersQueried(int numServersQueried) { _numServersQueried = numServersQueried; } @JsonProperty("numServersResponded") public int getNumServersResponded() { return _numServersResponded; } @JsonProperty("numServersResponded") @Override public void setNumServersResponded(int numServersResponded) { _numServersResponded = numServersResponded; } @JsonProperty("numDocsScanned") public long getNumDocsScanned() { return _numDocsScanned; } @JsonProperty("numDocsScanned") public void setNumDocsScanned(long numDocsScanned) { _numDocsScanned = numDocsScanned; } @JsonProperty("numEntriesScannedInFilter") @Override public long getNumEntriesScannedInFilter() { return _numEntriesScannedInFilter; } @JsonProperty("numEntriesScannedInFilter") public void setNumEntriesScannedInFilter(long numEntriesScannedInFilter) { _numEntriesScannedInFilter = numEntriesScannedInFilter; } @JsonProperty("numEntriesScannedPostFilter") @Override public long getNumEntriesScannedPostFilter() { return _numEntriesScannedPostFilter; } @JsonProperty("numEntriesScannedPostFilter") public void setNumEntriesScannedPostFilter(long numEntriesScannedPostFilter) { _numEntriesScannedPostFilter = numEntriesScannedPostFilter; } @JsonProperty("totalDocs") @Override public long getTotalDocs() { return _totalDocs; } @JsonProperty("totalDocs") public void setTotalDocs(long totalDocs) { _totalDocs = totalDocs; } @JsonProperty("timeUsedMs") public long getTimeUsedMs() { return _timeUsedMs; } @JsonProperty("timeUsedMs") @Override public void setTimeUsedMs(long timeUsedMs) { _timeUsedMs = timeUsedMs; } @JsonProperty("segmentStatistics") public List<String> getSegmentStatistics() { return _segmentStatistics; } @JsonProperty("segmentStatistics") public void setSegmentStatistics(List<String> segmentStatistics) { _segmentStatistics = segmentStatistics; } @JsonProperty("traceInfo") public Map<String, String> getTraceInfo() { return _traceInfo; } @JsonProperty("traceInfo") public void setTraceInfo(Map<String, String> traceInfo) { _traceInfo = traceInfo; } @Override public String toJsonString() throws IOException { return OBJECT_MAPPER.writeValueAsString(this); } @Override public JSONObject toJson() throws IOException, JSONException { return new JSONObject(toJsonString()); } public static BrokerResponseNative fromJsonString(String jsonString) throws IOException { return OBJECT_MAPPER.readValue(jsonString, new TypeReference<BrokerResponseNative>() { }); } public static BrokerResponseNative fromJsonObject(JSONObject jsonObject) throws IOException { return fromJsonString(jsonObject.toString()); } @JsonIgnore @Override public void setExceptions(List<ProcessingException> exceptions) { for (ProcessingException exception : exceptions) { _processingExceptions.add(new QueryProcessingException(exception.getErrorCode(), exception.getMessage())); } } public void addToExceptions(QueryProcessingException processingException) { _processingExceptions.add(processingException); } @JsonIgnore @Override public int getExceptionsSize() { return _processingExceptions.size(); } }