summaryrefslogtreecommitdiff
path: root/src/main/java/com/p4square/groupsindexer/GroupsSearch.java
diff options
context:
space:
mode:
authorJesse Morgan <jesse@jesterpm.net>2018-07-21 22:42:50 -0700
committerJesse Morgan <jesse@jesterpm.net>2018-07-21 22:42:50 -0700
commitfafa1140f3e8eedcb0f00b25c7891093df5fbf43 (patch)
tree5a0dea7fdc11176115283bbd56ff2137130afc7b /src/main/java/com/p4square/groupsindexer/GroupsSearch.java
Initial commit of groups search lambdas
Diffstat (limited to 'src/main/java/com/p4square/groupsindexer/GroupsSearch.java')
-rw-r--r--src/main/java/com/p4square/groupsindexer/GroupsSearch.java144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/main/java/com/p4square/groupsindexer/GroupsSearch.java b/src/main/java/com/p4square/groupsindexer/GroupsSearch.java
new file mode 100644
index 0000000..2cbc7e5
--- /dev/null
+++ b/src/main/java/com/p4square/groupsindexer/GroupsSearch.java
@@ -0,0 +1,144 @@
+package com.p4square.groupsindexer;
+
+import com.amazonaws.auth.AWS4Signer;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
+import com.amazonaws.http.AWSRequestSigningApacheInterceptor;
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.p4square.groupsindexer.model.ErrorResponse;
+import com.p4square.groupsindexer.model.GroupSearchDocument;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.elasticsearch.action.search.SearchRequest;
+import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.client.RestClient;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.index.query.BoolQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.builder.SearchSourceBuilder;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * GroupsSearch is an API Gateway Proxy Lambda which executes a search and returns the results.
+ *
+ * Required (custom) environment variables:
+ *
+ * <ul>
+ * <li>ES_URL</li>
+ * <li>IMAGE_URL_PREFIX</li>
+ * </ul>
+ */
+public class GroupsSearch implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
+
+ private static final AWSCredentialsProvider credentialsProvider = new DefaultAWSCredentialsProviderChain();
+
+ private static final Logger LOG = LogManager.getLogger(GroupsSearch.class);
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ private final RestHighLevelClient esClient;
+ private final String imageUrlPrefix;
+
+ public GroupsSearch() throws Exception {
+ // Prefix to prepend to image urls.
+ imageUrlPrefix = System.getenv("IMAGE_URL_PREFIX");
+
+ // Setup ElasticSearch client
+ final String ES_URL = System.getenv("ES_URL");
+ AWS4Signer signer = new AWS4Signer();
+ signer.setServiceName("es");
+ signer.setRegionName(System.getenv("AWS_DEFAULT_REGION"));
+ HttpRequestInterceptor interceptor = new AWSRequestSigningApacheInterceptor(signer.getServiceName(), signer, credentialsProvider);
+
+ esClient = new RestHighLevelClient(RestClient
+ .builder(HttpHost.create(ES_URL))
+ .setHttpClientConfigCallback(hacb -> hacb.addInterceptorLast(interceptor)));
+ }
+
+ @Override
+ public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
+ final APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
+
+ try {
+ final Map<String, String> params = event.getQueryStringParameters();
+ if (params == null) {
+ response.setStatusCode(400);
+ response.setBody(MAPPER.writeValueAsString(new ErrorResponse("Request must contain a query.")));
+ return response;
+ }
+
+ final BoolQueryBuilder query = QueryBuilders.boolQuery();
+
+ if (params.containsKey("q")) {
+ query.must(QueryBuilders.simpleQueryStringQuery(params.get("q")));
+ }
+
+ if (params.containsKey("groupTypeId")) {
+ query.filter(QueryBuilders.termQuery("groupType.id", params.get("groupTypeId")));
+ }
+
+ if (params.containsKey("campusId")) {
+ query.filter(QueryBuilders.termQuery("campus.id", params.get("campusId")));
+ }
+
+ if (params.containsKey("meetingDayId")) {
+ query.filter(QueryBuilders.termQuery("meetingDay.id", params.get("meetingDayId")));
+ }
+
+ if (params.containsKey("childcare")) {
+ query.filter(QueryBuilders.termQuery("childcare", Boolean.parseBoolean(params.get("childcare"))));
+ }
+
+ params.entrySet()
+ .stream()
+ .filter(entry -> entry.getKey().startsWith("udf_"))
+ .map(entry -> QueryBuilders.termQuery("udf." + entry.getKey() + ".id", entry.getValue()))
+ .forEach(query::filter);
+
+ SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
+ searchSourceBuilder.query(query);
+ searchSourceBuilder.size(20);
+
+ SearchRequest searchRequest = new SearchRequest("groups");
+ searchRequest.types("group");
+ searchRequest.source(searchSourceBuilder);
+
+ SearchResponse searchResponse = esClient.search(searchRequest);
+
+ List<GroupSearchDocument> docs = new ArrayList<>();
+ for (final SearchHit hit : searchResponse.getHits().getHits()) {
+ GroupSearchDocument doc = MAPPER.readValue(hit.getSourceAsString(), GroupSearchDocument.class);
+ // Sanitize the output
+ doc.setLeaderEmail(null);
+ if (doc.getImageUrl() != null) {
+ doc.setImageUrl(imageUrlPrefix + "/" + doc.getImageUrl());
+ }
+ docs.add(doc);
+ }
+
+ response.setStatusCode(200);
+ response.setBody(MAPPER.writeValueAsString(docs));
+
+ } catch (Exception e) {
+ LOG.error(e.getMessage());
+ response.setStatusCode(500);
+ try {
+ response.setBody(MAPPER.writeValueAsString(new ErrorResponse(e.getMessage())));
+ } catch (JsonProcessingException _) {
+ // Unexpected.
+ }
+ }
+
+ return response;
+ }
+}