Skip to content
85 changes: 60 additions & 25 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.oss</groupId>
Expand All @@ -8,35 +9,37 @@

<groupId>com.brsanthu</groupId>
<artifactId>google-analytics-java</artifactId>
<version>2.0.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
<java-version>1.8</java-version>
<slf4j-version>1.7.25</slf4j-version>
<junit.version>4.11</junit.version>
<httpclient-version>4.5.3</httpclient-version>
<httpclient-version>4.5.8</httpclient-version>
<junit.jupiter.version>5.4.2</junit.jupiter.version>
<junit.platform.version>1.4.0</junit.platform.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mockito.version>2.27.0</mockito.version>
<assertj.version>3.12.0</assertj.version>
</properties>

<build>
<plugins>

<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>

<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.2</version>
<version>3.8.1</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
Expand All @@ -58,7 +61,7 @@

<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<version>3.1.0</version>
<configuration>
<excludePackageNames>*.internal.*</excludePackageNames>
<failOnError>false</failOnError>
Expand All @@ -76,7 +79,7 @@

<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<version>3.1.2</version>
<configuration>
<useDefaultManifestFile>true</useDefaultManifestFile>
<archive>
Expand All @@ -91,7 +94,7 @@

<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<version>2.22.2</version>
<configuration>
<surefire.useFile>false</surefire.useFile>
</configuration>
Expand All @@ -100,7 +103,7 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.3.0</version>
<version>4.2.0</version>
<configuration>
<manifestLocation>META-INF</manifestLocation>
<instructions>
Expand Down Expand Up @@ -129,7 +132,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version><!--$NO-MVN-MAN-VER$-->
<version>2.5.3</version><!--$NO-MVN-MAN-VER$ -->
</plugin>
</plugins>
</build>
Expand All @@ -156,10 +159,42 @@
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>${junit.platform.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand All @@ -175,8 +210,8 @@
<url>https://github.com/brsanthu/google-analytics-java</url>
<connection>scm:git:git@github.com:brsanthu/google-analytics-java</connection>
<developerConnection>scm:git:git@github.com:brsanthu/google-analytics-java</developerConnection>
<tag>google-analytics-java-1.1.2</tag>
</scm>
<tag>google-analytics-java-1.1.2</tag>
</scm>
<issueManagement>
<system>github.com</system>
<url>https://github.com/brsanthu/google-analytics-java/issues</url>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ public class GoogleAnalyticsBuilder {
private DefaultRequest defaultRequest = new DefaultRequest();
private HttpClient httpClient;
private ExecutorService executor;
private GoogleAnalyticsExecutor googleAnalyticsExecutor;

public GoogleAnalyticsBuilder withGoogleAnalyticsExecutor(GoogleAnalyticsExecutor googleAnalyticsExecutor) {
this.googleAnalyticsExecutor = googleAnalyticsExecutor;
return this;
}

public GoogleAnalyticsBuilder withConfig(GoogleAnalyticsConfig config) {
this.config = GaUtils.firstNotNull(config, new GoogleAnalyticsConfig());
Expand Down Expand Up @@ -64,7 +70,7 @@ public GoogleAnalytics build() {
discoverer.discoverParameters(config, defaultRequest);
}

return new GoogleAnalyticsImpl(config, defaultRequest, createHttpClient(), createExecutor());
return new GoogleAnalyticsImpl(config, defaultRequest, createHttpClient(), createExecutor(), googleAnalyticsExecutor);
}

protected HttpClient createHttpClient() {
Expand Down
110 changes: 109 additions & 1 deletion src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public class GoogleAnalyticsConfig {
private int batchSize = 20;
private String httpUrl = "http://www.google-analytics.com/collect";
private String httpsUrl = "https://www.google-analytics.com/collect";
private String httpDebugUrl = "http://www.google-analytics.com/debug/collect";
private String httpsDebugUrl = "https://www.google-analytics.com/debug/collect";
private String batchUrl = "https://www.google-analytics.com/batch";
private String userAgent = null;
private String proxyHost = null;
Expand All @@ -52,6 +54,10 @@ public class GoogleAnalyticsConfig {
private boolean discoverRequestParameters = true;
private boolean gatherStats = false;
private RequestParameterDiscoverer requestParameterDiscoverer = new DefaultRequestParameterDiscoverer();
private GoogleAnalyticsExceptionHandler exceptionHandler;
private boolean autoQueueTimeEnabled = true;
private boolean anonymizeUserIp = false;
private boolean hitDebug = false;

public RequestParameterDiscoverer getRequestParameterDiscoverer() {
return requestParameterDiscoverer;
Expand Down Expand Up @@ -125,7 +131,7 @@ public GoogleAnalyticsConfig setDeriveSystemParameters(boolean deriveSystemPrope
* </p>
*/
public GoogleAnalyticsConfig setDiscoverRequestParameters(boolean discoverSystemParameters) {
this.discoverRequestParameters = discoverSystemParameters;
discoverRequestParameters = discoverSystemParameters;
return this;
}

Expand Down Expand Up @@ -274,6 +280,9 @@ public GoogleAnalyticsConfig setUseHttps(boolean useHttps) {
return this;
}

/**
* Future use and not used at the moment.
*/
public boolean isValidate() {
return validate;
}
Expand Down Expand Up @@ -332,7 +341,15 @@ public GoogleAnalyticsConfig setHttpsUrl(String httpsUrl) {
return this;
}

/**
* Returns the effective url to which we need to post the GA request to based on if hit debug is enabled and if
* https is enabled.
*/
public String getUrl() {
if (isHitDebug()) {
return useHttps ? httpsDebugUrl : httpDebugUrl;
}

return useHttps ? httpsUrl : httpUrl;
}

Expand Down Expand Up @@ -404,4 +421,95 @@ public GoogleAnalyticsConfig setBatchSize(int batchSize) {
return this;
}

public GoogleAnalyticsExceptionHandler getExceptionHandler() {
return exceptionHandler;
}

/**
* Set an exception handler which will implement the behavior in case of any exceptions. If not set, default
* behavior is to log a warning message.
*
* @since 2.1
*/
public GoogleAnalyticsConfig setExceptionHandler(GoogleAnalyticsExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
return this;
}

public boolean isAutoQueueTimeEnabled() {
return autoQueueTimeEnabled;
}

/**
* If enabled, library will calculate the queue time (qt) at the time request is being posted to GA based on when
* hit request was created and when it is posted to GA. Defaults to <code>true</code>.
*
* @since 2.1
*/
public GoogleAnalyticsConfig setAutoQueueTimeEnabled(boolean autoQueueTimeEnabled) {
this.autoQueueTimeEnabled = autoQueueTimeEnabled;
return this;
}

public boolean isAnonymizeUserIp() {
return anonymizeUserIp;
}

/**
* If true, and if <code>userIp</code> GA parameter is set, then that ip will be anonymized using same logic that is
* used at GA end. Defaults to <code>false</code>.
* <p>
* See for more info:
* <ul>
* <li>https://github.com/brsanthu/google-analytics-java/issues/57
* <li>https://support.google.com/analytics/answer/2763052?hl=en
* </ul>
*/
public GoogleAnalyticsConfig setAnonymizeUserIp(boolean anonymizeUserIp) {
this.anonymizeUserIp = anonymizeUserIp;
return this;
}

public String getHttpDebugUrl() {
return httpDebugUrl;
}

public GoogleAnalyticsConfig setHttpDebugUrl(String httpDebugUrl) {
this.httpDebugUrl = httpDebugUrl;
return this;
}

public String getHttpsDebugUrl() {
return httpsDebugUrl;
}

public GoogleAnalyticsConfig setHttpsDebugUrl(String httpsDebugUrl) {
this.httpsDebugUrl = httpsDebugUrl;
return this;
}

public boolean isHitDebug() {
return hitDebug;
}

/**
* If set to true, then library will use debug urls instead of normal GA urls (<code>debugHttpUrl</code> and
* <code>debugHttpsUrl</code>) which should return the hit validation response as part of http response. This would
* be captured as part of {@link GoogleAnalyticsResponse#getHttpResponse().getBody()}.
* <p>
* Library provides convenient validation response models at <code>com.brsanthu.googleanalytics.debug</code> package
* to deserialize http response (which will be in json format) into.
* <p>
* Note that to hit debug, disable batching as hit debug is not supported in batch mode.
* <p>
* Deserialization itself is not part of the library to avoid the dependency.
* <p>
* See <a href="https://developers.google.com/analytics/devguides/collection/protocol/v1/validating-hits">this</a>
* for more info.
*/
public GoogleAnalyticsConfig setHitDebug(boolean validateHits) {
hitDebug = validateHits;
return this;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.brsanthu.googleanalytics;

/**
* Models a handler which can be used to handle exceptions thrown while sending GA requests to google. This can be set
* as config parameter as below.
*
* <pre>
* GoogleAnalytics propagatingGa = GoogleAnalytics.builder()withConfig(
* new GoogleAnalyticsConfig().setExceptionHandler(new YourExceptionHandler())
* ).build();
* </pre>
*
* <p>
* Library comes with following implementations.
* <ul>
* <li>{@link PropagatingExceptionHandler} which propagates the exceptions.
* </ul>
*/
@FunctionalInterface
public interface GoogleAnalyticsExceptionHandler {
void handle(Throwable t);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.brsanthu.googleanalytics;

public interface GoogleAnalyticsStats {
long getTotalHits();

long getPageViewHits();

Expand All @@ -17,4 +18,4 @@ public interface GoogleAnalyticsStats {
long getSocialHits();

long getExceptionHits();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.brsanthu.googleanalytics;

/**
* Exception handler which propagates the exceptions instead of just logging.
*/
public class PropagatingExceptionHandler implements GoogleAnalyticsExceptionHandler {

@Override
public void handle(Throwable t) {
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}

throw new GoogleAnalyticsException(t);
}
}
Loading