diff --git a/docs/configuration.rst b/docs/configuration.rst
index 150f96ee..076f9b45 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -539,6 +539,23 @@ Browser source property: ``prefix``
+Browser source property: ``event_suffix``
+"""""""""""""""""""""""""""""""""""""""""
+:Description:
+ The path suffix that will be added to the prefix to determine the complete path that the tracking tag should use for submitting events. Configuring this should not normally be necessary.
+:Default:
+ ``csc-event``
+:Example:
+
+ .. code-block:: none
+
+ divolte.sources.a_source {
+ type = browser
+ event_suffix = web-event
+ }
+
+ In this case the tracking tag will submit events using ``/web-event`` as the URL path.
+
Browser source property: ``party_cookie``
"""""""""""""""""""""""""""""""""""""""""
:Description:
diff --git a/src/main/java/io/divolte/server/BrowserSource.java b/src/main/java/io/divolte/server/BrowserSource.java
index 193104c2..d7190521 100644
--- a/src/main/java/io/divolte/server/BrowserSource.java
+++ b/src/main/java/io/divolte/server/BrowserSource.java
@@ -36,6 +36,7 @@ public class BrowserSource extends HttpSource {
private static final Logger logger = LoggerFactory.getLogger(BrowserSource.class);
private final String pathPrefix;
+ private final String eventSuffix;
private final String javascriptName;
private final HttpHandler javascriptHandler;
private final HttpHandler eventHandler;
@@ -47,6 +48,7 @@ public BrowserSource(final ValidatedConfiguration vc,
final IncomingRequestProcessingPool processingPool) {
this(sourceName,
vc.configuration().getSourceConfiguration(sourceName, BrowserSourceConfiguration.class).prefix,
+ vc.configuration().getSourceConfiguration(sourceName, BrowserSourceConfiguration.class).eventSuffix,
loadTrackingJavaScript(vc, sourceName),
processingPool,
vc.configuration().sourceIndex(sourceName));
@@ -54,11 +56,13 @@ public BrowserSource(final ValidatedConfiguration vc,
private BrowserSource(final String sourceName,
final String pathPrefix,
+ final String eventSuffix,
final TrackingJavaScriptResource trackingJavascript,
final IncomingRequestProcessingPool processingPool,
final int sourceIndex) {
super(sourceName);
this.pathPrefix = pathPrefix;
+ this.eventSuffix = eventSuffix;
javascriptName = trackingJavascript.getScriptName();
javascriptHandler = new AllowedMethodsHandler(new JavaScriptHandler(trackingJavascript), Methods.GET);
final ClientSideCookieEventHandler clientSideCookieEventHandler = new ClientSideCookieEventHandler(processingPool, sourceIndex);
@@ -70,7 +74,7 @@ public PathHandler attachToPathHandler(PathHandler pathHandler) {
final String javascriptPath = pathPrefix + javascriptName;
pathHandler = pathHandler.addExactPath(javascriptPath, javascriptHandler);
logger.info("Registered source[{}] script location: {}", sourceName, javascriptPath);
- final String eventPath = pathPrefix + "csc-event";
+ final String eventPath = pathPrefix + eventSuffix;
pathHandler = pathHandler.addExactPath(eventPath, eventHandler);
logger.info("Registered source[{}] event handler: {}", sourceName, eventPath);
return pathHandler;
diff --git a/src/main/java/io/divolte/server/config/BrowserSourceConfiguration.java b/src/main/java/io/divolte/server/config/BrowserSourceConfiguration.java
index 51aadd05..3b45a1ca 100644
--- a/src/main/java/io/divolte/server/config/BrowserSourceConfiguration.java
+++ b/src/main/java/io/divolte/server/config/BrowserSourceConfiguration.java
@@ -23,9 +23,11 @@ public class BrowserSourceConfiguration extends SourceConfiguration {
private static final String DEFAULT_SESSION_COOKIE = "_dvs";
private static final String DEFAULT_SESSION_TIMEOUT = "30 minutes";
private static final String DEFAULT_PREFIX = "/";
+ private static final String DEFAULT_EVENT_SUFFIX = "csc-event";
public static final BrowserSourceConfiguration DEFAULT_BROWSER_SOURCE_CONFIGURATION = new BrowserSourceConfiguration(
DEFAULT_PREFIX,
+ DEFAULT_EVENT_SUFFIX,
Optional.empty(),
DEFAULT_PARTY_COOKIE,
DurationDeserializer.parseDuration(DEFAULT_PARTY_TIMEOUT),
@@ -34,6 +36,7 @@ public class BrowserSourceConfiguration extends SourceConfiguration {
JavascriptConfiguration.DEFAULT_JAVASCRIPT_CONFIGURATION);
public final String prefix;
+ public final String eventSuffix;
public final Optional cookieDomain;
public final String partyCookie;
public final Duration partyTimeout;
@@ -46,6 +49,7 @@ public class BrowserSourceConfiguration extends SourceConfiguration {
@JsonCreator
@ParametersAreNullableByDefault
BrowserSourceConfiguration(@JsonProperty(defaultValue=DEFAULT_PREFIX) final String prefix,
+ @JsonProperty(defaultValue=DEFAULT_EVENT_SUFFIX) final String eventSuffix,
@Nonnull final Optional cookieDomain,
@JsonProperty(defaultValue=DEFAULT_PARTY_COOKIE) final String partyCookie,
@JsonProperty(defaultValue=DEFAULT_PARTY_TIMEOUT) final Duration partyTimeout,
@@ -54,6 +58,7 @@ public class BrowserSourceConfiguration extends SourceConfiguration {
final JavascriptConfiguration javascript) {
// TODO: register a custom deserializer with Jackson that uses the defaultValue property from the annotation to fix this
this.prefix = Optional.ofNullable(prefix).map(BrowserSourceConfiguration::ensureTrailingSlash).orElse(DEFAULT_PREFIX);
+ this.eventSuffix = Optional.ofNullable(eventSuffix).orElse(DEFAULT_EVENT_SUFFIX);
this.cookieDomain = Objects.requireNonNull(cookieDomain);
this.partyCookie = Optional.ofNullable(partyCookie).orElse(DEFAULT_PARTY_COOKIE);
this.partyTimeout = Optional.ofNullable(partyTimeout).orElseGet(() -> DurationDeserializer.parseDuration(DEFAULT_PARTY_TIMEOUT));
@@ -70,6 +75,7 @@ private static String ensureTrailingSlash(final String s) {
protected MoreObjects.ToStringHelper toStringHelper() {
return super.toStringHelper()
.add("prefix", prefix)
+ .add("eventSuffix", eventSuffix)
.add("cookieDomain", cookieDomain)
.add("partyCookie", partyCookie)
.add("partyTimeout", partyTimeout)
diff --git a/src/main/java/io/divolte/server/js/TrackingJavaScriptResource.java b/src/main/java/io/divolte/server/js/TrackingJavaScriptResource.java
index 33a5b211..839fdb94 100644
--- a/src/main/java/io/divolte/server/js/TrackingJavaScriptResource.java
+++ b/src/main/java/io/divolte/server/js/TrackingJavaScriptResource.java
@@ -51,6 +51,7 @@ private static ImmutableMap createScriptConstants(final BrowserS
browserSourceConfiguration.cookieDomain.ifPresent((v) -> builder.put("COOKIE_DOMAIN", v));
builder.put("LOGGING", browserSourceConfiguration.javascript.logging);
builder.put(SCRIPT_CONSTANT_NAME, browserSourceConfiguration.javascript.name);
+ builder.put("EVENT_SUFFIX", browserSourceConfiguration.eventSuffix);
builder.put("AUTO_PAGE_VIEW_EVENT", browserSourceConfiguration.javascript.autoPageViewEvent);
return builder.build();
}
diff --git a/src/main/resources/divolte.js b/src/main/resources/divolte.js
index b6d490ab..f02bbe7c 100644
--- a/src/main/resources/divolte.js
+++ b/src/main/resources/divolte.js
@@ -34,6 +34,8 @@ var COOKIE_DOMAIN = '';
var LOGGING = false;
/** @define {string} */
var SCRIPT_NAME = 'divolte.js';
+/** @define {string} */
+var EVENT_SUFFIX = 'csc-event';
/** @define {boolean} */
var AUTO_PAGE_VIEW_EVENT = true;
@@ -676,7 +678,7 @@ var AUTO_PAGE_VIEW_EVENT = true;
signalQueue.deliverFirstPendingEvent();
}
};
- image.src = divolteUrl + 'csc-event?' + this.queue[0];
+ image.src = divolteUrl + EVENT_SUFFIX + '?' + this.queue[0];
};
/**
diff --git a/src/test/java/io/divolte/server/SeleniumJavaScriptTest.java b/src/test/java/io/divolte/server/SeleniumJavaScriptTest.java
index 28a94c43..16876a4e 100644
--- a/src/test/java/io/divolte/server/SeleniumJavaScriptTest.java
+++ b/src/test/java/io/divolte/server/SeleniumJavaScriptTest.java
@@ -39,7 +39,8 @@
@ParametersAreNonnullByDefault
public class SeleniumJavaScriptTest extends SeleniumTestBase {
@Test
- public void shouldRegenerateIDsOnExplicitNavigation() {
+ public void shouldRegenerateIDsOnExplicitNavigation() throws Exception {
+ doSetUp();
Preconditions.checkState(null != driver && null != server);
// do a sequence of explicit navigation by setting the browser location
@@ -55,7 +56,8 @@ public void shouldRegenerateIDsOnExplicitNavigation() {
}
@Test
- public void shouldRegenerateIDsOnRefresh() {
+ public void shouldRegenerateIDsOnRefresh() throws Exception {
+ doSetUp();
Preconditions.checkState(null != driver && null != server);
// Navigate to the same page twice
@@ -68,7 +70,8 @@ public void shouldRegenerateIDsOnRefresh() {
}
@Test
- public void shouldRegenerateIDsOnForwardBackNavigation() {
+ public void shouldRegenerateIDsOnForwardBackNavigation() throws Exception {
+ doSetUp();
Preconditions.checkState(null != driver && null != server);
// Navigate to the same page twice
@@ -88,7 +91,8 @@ public void shouldRegenerateIDsOnForwardBackNavigation() {
}
@Test
- public void shouldGenerateIDsOnComplexSeriesOfEvents() {
+ public void shouldGenerateIDsOnComplexSeriesOfEvents() throws Exception {
+ doSetUp();
Preconditions.checkState(null != driver && null != server);
// Navigate to the same page twice
@@ -141,7 +145,8 @@ private static T unchecked(final ExceptionSupplier supplier) {
}
@Test
- public void shouldSignalWhenOpeningPage() throws InterruptedException {
+ public void shouldSignalWhenOpeningPage() throws Exception {
+ doSetUp();
Preconditions.checkState(null != driver && null != server);
final String location = urlOf(BASIC);
@@ -205,7 +210,8 @@ public void shouldSignalWhenOpeningPage() throws InterruptedException {
}
@Test
- public void shouldSendCustomEvent() throws RuntimeException, InterruptedException {
+ public void shouldSendCustomEvent() throws Exception {
+ doSetUp();
Preconditions.checkState(null != driver && null != server);
driver.get(urlOf(BASIC));
server.waitForEvent();
@@ -225,7 +231,8 @@ public void shouldSendCustomEvent() throws RuntimeException, InterruptedExceptio
}
@Test
- public void shouldSetAppropriateCookies() throws RuntimeException, InterruptedException {
+ public void shouldSetAppropriateCookies() throws Exception {
+ doSetUp();
Preconditions.checkState(null != driver && null != server);
driver.get(urlOf(BASIC));
server.waitForEvent();
@@ -244,7 +251,8 @@ public void shouldSetAppropriateCookies() throws RuntimeException, InterruptedEx
}
@Test
- public void shouldPickupProvidedPageViewIdFromHash() throws RuntimeException, InterruptedException {
+ public void shouldPickupProvidedPageViewIdFromHash() throws Exception {
+ doSetUp();
Preconditions.checkState(null != driver && null != server);
driver.get(urlOf(PAGE_VIEW_SUPPLIED));
final EventPayload payload = server.waitForEvent();
@@ -254,8 +262,14 @@ public void shouldPickupProvidedPageViewIdFromHash() throws RuntimeException, In
assertEquals("supercalifragilisticexpialidocious0", eventData.eventId);
}
- @Before
- public void setup() throws Exception {
- doSetUp();
+ @Test
+ public void shouldUseConfiguredEventSuffix() throws Exception {
+ doSetUp("selenium-test-custom-event-suffix.conf");
+ Preconditions.checkState(null != driver && null != server);
+ driver.get(urlOf(BASIC));
+ final EventPayload payload = server.waitForEvent();
+ final DivolteEvent eventData = payload.event;
+
+ assertEquals("pageView", eventData.eventType.get());
}
}
diff --git a/src/test/java/io/divolte/server/SeleniumTestBase.java b/src/test/java/io/divolte/server/SeleniumTestBase.java
index 928ebbca..f0fb5008 100644
--- a/src/test/java/io/divolte/server/SeleniumTestBase.java
+++ b/src/test/java/io/divolte/server/SeleniumTestBase.java
@@ -149,7 +149,7 @@ protected void doSetUp() throws Exception {
doSetUp(Optional.empty());
}
- protected void doSetUp(final Optional configFileName) throws Exception {
+ private void doSetUp(final Optional configFileName) throws Exception {
final String driverName = System.getenv().getOrDefault(DRIVER_ENV_VAR, PHANTOMJS_DRIVER);
switch (driverName) {
diff --git a/src/test/resources/selenium-test-custom-event-suffix.conf b/src/test/resources/selenium-test-custom-event-suffix.conf
new file mode 100644
index 00000000..44504ff9
--- /dev/null
+++ b/src/test/resources/selenium-test-custom-event-suffix.conf
@@ -0,0 +1,21 @@
+//
+// Copyright 2016 GoDataDriven B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Instead of using the default 'csc-event' endpoint, use a different value.
+divolte.sources.browser {
+ type = browser
+ event_suffix = web-event
+}