/**
* Copyright (c) Codice Foundation
* <p>
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or any later version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package org.codice.ddf.catalog.ui.query;
import static spark.Spark.after;
import static spark.Spark.exception;
import static spark.Spark.post;
import static spark.route.RouteOverview.enableRouteOverview;
import java.util.concurrent.TimeUnit;
import org.boon.json.JsonParserFactory;
import org.boon.json.JsonSerializerFactory;
import org.boon.json.ObjectMapper;
import org.boon.json.implementation.ObjectMapperImpl;
import org.codice.ddf.catalog.ui.query.cql.CqlQueryResponse;
import org.codice.ddf.catalog.ui.query.cql.CqlRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Stopwatch;
import ddf.action.ActionRegistry;
import ddf.catalog.CatalogFramework;
import ddf.catalog.federation.FederationException;
import ddf.catalog.filter.FilterAdapter;
import ddf.catalog.filter.FilterBuilder;
import ddf.catalog.operation.QueryRequest;
import ddf.catalog.operation.QueryResponse;
import ddf.catalog.source.SourceUnavailableException;
import ddf.catalog.source.UnsupportedQueryException;
import spark.servlet.SparkApplication;
public class QueryApplication implements SparkApplication {
private static final Logger LOGGER = LoggerFactory.getLogger(QueryApplication.class);
private static final String APPLICATION_JSON = "application/json";
private CatalogFramework catalogFramework;
private FilterBuilder filterBuilder;
private FilterAdapter filterAdapter;
private ActionRegistry actionRegistry;
private ObjectMapper mapper = new ObjectMapperImpl(new JsonParserFactory().usePropertyOnly(),
new JsonSerializerFactory().includeEmpty()
.includeNulls()
.includeDefaultValues()
.setJsonFormatForDates(false));
@Override
public void init() {
post("/cql", APPLICATION_JSON, (req, res) -> {
CqlRequest cqlRequest = mapper.readValue(req.body(), CqlRequest.class);
CqlQueryResponse cqlQueryResponse = executeCqlQuery(cqlRequest);
return mapper.toJson(cqlQueryResponse);
});
after("/cql", (req, res) -> {
res.type(APPLICATION_JSON);
res.header("Content-Encoding", "gzip");
});
exception(UnsupportedQueryException.class, (e, request, response) -> {
response.status(400);
response.body("Unsupported query request.");
LOGGER.error("Query endpoint failed", e);
});
exception(Exception.class, (e, request, response) -> {
response.status(500);
response.body("Error while processing query request.");
LOGGER.error("Query endpoint failed", e);
});
enableRouteOverview();
}
private CqlQueryResponse executeCqlQuery(CqlRequest cqlRequest)
throws UnsupportedQueryException, SourceUnavailableException, FederationException {
QueryRequest request = cqlRequest.createQueryRequest(catalogFramework.getId(),
filterBuilder);
Stopwatch stopwatch = Stopwatch.createStarted();
QueryResponse response = catalogFramework.query(request);
stopwatch.stop();
return new CqlQueryResponse(cqlRequest.getId(),
request,
response,
cqlRequest.getSource(),
stopwatch.elapsed(TimeUnit.MILLISECONDS),
cqlRequest.isNormalize(),
filterAdapter,
actionRegistry);
}
public void setCatalogFramework(CatalogFramework catalogFramework) {
this.catalogFramework = catalogFramework;
}
public void setFilterBuilder(FilterBuilder filterBuilder) {
this.filterBuilder = filterBuilder;
}
public void setFilterAdapter(FilterAdapter filterAdapter) {
this.filterAdapter = filterAdapter;
}
public void setActionRegistry(ActionRegistry actionRegistry) {
this.actionRegistry = actionRegistry;
}
}