summaryrefslogtreecommitdiff
path: root/src/main/java/com/p4square/groupsindexer/SearchFields.java
blob: 8c21449118fd4b24de65e6e1521442629189f726 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package com.p4square.groupsindexer;

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.ccbapi.CCBAPI;
import com.p4square.ccbapi.CCBAPIClient;
import com.p4square.ccbapi.model.*;
import com.p4square.groupsindexer.model.ErrorResponse;
import com.p4square.groupsindexer.model.SearchField;
import com.p4square.groupsindexer.model.StringPair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.stream.Collectors;

/**
 * SearchFields is an API Gateway Proxy which returns the searchable dropdown fields and their choices.
 *
 * Required (custom) environment variables:
 * <ul>
 *  <li>CCBAPIURL</li>
 *  <li>CCBAPIUser</li>
 *  <li>CCBAPIPassword</li>
 * </ul>
 *
 */
public class SearchFields implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {

    private static final long REFRESH_INTERVAL_MS = 15 * 60 * 1000;

    private static final Logger LOG = LogManager.getLogger(GroupsSearch.class);
    private static final ObjectMapper MAPPER = new ObjectMapper();

    private final CCBAPI ccbClient;

    private List<SearchField> cachedFields;
    private long lastRefresh;

    public SearchFields() throws Exception {
        // Setup CCB Client
        final String CCBAPIURL = System.getenv("CCBAPIURL");
        final String CCBAPIUser = System.getenv("CCBAPIUser");
        final String CCBAPIPassword = System.getenv("CCBAPIPassword");
        ccbClient = new CCBAPIClient(new URI(CCBAPIURL), CCBAPIUser, CCBAPIPassword);
    }

    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
        final APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        try {
            final List<SearchField> fields = getFields();
            if (fields == null) {
                response.setStatusCode(500);
                response.setBody(MAPPER.writeValueAsString(new ErrorResponse("Unable to get search fields.")));
                return response;
            }

            response.setStatusCode(200);
            response.setBody(MAPPER.writeValueAsString(fields));

        } catch (Exception e) {
            LOG.error(e.getMessage());
            response.setStatusCode(500);
            try {
                response.setBody(MAPPER.writeValueAsString(new ErrorResponse(e.getMessage())));
            } catch (JsonProcessingException _) {
                // Unexpected.
            }
        }

        return response;
    }

    private synchronized List<SearchField> getFields() {
        if (System.currentTimeMillis() - lastRefresh < REFRESH_INTERVAL_MS) {
            LOG.debug("Using cached CCB fields");
            return cachedFields;
        }

        try {
            LOG.info("Fetching fields from CCB");

            cachedFields = new ArrayList<>();
            final GetCustomFieldLabelsResponse labels = ccbClient.getCustomFieldLabels();

            cachedFields.add(new SearchField("groupTypeId", "Group Type", getValues(LookupTableType.GROUP_TYPE)));
            // TODO fields.add(new SearchField("campusId", "Campus", ...));
            cachedFields.add(new SearchField("meetingDayId", "Day", getValues(LookupTableType.MEET_DAY)));


            for (final CustomField field : labels.getCustomFields()) {
                final LookupTableType type = getTypeFromString(field.getName());
                if (type != null) {
                    cachedFields.add(new SearchField(getSearchFieldIdForType(type), field.getLabel(), getValues(type)));
                }
            }

            cachedFields.add(new SearchField("childcare", "Childcare",
                    Arrays.asList(StringPair.of("true", "Yes"), StringPair.of("false", "No"))));

            lastRefresh = System.currentTimeMillis();
            return cachedFields;

        } catch (Exception e) {
            LOG.error(e.getMessage());
            return null;
        }
    }

    private LookupTableType getTypeFromString(String name) {
        switch (name) {
            case "udf_grp_pulldown_1":
                return LookupTableType.UDF_GRP_PULLDOWN_1;
            case "udf_grp_pulldown_2":
                return LookupTableType.UDF_GRP_PULLDOWN_2;
            case "udf_grp_pulldown_3":
                return LookupTableType.UDF_GRP_PULLDOWN_3;
            default:
                return null;
        }
    }

    private String getSearchFieldIdForType(LookupTableType type) {
        switch (type) {
            case UDF_GRP_PULLDOWN_1:
                return "udf_1";
            case UDF_GRP_PULLDOWN_2:
                return "udf_2";
            case UDF_GRP_PULLDOWN_3:
                return "udf_3";
            default:
                throw new IllegalArgumentException();
        }
    }

    private List<StringPair> getValues(LookupTableType type) throws IOException {
        final GetLookupTableRequest lookupTableRequest = new GetLookupTableRequest().withType(type);
        final GetLookupTableResponse lookupTable = ccbClient.getLookupTable(lookupTableRequest);

        return lookupTable.getItems()
                .stream()
                .map(entry -> StringPair.of(String.valueOf(entry.getId()), entry.getName()))
                .collect(Collectors.toList());
    }

}