2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.gpstracker.internal.provider;
15 import java.io.BufferedReader;
16 import java.util.Collections;
17 import java.util.List;
19 import javax.servlet.http.HttpServlet;
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.gpstracker.internal.discovery.TrackerDiscoveryService;
26 import org.openhab.binding.gpstracker.internal.handler.TrackerHandler;
27 import org.openhab.binding.gpstracker.internal.message.MessageUtil;
28 import org.openhab.binding.gpstracker.internal.message.dto.LocationMessage;
29 import org.openhab.binding.gpstracker.internal.message.dto.TransitionMessage;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
34 * Abstract callback servlet used by the trackers.
36 * @author Gabor Bicskei - Initial contribution
39 public abstract class AbstractCallbackServlet extends HttpServlet {
41 private static final long serialVersionUID = -2725161358635927815L;
46 private final Logger logger = LoggerFactory.getLogger(AbstractCallbackServlet.class);
49 * Discovery service to handle new trackers
51 private TrackerDiscoveryService discoveryService;
54 * Utility to process messages
56 private MessageUtil messageUtil = new MessageUtil();
61 private TrackerRegistry trackerRegistry;
64 * Constructor called at binding startup.
66 * @param discoveryService Discovery service for new trackers.
67 * @param trackerRegistry Tracker handler registry
69 protected AbstractCallbackServlet(TrackerDiscoveryService discoveryService, TrackerRegistry trackerRegistry) {
70 this.discoveryService = discoveryService;
71 this.trackerRegistry = trackerRegistry;
74 protected abstract String getPath();
77 * Process the HTTP requests from tracker applications
79 * @param req HTTP request
80 * @param resp HTTP response
83 protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
85 StringBuilder jb = new StringBuilder();
86 BufferedReader reader = req.getReader();
89 while ((line = reader.readLine()) != null) {
93 // clear the whitespaces from the message
94 String json = jb.toString().replaceAll("\\p{Z}", "");
95 logger.debug("Post message received from {} tracker: {}", getProvider(), json);
97 LocationMessage message = messageUtil.fromJson(json);
98 if (message != null) {
99 List<? extends LocationMessage> response = processMessage(message);
100 if (response != null) {
101 resp.getWriter().append(messageUtil.toJson(response)).flush();
104 resp.setStatus(HttpServletResponse.SC_OK);
105 } catch (Exception e) {
106 logger.error("Error processing location report:", e);
107 resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
112 * Process the message received by the servlet. If the tracker is unknown the discovery service is notified
113 * so that the next search will pop up the new tracker as result.
115 * @param message The message
116 * @return Response message.
118 private List<? extends LocationMessage> processMessage(LocationMessage message) {
119 String trackerId = message.getTrackerId();
120 if (!trackerId.isEmpty()) {
121 TrackerHandler recorder = getHandlerById(trackerId);
122 if (recorder != null) {
123 if (message instanceof TransitionMessage) {
124 TransitionMessage tm = (TransitionMessage) message;
125 recorder.doTransition(tm);
127 recorder.updateLocation(message);
129 return recorder.getNotifications();
131 logger.debug("There is no handler for tracker {}. Check the inbox for the new tracker.", trackerId);
134 logger.debug("Message without tracker id. Dropping message. {}", messageUtil.toJson(message));
136 return Collections.emptyList();
140 * Find handler for tracker. If the handler does not exist it is registered with discovery service.
142 * @param trackerId Tracker id.
143 * @return Handler for tracker.
145 private @Nullable TrackerHandler getHandlerById(String trackerId) {
146 TrackerHandler handler = trackerRegistry.getTrackerHandler(trackerId);
147 if (handler == null) {
148 // handler was not found - adding the tracker to discovery service.
149 discoveryService.addTracker(trackerId);
157 protected abstract String getProvider();