aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2017-11-24 16:55:15 +1300
committerGitHub <noreply@github.com>2017-11-24 16:55:15 +1300
commit924c28dc7435c7b1f95a3a19d191affb408ce704 (patch)
tree13264afdabb54f08aa786d61fdf3e2c55afde23e
parenta358302a32872fe9d6def421166703f3a586e337 (diff)
parent00c5cef324ed644ca5cae282864f3bca9629467a (diff)
downloadtraccar-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.java111
-rw-r--r--src/org/traccar/notification/EventForwarder.java54
-rw-r--r--src/org/traccar/notification/JsonTypeEventForwarder.java20
-rw-r--r--src/org/traccar/notification/MultiPartEventForwarder.java46
-rw-r--r--src/org/traccar/notification/NotificationFormatter.java39
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();
}
+
}