diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2017-11-24 16:55:15 +1300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-24 16:55:15 +1300 |
commit | 924c28dc7435c7b1f95a3a19d191affb408ce704 (patch) | |
tree | 13264afdabb54f08aa786d61fdf3e2c55afde23e | |
parent | a358302a32872fe9d6def421166703f3a586e337 (diff) | |
parent | 00c5cef324ed644ca5cae282864f3bca9629467a (diff) | |
download | traccar-server-924c28dc7435c7b1f95a3a19d191affb408ce704.tar.gz traccar-server-924c28dc7435c7b1f95a3a19d191affb408ce704.tar.bz2 traccar-server-924c28dc7435c7b1f95a3a19d191affb408ce704.zip |
Merge pull request #3624 from Shinryuken/payload-as-form-param
Support for custom params on EventForwarder
-rw-r--r-- | src/org/traccar/Context.java | 111 | ||||
-rw-r--r-- | src/org/traccar/notification/EventForwarder.java | 54 | ||||
-rw-r--r-- | src/org/traccar/notification/JsonTypeEventForwarder.java | 20 | ||||
-rw-r--r-- | src/org/traccar/notification/MultiPartEventForwarder.java | 46 | ||||
-rw-r--r-- | src/org/traccar/notification/NotificationFormatter.java | 39 |
5 files changed, 196 insertions, 74 deletions
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index 511ec980e..3681cc2cc 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -71,6 +71,8 @@ import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.MozillaGeolocationProvider; import org.traccar.geolocation.OpenCellIdGeolocationProvider; import org.traccar.notification.EventForwarder; +import org.traccar.notification.JsonTypeEventForwarder; +import org.traccar.notification.MultiPartEventForwarder; import org.traccar.reports.model.TripsConfig; import org.traccar.smpp.SmppClient; import org.traccar.web.WebServer; @@ -323,6 +325,9 @@ public final class Context { objectMapper = new ObjectMapper(); objectMapper.setConfig( objectMapper.getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); + if (Context.getConfig().getBoolean("mapper.prettyPrintedJson")) { + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + } if (config.hasKey("database.url")) { dataManager = new DataManager(config); @@ -349,24 +354,7 @@ public final class Context { } if (config.getBoolean("geolocation.enable")) { - String type = config.getString("geolocation.type", "mozilla"); - String url = config.getString("geolocation.url"); - String key = config.getString("geolocation.key"); - - switch (type) { - case "google": - geolocationProvider = new GoogleGeolocationProvider(key); - break; - case "opencellid": - geolocationProvider = new OpenCellIdGeolocationProvider(key); - break; - case "unwired": - geolocationProvider = new UnwiredGeolocationProvider(url, key); - break; - default: - geolocationProvider = new MozillaGeolocationProvider(key); - break; - } + initGeolocationModule(); } if (config.getBoolean("web.enable")) { @@ -380,39 +368,17 @@ public final class Context { tripsConfig = initTripsConfig(); if (config.getBoolean("event.enable")) { - geofenceManager = new GeofenceManager(dataManager); - calendarManager = new CalendarManager(dataManager); - notificationManager = new NotificationManager(dataManager); - Properties velocityProperties = new Properties(); - velocityProperties.setProperty("file.resource.loader.path", - Context.getConfig().getString("templates.rootPath", "templates") + "/"); - velocityProperties.setProperty("runtime.log.logsystem.class", - "org.apache.velocity.runtime.log.NullLogChute"); - - String address; - try { - address = config.getString("web.address", InetAddress.getLocalHost().getHostAddress()); - } catch (UnknownHostException e) { - address = "localhost"; - } - - String webUrl = URIUtil.newURI("http", address, config.getInteger("web.port", 8082), "", ""); - webUrl = Context.getConfig().getString("web.url", webUrl); - velocityProperties.setProperty("web.url", webUrl); - - velocityEngine = new VelocityEngine(); - velocityEngine.init(velocityProperties); - - motionEventHandler = new MotionEventHandler(tripsConfig); - overspeedEventHandler = new OverspeedEventHandler( - Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000, - Context.getConfig().getBoolean("event.overspeed.notRepeat")); + initEventsModule(); } serverManager = new ServerManager(); if (config.getBoolean("event.forward.enable")) { - eventForwarder = new EventForwarder(); + if (Context.getConfig().getBoolean("event.forward.payloadAsParamMode")) { + eventForwarder = new MultiPartEventForwarder(); + } else { + eventForwarder = new JsonTypeEventForwarder(); + } } attributesManager = new AttributesManager(dataManager); @@ -429,6 +395,59 @@ public final class Context { } + private static void initGeolocationModule() { + + String type = config.getString("geolocation.type", "mozilla"); + String url = config.getString("geolocation.url"); + String key = config.getString("geolocation.key"); + + switch (type) { + case "google": + geolocationProvider = new GoogleGeolocationProvider(key); + break; + case "opencellid": + geolocationProvider = new OpenCellIdGeolocationProvider(key); + break; + case "unwired": + geolocationProvider = new UnwiredGeolocationProvider(url, key); + break; + default: + geolocationProvider = new MozillaGeolocationProvider(key); + break; + } + } + + private static void initEventsModule() { + + geofenceManager = new GeofenceManager(dataManager); + calendarManager = new CalendarManager(dataManager); + notificationManager = new NotificationManager(dataManager); + Properties velocityProperties = new Properties(); + velocityProperties.setProperty("file.resource.loader.path", + Context.getConfig().getString("templates.rootPath", "templates") + "/"); + velocityProperties.setProperty("runtime.log.logsystem.class", + "org.apache.velocity.runtime.log.NullLogChute"); + + String address; + try { + address = config.getString("web.address", InetAddress.getLocalHost().getHostAddress()); + } catch (UnknownHostException e) { + address = "localhost"; + } + + String webUrl = URIUtil.newURI("http", address, config.getInteger("web.port", 8082), "", ""); + webUrl = Context.getConfig().getString("web.url", webUrl); + velocityProperties.setProperty("web.url", webUrl); + + velocityEngine = new VelocityEngine(); + velocityEngine.init(velocityProperties); + + motionEventHandler = new MotionEventHandler(tripsConfig); + overspeedEventHandler = new OverspeedEventHandler( + Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000, + Context.getConfig().getBoolean("event.overspeed.notRepeat")); + } + public static void init(IdentityManager testIdentityManager) { config = new Config(); objectMapper = new ObjectMapper(); diff --git a/src/org/traccar/notification/EventForwarder.java b/src/org/traccar/notification/EventForwarder.java index ac37f980c..68c3ea221 100644 --- a/src/org/traccar/notification/EventForwarder.java +++ b/src/org/traccar/notification/EventForwarder.java @@ -17,6 +17,9 @@ package org.traccar.notification; import com.fasterxml.jackson.core.JsonProcessingException; import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder; +import java.util.Arrays; +import java.util.List; + import org.traccar.Context; import org.traccar.helper.Log; import org.traccar.model.Device; @@ -27,15 +30,16 @@ import org.traccar.model.Position; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; +import com.ning.http.client.FluentCaseInsensitiveStringsMap; -public final class EventForwarder { +public abstract class EventForwarder { - private String url; - private String header; + private final String url; + private final String header; public EventForwarder() { url = Context.getConfig().getString("event.forward.url", "http://localhost/"); - header = Context.getConfig().getString("event.forward.header", ""); + header = Context.getConfig().getString("event.forward.header"); } private static final String KEY_POSITION = "position"; @@ -43,26 +47,39 @@ public final class EventForwarder { private static final String KEY_GEOFENCE = "geofence"; private static final String KEY_DEVICE = "device"; - public void forwardEvent(Event event, Position position) { + public final void forwardEvent(Event event, Position position) { BoundRequestBuilder requestBuilder = Context.getAsyncHttpClient().preparePost(url); + requestBuilder.setBodyEncoding(StandardCharsets.UTF_8.name()); - 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()); - } - } + requestBuilder.addHeader("Content-Type", getContentType()); + + if (header != null && !header.isEmpty()) { + FluentCaseInsensitiveStringsMap params = new FluentCaseInsensitiveStringsMap(); + params.putAll(splitIntoKeyValues(header, ":")); + requestBuilder.setHeaders(params); } - requestBuilder.setBody(preparePayload(event, position)); + setContent(event, position, requestBuilder); requestBuilder.execute(); } - private byte[] preparePayload(Event event, Position position) { + protected Map<String, List<String>> splitIntoKeyValues(String params, String separator) { + + String[] splitedLine; + Map<String, List<String>> 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; + } + + protected String prepareJsonPayload(Event event, Position position) { Map<String, Object> data = new HashMap<>(); data.put(KEY_EVENT, event); if (position != null) { @@ -81,11 +98,14 @@ public final class EventForwarder { } } try { - return Context.getObjectMapper().writeValueAsString(data).getBytes(StandardCharsets.UTF_8); + return Context.getObjectMapper().writeValueAsString(data); } catch (JsonProcessingException e) { Log.warning(e); return null; } } + protected abstract String getContentType(); + protected abstract void setContent(Event event, Position position, BoundRequestBuilder requestBuilder); + } diff --git a/src/org/traccar/notification/JsonTypeEventForwarder.java b/src/org/traccar/notification/JsonTypeEventForwarder.java new file mode 100644 index 000000000..c1e4220d0 --- /dev/null +++ b/src/org/traccar/notification/JsonTypeEventForwarder.java @@ -0,0 +1,20 @@ +package org.traccar.notification;
+
+import org.traccar.model.Event;
+import org.traccar.model.Position;
+
+import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
+
+public class JsonTypeEventForwarder extends EventForwarder {
+
+ @Override
+ protected String getContentType() {
+ return "application/json; charset=utf-8";
+ }
+
+ @Override
+ protected void setContent(Event event, Position position, BoundRequestBuilder requestBuilder) {
+ requestBuilder.setBody(prepareJsonPayload(event, position));
+ }
+
+}
diff --git a/src/org/traccar/notification/MultiPartEventForwarder.java b/src/org/traccar/notification/MultiPartEventForwarder.java new file mode 100644 index 000000000..f4c36d3e4 --- /dev/null +++ b/src/org/traccar/notification/MultiPartEventForwarder.java @@ -0,0 +1,46 @@ +package org.traccar.notification; + +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.traccar.Context; +import org.traccar.model.Event; +import org.traccar.model.Position; + +import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder; +import com.ning.http.client.multipart.StringPart; + +public class MultiPartEventForwarder extends EventForwarder { + + private final String payloadParamName; + private final String additionalParams; + + public MultiPartEventForwarder() { + payloadParamName = Context.getConfig().getString("event.forward.paramMode.payloadParamName", "payload"); + additionalParams = Context.getConfig().getString("event.forward.paramMode.additionalParams"); + } + + @Override + protected String getContentType() { + return "multipart/form-data"; + } + + @Override + protected void setContent(Event event, Position position, BoundRequestBuilder requestBuilder) { + + if (additionalParams != null && !additionalParams.isEmpty()) { + Map<String, List<String>> paramsToAdd = splitIntoKeyValues(additionalParams, "="); + + for (Entry<String, List<String>> param : paramsToAdd.entrySet()) { + for (String singleParamValue : param.getValue()) { + requestBuilder.addBodyPart(new StringPart(param.getKey(), singleParamValue, null, + StandardCharsets.UTF_8)); + } + } + } + requestBuilder.addBodyPart(new StringPart(payloadParamName, + prepareJsonPayload(event, position), "application/json", StandardCharsets.UTF_8)); + } +} diff --git a/src/org/traccar/notification/NotificationFormatter.java b/src/org/traccar/notification/NotificationFormatter.java index 8da819430..114825a83 100644 --- a/src/org/traccar/notification/NotificationFormatter.java +++ b/src/org/traccar/notification/NotificationFormatter.java @@ -18,6 +18,7 @@ package org.traccar.notification; import java.io.StringWriter; import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; import java.util.Locale; import org.apache.velocity.Template; @@ -39,6 +40,7 @@ public final class NotificationFormatter { } public static VelocityContext prepareContext(long userId, Event event, Position position) { + User user = Context.getPermissionsManager().getUser(userId); Device device = Context.getIdentityManager().getById(event.getDeviceId()); @@ -68,31 +70,46 @@ public final class NotificationFormatter { } public static Template getTemplate(Event event, String path) { + + String templateFilePath; Template template; + try { - template = Context.getVelocityEngine().getTemplate(path + event.getType() + ".vm", - StandardCharsets.UTF_8.name()); + templateFilePath = Paths.get(path, event.getType() + ".vm").toString(); + template = Context.getVelocityEngine().getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); } catch (ResourceNotFoundException error) { Log.warning(error); - template = Context.getVelocityEngine().getTemplate(path + "unknown.vm", - StandardCharsets.UTF_8.name()); + templateFilePath = Paths.get(path, "unknown.vm").toString(); + template = Context.getVelocityEngine().getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); } return template; } public static MailMessage formatMailMessage(long userId, Event event, Position position) { + String templatePath = Context.getConfig().getString("mail.templatesPath", "mail"); VelocityContext velocityContext = prepareContext(userId, event, position); - StringWriter writer = new StringWriter(); - getTemplate(event, Context.getConfig().getString("mail.templatesPath", "mail") + "/") - .merge(velocityContext, writer); - return new MailMessage((String) velocityContext.get("subject"), writer.toString()); + String formattedMessage = formatMessage(velocityContext, userId, event, position, templatePath); + + return new MailMessage((String) velocityContext.get("subject"), formattedMessage); } public static String formatSmsMessage(long userId, Event event, Position position) { - VelocityContext velocityContext = prepareContext(userId, event, position); + String templatePath = Context.getConfig().getString("sms.templatesPath", "sms"); + + return formatMessage(null, userId, event, position, templatePath); + } + + private static String formatMessage(VelocityContext vc, Long userId, Event event, Position position, + String templatePath) { + + VelocityContext velocityContext = vc; + if (velocityContext == null) { + velocityContext = prepareContext(userId, event, position); + } StringWriter writer = new StringWriter(); - getTemplate(event, Context.getConfig().getString("sms.templatesPath", "sms") + "/") - .merge(velocityContext, writer); + getTemplate(event, templatePath).merge(velocityContext, writer); + return writer.toString(); } + } |