From d1327cef4df28065b3d9879b07c826d6623f98e0 Mon Sep 17 00:00:00 2001 From: Shinryuken Date: Sat, 4 Nov 2017 17:34:11 +0100 Subject: Adding support for additional parameters on post body request (pushover support) Hi, i implemented a new modality when sending event messages inside EventForwarder, now you can send requests as a "form-urlencoded", this means that the actual payload will be sent as a form parameter (the parameter name is configurable), this strategy will let you to add another parameters inside the form body message too. You can add new custom form params almost on the same way as the custom headers are inserted (event.forward.header), the only difference is that you will use the equals "=" char instead of ":" as key/value separator. You can enable this mode using the option: "event.forward.payloadAsParamMode", when using this mode you can use the other 2 configuration elements, "event.forward.paramMode.payloadParamName" if you want to change the form name param of the payload (default is "payload") and "event.forward.paramMode.additionalParams" to specify additional key/value form params. I added an option to prettyPrint the payload messages too, you can enable it using "event.forward.prettyPrintedPayload", i decided to add this option only for the EventForwarder behaviour. This is an example (using all the new params) that lets you integrate traccar server with the pushover platform. 60 true true https://api.pushover.net/1/messages.json true true message token=YOUR_TOKEN_ID user=YOUR_USER_ID I tested the new options and they work pretty well. Tried to make the change as clean as possible and avoiding code duplications. This mode does not change or affects the actual behabiour of the module. Let me know what do you think. --- src/org/traccar/notification/EventForwarder.java | 88 +++++++++++++++++++----- 1 file changed, 72 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/org/traccar/notification/EventForwarder.java b/src/org/traccar/notification/EventForwarder.java index ac37f980c..7daa4d16c 100644 --- a/src/org/traccar/notification/EventForwarder.java +++ b/src/org/traccar/notification/EventForwarder.java @@ -15,8 +15,12 @@ */ package org.traccar.notification; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.traccar.Context; import org.traccar.helper.Log; import org.traccar.model.Device; @@ -24,18 +28,28 @@ import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder; +import com.ning.http.client.FluentCaseInsensitiveStringsMap; public final class EventForwarder { private String url; private String header; + private boolean payloadAsParamMode; + private String payloadParamName; + private String additionalParams; + private ObjectWriter internalObjectWriter; public EventForwarder() { url = Context.getConfig().getString("event.forward.url", "http://localhost/"); header = Context.getConfig().getString("event.forward.header", ""); + payloadAsParamMode = Context.getConfig().getBoolean("event.forward.payloadAsParamMode"); + payloadParamName = Context.getConfig().getString("event.forward.paramMode.payloadParamName", "payload"); + additionalParams = Context.getConfig().getString("event.forward.paramMode.additionalParams", ""); + + internalObjectWriter = initInternalObjectWriter(); } private static final String KEY_POSITION = "position"; @@ -46,23 +60,59 @@ public final class EventForwarder { public void forwardEvent(Event event, Position position) { BoundRequestBuilder requestBuilder = Context.getAsyncHttpClient().preparePost(url); + requestBuilder.setBodyEncoding(StandardCharsets.UTF_8.name()); + + setContentTypeFromMode(requestBuilder); - requestBuilder.addHeader("Content-Type", "application/json; charset=utf-8"); if (!header.equals("")) { - String[] headerLines = header.split("\\r?\\n"); - for (String headerLine: headerLines) { - String[] splitedLine = headerLine.split(":", 2); - if (splitedLine.length == 2) { - requestBuilder.setHeader(splitedLine[0].trim(), splitedLine[1].trim()); - } - } + FluentCaseInsensitiveStringsMap params = new FluentCaseInsensitiveStringsMap(); + params.putAll(splitParams(header, ":")); + requestBuilder.setHeaders(params); } - requestBuilder.setBody(preparePayload(event, position)); + setContent(requestBuilder, preparePayload(event, position)); + requestBuilder.execute(); } - private byte[] preparePayload(Event event, Position position) { + private void setContent(BoundRequestBuilder requestBuilder, String payload) { + + if (payloadAsParamMode) { + + if (!additionalParams.equals("")) { + requestBuilder.setFormParams(splitParams(additionalParams, "=")); + } + requestBuilder.addFormParam(payloadParamName, payload); + + } else { + requestBuilder.setBody(payload); + } + } + + private Map> splitParams(String params, String separator) { + + String[] splitedLine; + Map> paramsMap = new HashMap<>(); + String[] paramsLines = params.split("\\r?\\n"); + + for (String paramLine: paramsLines) { + splitedLine = paramLine.split(separator, 2); + if (splitedLine.length == 2) { + paramsMap.put(splitedLine[0].trim(), Arrays.asList(splitedLine[1].trim())); + } + } + return paramsMap; + } + + private void setContentTypeFromMode(BoundRequestBuilder requestBuilder) { + if (payloadAsParamMode) { + requestBuilder.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); + } else { + requestBuilder.addHeader("Content-Type", "application/json; charset=utf-8"); + } + } + + private String preparePayload(Event event, Position position) { Map data = new HashMap<>(); data.put(KEY_EVENT, event); if (position != null) { @@ -81,11 +131,17 @@ public final class EventForwarder { } } try { - return Context.getObjectMapper().writeValueAsString(data).getBytes(StandardCharsets.UTF_8); + return internalObjectWriter.writeValueAsString(data); } catch (JsonProcessingException e) { Log.warning(e); return null; } } + private ObjectWriter initInternalObjectWriter() { + return Context.getConfig().getBoolean("event.forward.prettyPrintedPayload") + ? Context.getObjectMapper().writerWithDefaultPrettyPrinter() + : Context.getObjectMapper().writer(); + } + } -- cgit v1.2.3