]> git.basschouten.com Git - openhab-addons.git/blob
b6bc065987aea11ae406de1dc9c741c20fa3a02a
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.gpstracker.internal.provider;
14
15 import java.io.BufferedReader;
16 import java.util.Collections;
17 import java.util.List;
18
19 import javax.servlet.http.HttpServlet;
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse;
22
23 import org.openhab.binding.gpstracker.internal.discovery.TrackerDiscoveryService;
24 import org.openhab.binding.gpstracker.internal.handler.TrackerHandler;
25 import org.openhab.binding.gpstracker.internal.message.LocationMessage;
26 import org.openhab.binding.gpstracker.internal.message.MessageUtil;
27 import org.openhab.binding.gpstracker.internal.message.TransitionMessage;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * Abstract callback servlet used by the trackers.
33  *
34  * @author Gabor Bicskei - Initial contribution
35  */
36 public abstract class AbstractCallbackServlet extends HttpServlet {
37
38     private static final long serialVersionUID = -2725161358635927815L;
39
40     /**
41      * Class logger
42      */
43     private final Logger logger = LoggerFactory.getLogger(AbstractCallbackServlet.class);
44
45     /**
46      * Discovery service to handle new trackers
47      */
48     private TrackerDiscoveryService discoveryService;
49
50     /**
51      * Utility to process messages
52      */
53     private MessageUtil messageUtil = new MessageUtil();
54
55     /**
56      * Tracker registry
57      */
58     private TrackerRegistry trackerRegistry;
59
60     /**
61      * Constructor called at binding startup.
62      *
63      * @param discoveryService Discovery service for new trackers.
64      * @param trackerRegistry Tracker handler registry
65      */
66     protected AbstractCallbackServlet(TrackerDiscoveryService discoveryService, TrackerRegistry trackerRegistry) {
67         this.discoveryService = discoveryService;
68         this.trackerRegistry = trackerRegistry;
69     }
70
71     protected abstract String getPath();
72
73     /**
74      * Process the HTTP requests from tracker applications
75      *
76      * @param req HTTP request
77      * @param resp HTTP response
78      */
79     @Override
80     protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
81         try {
82             StringBuilder jb = new StringBuilder();
83             BufferedReader reader = req.getReader();
84
85             String line;
86             while ((line = reader.readLine()) != null) {
87                 jb.append(line);
88             }
89
90             // clear the whitespaces from the message
91             String json = jb.toString().replaceAll("\\p{Z}", "");
92             logger.debug("Post message received from {} tracker: {}", getProvider(), json);
93
94             LocationMessage message = messageUtil.fromJson(json);
95             if (message != null) {
96                 List<? extends LocationMessage> response = processMessage(message);
97                 if (response != null) {
98                     resp.getWriter().append(messageUtil.toJson(response)).flush();
99                 }
100             }
101             resp.setStatus(HttpServletResponse.SC_OK);
102         } catch (Exception e) {
103             logger.error("Error processing location report:", e);
104             resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
105         }
106     }
107
108     /**
109      * Process the message received by the servlet. If the tracker is unknown the discovery service is notified
110      * so that the next search will pop up the new tracker as result.
111      *
112      * @param message The message
113      * @return Response message.
114      */
115     private List<? extends LocationMessage> processMessage(LocationMessage message) {
116         String trackerId = message.getTrackerId();
117         if (!trackerId.isEmpty()) {
118             TrackerHandler recorder = getHandlerById(trackerId);
119             if (recorder != null) {
120                 if (message instanceof TransitionMessage) {
121                     TransitionMessage tm = (TransitionMessage) message;
122                     recorder.doTransition(tm);
123                 } else {
124                     recorder.updateLocation(message);
125                 }
126                 return recorder.getNotifications();
127             } else {
128                 logger.debug("There is no handler for tracker {}. Check the inbox for the new tracker.", trackerId);
129             }
130         } else {
131             logger.debug("Message without tracker id. Dropping message. {}", messageUtil.toJson(message));
132         }
133         return Collections.emptyList();
134     }
135
136     /**
137      * Find handler for tracker. If the handler does not exist it is registered with discovery service.
138      *
139      * @param trackerId Tracker id.
140      * @return Handler for tracker.
141      */
142     private TrackerHandler getHandlerById(String trackerId) {
143         if (trackerId != null) {
144             TrackerHandler handler = trackerRegistry.getTrackerHandler(trackerId);
145             if (handler == null) {
146                 // handler was not found - adding the tracker to discovery service.
147                 discoveryService.addTracker(trackerId);
148             } else {
149                 return handler;
150             }
151         }
152         return null;
153     }
154
155     protected abstract String getProvider();
156 }