*
* Optional.
- *
+ *
*
*
* This parameter specifies that this visitor has been exposed to a particular variation of an experiment. It should
@@ -1880,4 +1878,17 @@ public GoogleAnalyticsRequest setExecutor(GoogleAnalyticsExecutor delegateExe
this.delegateExecutor = delegateExecutor;
return this;
}
+
+ /**
+ * Indicates the datetime at which this event occurred. This is used to report the qt parameter, if one
+ * is not set. The occurredAt defaults to datetime when this request was instantiated.
+ */
+ public T occurredAt(ZonedDateTime value) {
+ this.occurredAt = value;
+ return (T) this;
+ }
+
+ public ZonedDateTime occurredAt() {
+ return occurredAt;
+ }
}
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java
index eba245f..b4152a1 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java
@@ -1,15 +1,12 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.request;
@@ -22,6 +19,7 @@
*/
public class GoogleAnalyticsResponse {
private int statusCode = 200;
+ private GoogleAnalyticsRequest> googleAnalyticsRequest;
private Map requestParams = null;
public Map getRequestParams() {
@@ -29,7 +27,7 @@ public Map getRequestParams() {
}
public void setRequestParams(Map postedParms) {
- this.requestParams = postedParms;
+ requestParams = postedParms;
}
public void setStatusCode(int statusCode) {
@@ -48,4 +46,13 @@ public String toString() {
builder.append("]");
return builder.toString();
}
+
+ public GoogleAnalyticsRequest> getGoogleAnalyticsRequest() {
+ return googleAnalyticsRequest;
+ }
+
+ public GoogleAnalyticsResponse setGoogleAnalyticsRequest(GoogleAnalyticsRequest> googleAnalyticsRequest) {
+ this.googleAnalyticsRequest = googleAnalyticsRequest;
+ return this;
+ }
}
diff --git a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
index 77d1ab1..408b39a 100644
--- a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
+++ b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
@@ -1,18 +1,25 @@
package com.brsanthu.googleanalytics;
import static com.brsanthu.googleanalytics.internal.Constants.TEST_TRACKING_ID;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.QUEUE_TIME;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.within;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import java.time.ZonedDateTime;
+
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatchers;
import com.brsanthu.googleanalytics.httpclient.HttpClient;
+import com.brsanthu.googleanalytics.httpclient.HttpResponse;
import com.brsanthu.googleanalytics.request.DefaultRequest;
+import com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter;
import com.brsanthu.googleanalytics.request.GoogleAnalyticsResponse;
public class GoogleAnalyticsTest {
@@ -150,4 +157,60 @@ void testExceptionHandler() throws Exception {
assertThatThrownBy(() -> propagatingGa.screenView().sendAsync().get()).hasMessageContaining("Testing Exception");
}
+
+ @Test
+ void testAutoQueueTime() throws Exception {
+
+ HttpClient client = mock(HttpClient.class);
+ when(client.post(ArgumentMatchers.any())).thenReturn(new HttpResponse().setStatusCode(200));
+
+ // By default queue time is added based on when hit was created and posted. In this test case, it should be
+ // close to 0
+ GoogleAnalytics gaAutoTimeEnabled = GoogleAnalytics.builder().withHttpClient(client).withConfig(new GoogleAnalyticsConfig()).build();
+ GoogleAnalyticsResponse respEnabled = gaAutoTimeEnabled.screenView().send();
+ assertThat(Integer.parseInt(respEnabled.getRequestParams().get(GoogleAnalyticsParameter.QUEUE_TIME.getParameterName()))).isCloseTo(0,
+ within(100));
+
+ // We can set occurred at to a past value and if so, it will be used to calcualte queue time.
+ GoogleAnalytics gaAutoTimeEnabledOccurredAt = GoogleAnalytics.builder().withHttpClient(client).withConfig(
+ new GoogleAnalyticsConfig()).build();
+ GoogleAnalyticsResponse respEnabledOccurredAt = gaAutoTimeEnabledOccurredAt.screenView().occurredAt(
+ ZonedDateTime.now().minusSeconds(5)).send();
+ assertThat(Integer.parseInt(respEnabledOccurredAt.getRequestParams().get(GoogleAnalyticsParameter.QUEUE_TIME.getParameterName()))).isCloseTo(
+ 5000, within(100));
+
+ // We can set both occurredAt and queue time, then time based on occurred at will be added to set queue time.
+ GoogleAnalyticsResponse respEnabledWithSetQueueTime = gaAutoTimeEnabled.screenView().occurredAt(
+ ZonedDateTime.now().minusSeconds(5)).queueTime(1000).send();
+ assertThat(Integer.parseInt(
+ respEnabledWithSetQueueTime.getRequestParams().get(GoogleAnalyticsParameter.QUEUE_TIME.getParameterName()))).isCloseTo(6000,
+ within(100));
+
+ // If we disable auto queue time, then queue time is not calculated
+ GoogleAnalytics gaAutoTimeDisabled = GoogleAnalytics.builder().withHttpClient(client).withConfig(
+ new GoogleAnalyticsConfig().setAutoQueueTimeEnabled(false)).build();
+ GoogleAnalyticsResponse respDisabled = gaAutoTimeDisabled.screenView().occurredAt(ZonedDateTime.now().minusSeconds(5)).send();
+ assertThat(respDisabled.getRequestParams().get(GoogleAnalyticsParameter.QUEUE_TIME.getParameterName())).isNull();
+ }
+
+ @Test
+ void testAutoQueueTimeBatch() throws Exception {
+ HttpClient client = mock(HttpClient.class);
+ when(client.post(ArgumentMatchers.any())).thenReturn(new HttpResponse().setStatusCode(200));
+
+ GoogleAnalytics gaAutoTimeEnabled = GoogleAnalytics.builder().withHttpClient(client).withConfig(
+ new GoogleAnalyticsConfig().setBatchingEnabled(true).setBatchSize(2)).build();
+
+ // First request will add to batch.
+ GoogleAnalyticsResponse resp1 = gaAutoTimeEnabled.screenView().send();
+
+ Thread.sleep(500);
+
+ GoogleAnalyticsResponse resp2 = gaAutoTimeEnabled.screenView().send();
+
+ assertThat(Integer.parseInt(resp1.getRequestParams().get(QUEUE_TIME.getParameterName()))).isCloseTo(500, within(100));
+
+ assertThat(Integer.parseInt(resp2.getRequestParams().get(QUEUE_TIME.getParameterName()))).isCloseTo(0, within(100));
+ }
+
}
From 930fb9a0c4d10deffee341a9a65c70a8e17d5b9b Mon Sep 17 00:00:00 2001
From: Santhosh Kumar
Date: Sun, 19 May 2019 11:02:49 -0700
Subject: [PATCH 04/11] Add ability to deep clone a hit #52
---
.../request/GoogleAnalyticsRequest.java | 25 +++++++++++++++++++
.../googleanalytics/GoogleAnalyticsTest.java | 12 +++++++++
2 files changed, 37 insertions(+)
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
index e87c0b7..62e6869 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
@@ -1891,4 +1891,29 @@ public T occurredAt(ZonedDateTime value) {
public ZonedDateTime occurredAt() {
return occurredAt;
}
+
+ /**
+ * Deep clones this hit and returns new request of same type. Any changes made to this request after this call, will
+ * not be reflected in the returned instance.
+ */
+ public T deepClone() {
+ try {
+ GoogleAnalyticsRequest clonedReq = this.getClass().newInstance();
+ clonedReq.occurredAt = ZonedDateTime.now();
+ clonedReq.parms = cloneMap(parms);
+ clonedReq.customDimensions = cloneMap(customDimensions);
+ clonedReq.customMetrics = cloneMap(customMetrics);
+ clonedReq.delegateExecutor = delegateExecutor;
+
+ return (T) clonedReq;
+ } catch (Exception e) {
+ throw new RuntimeException("Exception while deep cloning " + this, e);
+ }
+ }
+
+ private Map cloneMap(Map input) {
+ Map output = new HashMap<>();
+ output.putAll(input);
+ return output;
+ }
}
diff --git a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
index 408b39a..75236d0 100644
--- a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
+++ b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
@@ -21,6 +21,7 @@
import com.brsanthu.googleanalytics.request.DefaultRequest;
import com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter;
import com.brsanthu.googleanalytics.request.GoogleAnalyticsResponse;
+import com.brsanthu.googleanalytics.request.ScreenViewHit;
public class GoogleAnalyticsTest {
@@ -213,4 +214,15 @@ void testAutoQueueTimeBatch() throws Exception {
assertThat(Integer.parseInt(resp2.getRequestParams().get(QUEUE_TIME.getParameterName()))).isCloseTo(0, within(100));
}
+ @Test
+ void testDeepClone() throws Exception {
+ ScreenViewHit screenhit1 = ga.screenView().adwordsId("test1");
+ ScreenViewHit screenhit2 = screenhit1.deepClone();
+
+ screenhit1.adwordsId("test1updated");
+
+ assertThat(screenhit1).isNotSameAs(screenhit2);
+ assertThat(screenhit1.adwordsId()).isEqualTo("test1updated");
+ assertThat(screenhit2.adwordsId()).isEqualTo("test1");
+ }
}
From 3e4d516f568b74f42aaf041fb22a50acfe446f65 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar
Date: Sun, 19 May 2019 11:10:51 -0700
Subject: [PATCH 05/11] Deprecate api with typo custommMetrics #55
---
.../googleanalytics/internal/GoogleAnalyticsImpl.java | 6 +++---
.../request/GoogleAnalyticsRequest.java | 10 ++++++++++
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java b/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
index 2edc383..2d4fe43 100644
--- a/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
+++ b/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
@@ -291,11 +291,11 @@ protected void processCustomDimensionParameters(GoogleAnalyticsRequest> reques
*/
protected void processCustomMetricParameters(GoogleAnalyticsRequest> request, HttpRequest req) {
Map customMetricParms = new HashMap<>();
- for (String defaultCustomMetricKey : defaultRequest.custommMetrics().keySet()) {
- customMetricParms.put(defaultCustomMetricKey, defaultRequest.custommMetrics().get(defaultCustomMetricKey));
+ for (String defaultCustomMetricKey : defaultRequest.customMetrics().keySet()) {
+ customMetricParms.put(defaultCustomMetricKey, defaultRequest.customMetrics().get(defaultCustomMetricKey));
}
- Map requestCustomMetrics = request.custommMetrics();
+ Map requestCustomMetrics = request.customMetrics();
for (String requestCustomDimKey : requestCustomMetrics.keySet()) {
customMetricParms.put(requestCustomDimKey, requestCustomMetrics.get(requestCustomDimKey));
}
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
index 62e6869..88adb63 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
@@ -306,10 +306,20 @@ public Map customDimensions() {
return customDimensions;
}
+ /**
+ * This method name has typo hence has been deprecated.
+ *
+ * @deprecated please use {@link #customMetrics}
+ */
+ @Deprecated
public Map custommMetrics() {
return customMetrics;
}
+ public Map customMetrics() {
+ return customMetrics;
+ }
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
From 15ef1d0d0b13558e37f7c5c6fa6044b5a43a5b91 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar
Date: Sun, 19 May 2019 11:22:41 -0700
Subject: [PATCH 06/11] Add total hits to stats #56
---
.../googleanalytics/GoogleAnalyticsStats.java | 3 +-
.../internal/GoogleAnalyticsStatsImpl.java | 21 +++++++------
.../googleanalytics/GoogleAnalyticsTest.java | 30 +++++++++++++++++++
3 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsStats.java b/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsStats.java
index 0982629..b63db1f 100644
--- a/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsStats.java
+++ b/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsStats.java
@@ -1,6 +1,7 @@
package com.brsanthu.googleanalytics;
public interface GoogleAnalyticsStats {
+ long getTotalHits();
long getPageViewHits();
@@ -17,4 +18,4 @@ public interface GoogleAnalyticsStats {
long getSocialHits();
long getExceptionHits();
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsStatsImpl.java b/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsStatsImpl.java
index ccb9d69..2b90e3b 100644
--- a/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsStatsImpl.java
+++ b/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsStatsImpl.java
@@ -1,15 +1,12 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.internal;
@@ -105,6 +102,12 @@ public long getExceptionHits() {
return exceptionHits.get();
}
+ @Override
+ public long getTotalHits() {
+ return pageViewHits.get() + eventHits.get() + screenViewHits.get() + itemHits.get() + transactionHits.get() + timingHits.get()
+ + socialHits.get() + exceptionHits.get();
+ }
+
@Override
public String toString() {
return "GoogleAnalyticsStatsImpl [pageViewHits=" + pageViewHits + ", eventHits=" + eventHits + ", screenViewHits=" + screenViewHits
diff --git a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
index 75236d0..fc35b2f 100644
--- a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
+++ b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
@@ -11,6 +11,7 @@
import static org.mockito.Mockito.when;
import java.time.ZonedDateTime;
+import java.util.stream.IntStream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -225,4 +226,33 @@ void testDeepClone() throws Exception {
assertThat(screenhit1.adwordsId()).isEqualTo("test1updated");
assertThat(screenhit2.adwordsId()).isEqualTo("test1");
}
+
+ @Test
+ void testStats() throws Exception {
+ HttpClient client = mock(HttpClient.class);
+ when(client.post(ArgumentMatchers.any())).thenReturn(new HttpResponse().setStatusCode(200));
+
+ GoogleAnalytics ga = GoogleAnalytics.builder().withHttpClient(client).withConfig(
+ new GoogleAnalyticsConfig().setGatherStats(true).setBatchingEnabled(true).setBatchSize(2)).build();
+
+ IntStream.rangeClosed(1, 1).forEach(val -> ga.pageView().send());
+ IntStream.rangeClosed(1, 2).forEach(val -> ga.event().send());
+ IntStream.rangeClosed(1, 3).forEach(val -> ga.screenView().send());
+ IntStream.rangeClosed(1, 4).forEach(val -> ga.item().send());
+ IntStream.rangeClosed(1, 5).forEach(val -> ga.transaction().send());
+ IntStream.rangeClosed(1, 6).forEach(val -> ga.timing().send());
+ IntStream.rangeClosed(1, 7).forEach(val -> ga.social().send());
+ IntStream.rangeClosed(1, 8).forEach(val -> ga.exception().send());
+
+ assertThat(ga.getStats().getPageViewHits()).isEqualTo(1);
+ assertThat(ga.getStats().getEventHits()).isEqualTo(2);
+ assertThat(ga.getStats().getScreenViewHits()).isEqualTo(3);
+ assertThat(ga.getStats().getItemHits()).isEqualTo(4);
+ assertThat(ga.getStats().getTransactionHits()).isEqualTo(5);
+ assertThat(ga.getStats().getTimingHits()).isEqualTo(6);
+ assertThat(ga.getStats().getSocialHits()).isEqualTo(7);
+ assertThat(ga.getStats().getExceptionHits()).isEqualTo(8);
+ assertThat(ga.getStats().getTotalHits()).isEqualTo(36);
+
+ }
}
From 0e5ade86f4398d6dc7feefbd65db0da9b02b7c65 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar
Date: Sun, 19 May 2019 18:00:50 -0700
Subject: [PATCH 07/11] Add support for generic hit as AnyHit #54
---
.../googleanalytics/request/AnyHit.java | 1194 +++++++++++++++++
.../request/DefaultRequest.java | 18 +-
.../googleanalytics/request/EventHit.java | 16 +-
.../googleanalytics/request/ExceptionHit.java | 16 +-
.../request/GoogleAnalyticsRequest.java | 26 +-
.../googleanalytics/request/ItemHit.java | 16 +-
.../googleanalytics/request/PageViewHit.java | 17 +-
.../request/ScreenViewHit.java | 16 +-
.../googleanalytics/request/SocialHit.java | 16 +-
.../googleanalytics/request/TimingHit.java | 16 +-
.../request/TransactionHit.java | 16 +-
.../googleanalytics/GoogleAnalyticsTest.java | 13 +
.../googleanalytics/HitTypesTest.java | 3 +
13 files changed, 1290 insertions(+), 93 deletions(-)
create mode 100644 src/main/java/com/brsanthu/googleanalytics/request/AnyHit.java
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/AnyHit.java b/src/main/java/com/brsanthu/googleanalytics/request/AnyHit.java
new file mode 100644
index 0000000..5d33b04
--- /dev/null
+++ b/src/main/java/com/brsanthu/googleanalytics/request/AnyHit.java
@@ -0,0 +1,1194 @@
+package com.brsanthu.googleanalytics.request;
+
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.CURRENCY_CODE;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.DNS_TIME;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EVENT_ACTION;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EVENT_CATEGORY;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EVENT_LABEL;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EVENT_VALUE;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EXCEPTION_DESCRIPTION;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EXCEPTION_FATAL;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.ITEM_CATEGORY;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.ITEM_CODE;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.ITEM_NAME;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.ITEM_PRICE;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.ITEM_QUANTITY;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.PAGE_DOWNLOAD_TIME;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.PAGE_LOAD_TIME;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.REDIRECT_RESPONSE_TIME;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.SCREEN_NAME;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.SERVER_RESPONSE_TIME;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.SOCIAL_ACTION;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.SOCIAL_ACTION_TARGET;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.SOCIAL_NETWORK;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.TCP_CONNECT_TIME;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.TRANSACTION_AFFILIATION;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.TRANSACTION_ID;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.TRANSACTION_REVENUE;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.TRANSACTION_SHIPPING;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.TRANSACTION_TAX;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.USER_TIMING_CATEGORY;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.USER_TIMING_LABEL;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.USER_TIMING_TIME;
+import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.USER_TIMING_VARIABLE_NAME;
+
+/**
+ * Represents a generic GA hit which provides access all supported GA parameters as typed accessors. You can use this
+ * hit type if you want to set GA hit type as dynamic parameter instead of dealing with constructing hit type specific
+ * instance.
+ */
+public class AnyHit extends GoogleAnalyticsRequest {
+
+ /**
+ * Event Tracking
+ *
+ * Optional.
+ *
+ *
+ * Specifies the event category. Must not be empty.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * ec |
+ * text |
+ * None |
+ * 150 Bytes |
+ * event |
+ *
+ *
+ *
+ *
Example value: Category
+ * Example usage: ec=Category
+ */
+ public AnyHit eventCategory(String value) {
+ setString(EVENT_CATEGORY, value);
+ return this;
+ }
+
+ public String eventCategory() {
+ return getString(EVENT_CATEGORY);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the event action. Must not be empty.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * ea |
+ * text |
+ * None |
+ * 500 Bytes |
+ * event |
+ *
+ *
+ *
+ *
Example value: Action
+ * Example usage: ea=Action
+ */
+ public AnyHit eventAction(String value) {
+ setString(EVENT_ACTION, value);
+ return this;
+ }
+
+ public String eventAction() {
+ return getString(EVENT_ACTION);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the event label.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * el |
+ * text |
+ * None |
+ * 500 Bytes |
+ * event |
+ *
+ *
+ *
+ *
Example value: Label
+ * Example usage: el=Label
+ */
+ public AnyHit eventLabel(String value) {
+ setString(EVENT_LABEL, value);
+ return this;
+ }
+
+ public String eventLabel() {
+ return getString(EVENT_LABEL);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the event value. Values must be non-negative.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * ev |
+ * integer |
+ * None |
+ * None |
+ * event |
+ *
+ *
+ *
+ *
Example value: 55
+ * Example usage: ev=55
+ */
+ public AnyHit eventValue(Integer value) {
+ setInteger(EVENT_VALUE, value);
+ return this;
+ }
+
+ public Integer eventValue() {
+ return getInteger(EVENT_VALUE);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the description of an exception.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * exd |
+ * text |
+ * None |
+ * 150 Bytes |
+ * exception |
+ *
+ *
+ *
+ *
Example value: DatabaseError
+ * Example usage: exd=DatabaseError
+ */
+ public AnyHit exceptionDescription(String value) {
+ setString(EXCEPTION_DESCRIPTION, value);
+ return this;
+ }
+
+ public String exceptionDescription() {
+ return getString(EXCEPTION_DESCRIPTION);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies whether the exception was fatal.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * exf |
+ * boolean |
+ * 1 |
+ * None |
+ * exception |
+ *
+ *
+ *
+ *
Example value: 0
+ * Example usage: exf=0
+ */
+ public AnyHit exceptionFatal(Boolean value) {
+ setBoolean(EXCEPTION_FATAL, value);
+ return this;
+ }
+
+ public Boolean exceptionFatal() {
+ return getBoolean(EXCEPTION_FATAL);
+ }
+
+ /**
+ *
+ *
+ * Required for transaction hit type.
+ * Required for item hit type.
+ *
+ *
+ * A unique identifier for the transaction. This value should be the same for both the Transaction hit and Items
+ * hits associated to the particular transaction.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * ti |
+ * text |
+ * None |
+ * 500 Bytes |
+ * transaction, item |
+ *
+ *
+ *
+ *
Example value: OD564
+ * Example usage: ti=OD564
+ */
+ public AnyHit txId(String value) {
+ setString(TRANSACTION_ID, value);
+ return this;
+ }
+
+ public String txId() {
+ return getString(TRANSACTION_ID);
+ }
+
+ /**
+ *
+ *
+ * Required for item hit type.
+ *
+ *
+ * Specifies the item name.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * in |
+ * text |
+ * None |
+ * 500 Bytes |
+ * item |
+ *
+ *
+ *
+ *
Example value: Shoe
+ * Example usage: in=Shoe
+ */
+ public AnyHit itemName(String value) {
+ setString(ITEM_NAME, value);
+ return this;
+ }
+
+ public String itemName() {
+ return getString(ITEM_NAME);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the price for a single item / unit.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * ip |
+ * currency |
+ * 0 |
+ * None |
+ * item |
+ *
+ *
+ *
+ *
Example value: 3.50
+ * Example usage: ip=3.50
+ */
+ public AnyHit itemPrice(Double value) {
+ setDouble(ITEM_PRICE, value);
+ return this;
+ }
+
+ public Double itemPrice() {
+ return getDouble(ITEM_PRICE);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the number of items purchased.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * iq |
+ * integer |
+ * 0 |
+ * None |
+ * item |
+ *
+ *
+ *
+ *
Example value: 4
+ * Example usage: iq=4
+ */
+ public AnyHit itemQuantity(Integer value) {
+ setInteger(ITEM_QUANTITY, value);
+ return this;
+ }
+
+ public Integer itemQuantity() {
+ return getInteger(ITEM_QUANTITY);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the SKU or item code.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * ic |
+ * text |
+ * None |
+ * 500 Bytes |
+ * item |
+ *
+ *
+ *
+ *
Example value: SKU47
+ * Example usage: ic=SKU47
+ */
+ public AnyHit itemCode(String value) {
+ setString(ITEM_CODE, value);
+ return this;
+ }
+
+ public String itemCode() {
+ return getString(ITEM_CODE);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the category that the item belongs to.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * iv |
+ * text |
+ * None |
+ * 500 Bytes |
+ * item |
+ *
+ *
+ *
+ *
Example value: Blue
+ * Example usage: iv=Blue
+ */
+ public AnyHit itemCategory(String value) {
+ setString(ITEM_CATEGORY, value);
+ return this;
+ }
+
+ public String itemCategory() {
+ return getString(ITEM_CATEGORY);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * When present indicates the local currency for all transaction currency values. Value should be a valid ISO 4217
+ * currency code.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * cu |
+ * text |
+ * None |
+ * 10 Bytes |
+ * transaction, item |
+ *
+ *
+ *
+ *
Example value: EUR
+ * Example usage: cu=EUR
+ */
+ public AnyHit currencyCode(String value) {
+ setString(CURRENCY_CODE, value);
+ return this;
+ }
+
+ public String currencyCode() {
+ return getString(CURRENCY_CODE);
+ }
+
+ public AnyHit screenName(String value) {
+ setString(SCREEN_NAME, value);
+ return this;
+ }
+
+ public String screenName() {
+ return getString(SCREEN_NAME);
+ }
+
+ /**
+ *
+ *
+ * Required for social hit type.
+ *
+ *
+ * Specifies the social network, for example Facebook or Google Plus.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * sn |
+ * text |
+ * None |
+ * 50 Bytes |
+ * social |
+ *
+ *
+ *
+ *
Example value: facebook
+ * Example usage: sn=facebook
+ */
+ public AnyHit socialNetwork(String value) {
+ setString(SOCIAL_NETWORK, value);
+ return this;
+ }
+
+ public String socialNetwork() {
+ return getString(SOCIAL_NETWORK);
+ }
+
+ /**
+ *
+ *
+ * Required for social hit type.
+ *
+ *
+ * Specifies the social interaction action. For example on Google Plus when a user clicks the +1 button, the social
+ * action is 'plus'.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * sa |
+ * text |
+ * None |
+ * 50 Bytes |
+ * social |
+ *
+ *
+ *
+ *
Example value: like
+ * Example usage: sa=like
+ */
+ public AnyHit socialAction(String value) {
+ setString(SOCIAL_ACTION, value);
+ return this;
+ }
+
+ public String socialAction() {
+ return getString(SOCIAL_ACTION);
+ }
+
+ /**
+ *
+ *
+ * Required for social hit type.
+ *
+ *
+ * Specifies the target of a social interaction. This value is typically a URL but can be any text.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * st |
+ * text |
+ * None |
+ * 2048 Bytes |
+ * social |
+ *
+ *
+ *
+ *
Example value: http://foo.com
+ * Example usage: st=http%3A%2F%2Ffoo.com
+ */
+ public AnyHit socialActionTarget(String value) {
+ setString(SOCIAL_ACTION_TARGET, value);
+ return this;
+ }
+
+ public String socialActionTarget() {
+ return getString(SOCIAL_ACTION_TARGET);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the user timing category.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * utc |
+ * text |
+ * None |
+ * 150 Bytes |
+ * timing |
+ *
+ *
+ *
+ *
Example value: category
+ * Example usage: utc=category
+ */
+ public AnyHit userTimingCategory(String value) {
+ setString(USER_TIMING_CATEGORY, value);
+ return this;
+ }
+
+ public String userTimingCategory() {
+ return getString(USER_TIMING_CATEGORY);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the user timing variable.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * utv |
+ * text |
+ * None |
+ * 500 Bytes |
+ * timing |
+ *
+ *
+ *
+ *
Example value: lookup
+ * Example usage: utv=lookup
+ */
+ public AnyHit userTimingVariableName(String value) {
+ setString(USER_TIMING_VARIABLE_NAME, value);
+ return this;
+ }
+
+ public String userTimingVariableName() {
+ return getString(USER_TIMING_VARIABLE_NAME);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the user timing value. The value is in milliseconds.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * utt |
+ * integer |
+ * None |
+ * None |
+ * timing |
+ *
+ *
+ *
+ *
Example value: 123
+ * Example usage: utt=123
+ */
+ public AnyHit userTimingTime(Integer value) {
+ setInteger(USER_TIMING_TIME, value);
+ return this;
+ }
+
+ public Integer userTimingTime() {
+ return getInteger(USER_TIMING_TIME);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the user timing label.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * utl |
+ * text |
+ * None |
+ * 500 Bytes |
+ * timing |
+ *
+ *
+ *
+ *
Example value: label
+ * Example usage: utl=label
+ */
+ public AnyHit userTimingLabel(String value) {
+ setString(USER_TIMING_LABEL, value);
+ return this;
+ }
+
+ public String userTimingLabel() {
+ return getString(USER_TIMING_LABEL);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the time it took for a page to load. The value is in milliseconds.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * plt |
+ * integer |
+ * None |
+ * None |
+ * timing |
+ *
+ *
+ *
+ *
Example value: 3554
+ * Example usage: plt=3554
+ */
+ public AnyHit pageLoadTime(Integer value) {
+ setInteger(PAGE_LOAD_TIME, value);
+ return this;
+ }
+
+ public Integer pageLoadTime() {
+ return getInteger(PAGE_LOAD_TIME);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the time it took to do a DNS lookup.The value is in milliseconds.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * dns |
+ * integer |
+ * None |
+ * None |
+ * timing |
+ *
+ *
+ *
+ *
Example value: 43
+ * Example usage: dns=43
+ */
+ public AnyHit dnsTime(Integer value) {
+ setInteger(DNS_TIME, value);
+ return this;
+ }
+
+ public Integer dnsTime() {
+ return getInteger(DNS_TIME);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the time it took for the page to be downloaded. The value is in milliseconds.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * pdt |
+ * integer |
+ * None |
+ * None |
+ * timing |
+ *
+ *
+ *
+ *
Example value: 500
+ * Example usage: pdt=500
+ */
+ public AnyHit pageDownloadTime(Integer value) {
+ setInteger(PAGE_DOWNLOAD_TIME, value);
+ return this;
+ }
+
+ public Integer pageDownloadTime() {
+ return getInteger(PAGE_DOWNLOAD_TIME);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the time it took for any redirects to happen. The value is in milliseconds.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * rrt |
+ * integer |
+ * None |
+ * None |
+ * timing |
+ *
+ *
+ *
+ *
Example value: 500
+ * Example usage: rrt=500
+ */
+ public AnyHit redirectResponseTime(Integer value) {
+ setInteger(REDIRECT_RESPONSE_TIME, value);
+ return this;
+ }
+
+ public Integer redirectResponseTime() {
+ return getInteger(REDIRECT_RESPONSE_TIME);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the time it took for a TCP connection to be made. The value is in milliseconds.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * tcp |
+ * integer |
+ * None |
+ * None |
+ * timing |
+ *
+ *
+ *
+ *
Example value: 500
+ * Example usage: tcp=500
+ */
+ public AnyHit tcpConnectTime(Integer value) {
+ setInteger(TCP_CONNECT_TIME, value);
+ return this;
+ }
+
+ public Integer tcpConnectTime() {
+ return getInteger(TCP_CONNECT_TIME);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the time it took for the server to respond after the connect time. The value is in milliseconds.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * srt |
+ * integer |
+ * None |
+ * None |
+ * timing |
+ *
+ *
+ *
+ *
Example value: 500
+ * Example usage: srt=500
+ */
+ public AnyHit serverResponseTime(Integer value) {
+ setInteger(SERVER_RESPONSE_TIME, value);
+ return this;
+ }
+
+ public Integer serverResponseTime() {
+ return getInteger(SERVER_RESPONSE_TIME);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the affiliation or store name.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * ta |
+ * text |
+ * None |
+ * 500 Bytes |
+ * transaction |
+ *
+ *
+ *
+ *
Example value: Member
+ * Example usage: ta=Member
+ */
+ public AnyHit txAffiliation(String value) {
+ setString(TRANSACTION_AFFILIATION, value);
+ return this;
+ }
+
+ public String txAffiliation() {
+ return getString(TRANSACTION_AFFILIATION);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the total revenue associated with the transaction. This value should include any shipping or tax costs.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * tr |
+ * currency |
+ * 0 |
+ * None |
+ * transaction |
+ *
+ *
+ *
+ *
Example value: 15.47
+ * Example usage: tr=15.47
+ */
+ public AnyHit txRevenue(Double value) {
+ setDouble(TRANSACTION_REVENUE, value);
+ return this;
+ }
+
+ public Double txRevenue() {
+ return getDouble(TRANSACTION_REVENUE);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the total shipping cost of the transaction.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * ts |
+ * currency |
+ * 0 |
+ * None |
+ * transaction |
+ *
+ *
+ *
+ *
Example value: 3.50
+ * Example usage: ts=3.50
+ */
+ public AnyHit txShipping(Double value) {
+ setDouble(TRANSACTION_SHIPPING, value);
+ return this;
+ }
+
+ public Double txShipping() {
+ return getDouble(TRANSACTION_SHIPPING);
+ }
+
+ /**
+ *
+ *
+ * Optional.
+ *
+ *
+ * Specifies the total tax of the transaction.
+ *
+ *
+ *
+ *
+ * | Parameter |
+ * Value Type |
+ * Default Value |
+ * Max Length |
+ * Supported Hit Types |
+ *
+ *
+ * tt |
+ * currency |
+ * 0 |
+ * None |
+ * transaction |
+ *
+ *
+ *
+ *
Example value: 11.20
+ * Example usage: tt=11.20
+ */
+ public AnyHit txTax(Double value) {
+ setDouble(TRANSACTION_TAX, value);
+ return this;
+ }
+
+ public Double txTax() {
+ return getDouble(TRANSACTION_TAX);
+ }
+}
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/DefaultRequest.java b/src/main/java/com/brsanthu/googleanalytics/request/DefaultRequest.java
index 6c9a069..5cfa601 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/DefaultRequest.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/DefaultRequest.java
@@ -1,15 +1,12 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.request;
@@ -47,7 +44,6 @@
import java.util.UUID;
-import com.brsanthu.googleanalytics.internal.Constants;
import com.brsanthu.googleanalytics.internal.GaUtils;
import com.brsanthu.googleanalytics.internal.GoogleAnalyticsImpl;
@@ -71,7 +67,7 @@ public DefaultRequest(String hitType) {
}
public DefaultRequest(String hitType, String trackingId, String appName, String appVersion) {
- hitType(GaUtils.isBlank(hitType) ? Constants.HIT_PAGEVIEW : hitType);
+ hitType(GaUtils.isBlank(hitType) ? HIT_PAGEVIEW : hitType);
trackingId(trackingId);
applicationName(appName);
applicationVersion(appVersion);
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/EventHit.java b/src/main/java/com/brsanthu/googleanalytics/request/EventHit.java
index 9a16d9e..491a8e9 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/EventHit.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/EventHit.java
@@ -1,19 +1,15 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.request;
-import static com.brsanthu.googleanalytics.internal.Constants.HIT_EVENT;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EVENT_ACTION;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EVENT_CATEGORY;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EVENT_LABEL;
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/ExceptionHit.java b/src/main/java/com/brsanthu/googleanalytics/request/ExceptionHit.java
index c2bd101..6af9b71 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/ExceptionHit.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/ExceptionHit.java
@@ -1,19 +1,15 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.request;
-import static com.brsanthu.googleanalytics.internal.Constants.HIT_EXCEPTION;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EXCEPTION_DESCRIPTION;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.EXCEPTION_FATAL;
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
index 88adb63..c8a1ed9 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
@@ -72,11 +72,20 @@
@SuppressWarnings("unchecked")
public class GoogleAnalyticsRequest {
+ public static final String HIT_SCREENVIEW = "screenview";
+ public static final String HIT_PAGEVIEW = "pageview";
+ public static final String HIT_EVENT = "event";
+ public static final String HIT_ITEM = "item";
+ public static final String HIT_TXN = "transaction";
+ public static final String HIT_SOCIAL = "social";
+ public static final String HIT_TIMING = "timing";
+ public static final String HIT_EXCEPTION = "exception";
+
protected Map parms = new HashMap<>();
protected Map customDimensions = new HashMap<>();
protected Map customMetrics = new HashMap<>();
protected GoogleAnalyticsExecutor delegateExecutor = null;
- private ZonedDateTime occurredAt = ZonedDateTime.now();
+ protected ZonedDateTime occurredAt = ZonedDateTime.now();
public GoogleAnalyticsRequest() {
this(null, null, null, null);
@@ -1926,4 +1935,19 @@ private Map cloneMap(Map input) {
output.putAll(input);
return output;
}
+
+ /**
+ * Creates a anyhit wrapper for current request with state shared between this instance and returned {@link AnyHit}.
+ * If you want a copy, then call {@link #deepClone()} first and then this method.
+ */
+ public AnyHit asAnyHit() {
+ AnyHit anyHit = new AnyHit();
+ anyHit.customDimensions = customDimensions;
+ anyHit.customMetrics = customMetrics;
+ anyHit.delegateExecutor = delegateExecutor;
+ anyHit.parms = parms;
+ anyHit.occurredAt = occurredAt;
+
+ return anyHit;
+ }
}
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/ItemHit.java b/src/main/java/com/brsanthu/googleanalytics/request/ItemHit.java
index c894d85..29887f3 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/ItemHit.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/ItemHit.java
@@ -1,19 +1,15 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.request;
-import static com.brsanthu.googleanalytics.internal.Constants.HIT_ITEM;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.CURRENCY_CODE;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.ITEM_CATEGORY;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.ITEM_CODE;
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/PageViewHit.java b/src/main/java/com/brsanthu/googleanalytics/request/PageViewHit.java
index 566b2ea..1a76e7f 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/PageViewHit.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/PageViewHit.java
@@ -1,20 +1,15 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.request;
-import static com.brsanthu.googleanalytics.internal.Constants.HIT_PAGEVIEW;
-
/**
* GA request to track a typical web page view
*
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/ScreenViewHit.java b/src/main/java/com/brsanthu/googleanalytics/request/ScreenViewHit.java
index a27e0a1..6f38fe3 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/ScreenViewHit.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/ScreenViewHit.java
@@ -1,19 +1,15 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.request;
-import static com.brsanthu.googleanalytics.internal.Constants.HIT_SCREENVIEW;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.SCREEN_NAME;
/**
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/SocialHit.java b/src/main/java/com/brsanthu/googleanalytics/request/SocialHit.java
index 9d7afb8..a77dce8 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/SocialHit.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/SocialHit.java
@@ -1,19 +1,15 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.request;
-import static com.brsanthu.googleanalytics.internal.Constants.HIT_SOCIAL;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.SOCIAL_ACTION;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.SOCIAL_ACTION_TARGET;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.SOCIAL_NETWORK;
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/TimingHit.java b/src/main/java/com/brsanthu/googleanalytics/request/TimingHit.java
index ed2b5d7..79e62fd 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/TimingHit.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/TimingHit.java
@@ -1,19 +1,15 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.request;
-import static com.brsanthu.googleanalytics.internal.Constants.HIT_TIMING;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.DNS_TIME;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.PAGE_DOWNLOAD_TIME;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.PAGE_LOAD_TIME;
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/TransactionHit.java b/src/main/java/com/brsanthu/googleanalytics/request/TransactionHit.java
index f257fab..6d1ebe1 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/TransactionHit.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/TransactionHit.java
@@ -1,19 +1,15 @@
/*
- * 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
+ * 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
+ * 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.
+ * 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.
*/
package com.brsanthu.googleanalytics.request;
-import static com.brsanthu.googleanalytics.internal.Constants.HIT_TXN;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.CURRENCY_CODE;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.TRANSACTION_AFFILIATION;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.TRANSACTION_ID;
diff --git a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
index fc35b2f..9f8846f 100644
--- a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
+++ b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
@@ -19,6 +19,7 @@
import com.brsanthu.googleanalytics.httpclient.HttpClient;
import com.brsanthu.googleanalytics.httpclient.HttpResponse;
+import com.brsanthu.googleanalytics.request.AnyHit;
import com.brsanthu.googleanalytics.request.DefaultRequest;
import com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter;
import com.brsanthu.googleanalytics.request.GoogleAnalyticsResponse;
@@ -253,6 +254,18 @@ void testStats() throws Exception {
assertThat(ga.getStats().getSocialHits()).isEqualTo(7);
assertThat(ga.getStats().getExceptionHits()).isEqualTo(8);
assertThat(ga.getStats().getTotalHits()).isEqualTo(36);
+ }
+
+ @Test
+ void testAnyHit() throws Exception {
+ ScreenViewHit sv = ga.screenView().adwordsId("adsid123");
+
+ AnyHit anyhit1 = sv.asAnyHit();
+ anyhit1.adwordsId("adsid456");
+ assertThat(sv.adwordsId()).isEqualTo(anyhit1.adwordsId());
+ AnyHit anyhit2 = sv.deepClone().asAnyHit();
+ anyhit2.adwordsId("adsid789");
+ assertThat(sv.adwordsId()).isNotEqualTo(anyhit2.adwordsId());
}
}
diff --git a/src/test/java/com/brsanthu/googleanalytics/HitTypesTest.java b/src/test/java/com/brsanthu/googleanalytics/HitTypesTest.java
index 326b0c0..0de5b77 100644
--- a/src/test/java/com/brsanthu/googleanalytics/HitTypesTest.java
+++ b/src/test/java/com/brsanthu/googleanalytics/HitTypesTest.java
@@ -1,9 +1,11 @@
package com.brsanthu.googleanalytics;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import org.junit.jupiter.api.Test;
+import com.brsanthu.googleanalytics.request.AnyHit;
import com.brsanthu.googleanalytics.request.EventHit;
import com.brsanthu.googleanalytics.request.ExceptionHit;
import com.brsanthu.googleanalytics.request.ItemHit;
@@ -25,5 +27,6 @@ public void testHitTypes() throws Exception {
assertEquals("social", new SocialHit().hitType());
assertEquals("timing", new TimingHit().hitType());
assertEquals("transaction", new TransactionHit().hitType());
+ assertThat(new AnyHit().hitType()).isEqualTo("pageview");
}
}
From e73a98998ea8f636c2e5924659d43fac71f61e3a Mon Sep 17 00:00:00 2001
From: Santhosh Kumar
Date: Sun, 19 May 2019 18:20:05 -0700
Subject: [PATCH 08/11] Add support for anonymizing user ip address with config
#57
---
.../GoogleAnalyticsConfig.java | 22 ++++++++++++++
.../internal/GoogleAnalyticsImpl.java | 29 +++++++++++++++++--
.../googleanalytics/GoogleAnalyticsTest.java | 28 +++++++++++-------
3 files changed, 66 insertions(+), 13 deletions(-)
diff --git a/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfig.java b/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfig.java
index 30d34c8..1f171e2 100644
--- a/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfig.java
+++ b/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfig.java
@@ -54,6 +54,7 @@ public class GoogleAnalyticsConfig {
private RequestParameterDiscoverer requestParameterDiscoverer = new DefaultRequestParameterDiscoverer();
private GoogleAnalyticsExceptionHandler exceptionHandler;
private boolean autoQueueTimeEnabled = true;
+ private boolean anonymizeUserIp = false;
public RequestParameterDiscoverer getRequestParameterDiscoverer() {
return requestParameterDiscoverer;
@@ -413,6 +414,8 @@ public GoogleAnalyticsExceptionHandler getExceptionHandler() {
/**
* 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;
@@ -434,4 +437,23 @@ public GoogleAnalyticsConfig setAutoQueueTimeEnabled(boolean autoQueueTimeEnable
return this;
}
+ public boolean isAnonymizeUserIp() {
+ return anonymizeUserIp;
+ }
+
+ /**
+ * If true, and if userIp GA parameter is set, then that ip will be anonymized using same logic that is
+ * used at GA end. Defaults to false.
+ *
+ * See for more info:
+ *
+ * - https://github.com/brsanthu/google-analytics-java/issues/57
+ *
- https://support.google.com/analytics/answer/2763052?hl=en
+ *
+ */
+ public GoogleAnalyticsConfig setAnonymizeUserIp(boolean anonymizeUserIp) {
+ this.anonymizeUserIp = anonymizeUserIp;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java b/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
index 2d4fe43..d5497a3 100644
--- a/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
+++ b/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
@@ -13,6 +13,8 @@
import static com.brsanthu.googleanalytics.internal.GaUtils.isEmpty;
import static com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter.QUEUE_TIME;
+import java.net.Inet6Address;
+import java.net.InetAddress;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
@@ -241,9 +243,9 @@ private HttpRequest createHttpRequest(GoogleAnalyticsRequest> gaReq) {
return httpReq;
}
- protected void processParameters(GoogleAnalyticsRequest> request, HttpRequest req) {
+ protected void processParameters(GoogleAnalyticsRequest> gaReq, HttpRequest httpReq) {
- Map requestParms = request.getParameters();
+ Map requestParms = gaReq.getParameters();
Map defaultParms = defaultRequest.getParameters();
for (GoogleAnalyticsParameter parm : defaultParms.keySet()) {
@@ -256,8 +258,29 @@ protected void processParameters(GoogleAnalyticsRequest> request, HttpRequest
}
}
+ anonymizeUserIp(gaReq, httpReq);
+
for (GoogleAnalyticsParameter key : requestParms.keySet()) {
- req.addBodyParam(key.getParameterName(), requestParms.get(key));
+ httpReq.addBodyParam(key.getParameterName(), requestParms.get(key));
+ }
+ }
+
+ private void anonymizeUserIp(GoogleAnalyticsRequest> gaReq, HttpRequest httpReq) {
+ if (config.isAnonymizeUserIp() && gaReq.userIp() != null) {
+ try {
+ InetAddress ip = InetAddress.getByName(gaReq.userIp());
+ byte[] address = ip.getAddress();
+ int anonymizedBytes = ip instanceof Inet6Address ? 10 : 1;
+
+ for (int i = 0; i < anonymizedBytes; ++i) {
+ address[address.length - i - 1] = 0;
+ }
+
+ String anonymizedIp = InetAddress.getByAddress(address).getHostAddress();
+ gaReq.userIp(anonymizedIp);
+ } catch (Exception e) {
+ logger.warn("Error anonymizing user ip", e);
+ }
}
}
diff --git a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
index 9f8846f..c77df79 100644
--- a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
+++ b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
@@ -28,10 +28,13 @@
public class GoogleAnalyticsTest {
private static GoogleAnalytics ga = null;
+ private static HttpClient client;
@BeforeAll
public static void setup() {
ga = GoogleAnalytics.builder().withTrackingId(TEST_TRACKING_ID).withAppName("Junit Test").withAppVersion("1.0.0").build();
+ client = mock(HttpClient.class);
+ when(client.post(ArgumentMatchers.any())).thenReturn(new HttpResponse().setStatusCode(200));
}
@Test
@@ -163,10 +166,6 @@ void testExceptionHandler() throws Exception {
@Test
void testAutoQueueTime() throws Exception {
-
- HttpClient client = mock(HttpClient.class);
- when(client.post(ArgumentMatchers.any())).thenReturn(new HttpResponse().setStatusCode(200));
-
// By default queue time is added based on when hit was created and posted. In this test case, it should be
// close to 0
GoogleAnalytics gaAutoTimeEnabled = GoogleAnalytics.builder().withHttpClient(client).withConfig(new GoogleAnalyticsConfig()).build();
@@ -198,9 +197,6 @@ void testAutoQueueTime() throws Exception {
@Test
void testAutoQueueTimeBatch() throws Exception {
- HttpClient client = mock(HttpClient.class);
- when(client.post(ArgumentMatchers.any())).thenReturn(new HttpResponse().setStatusCode(200));
-
GoogleAnalytics gaAutoTimeEnabled = GoogleAnalytics.builder().withHttpClient(client).withConfig(
new GoogleAnalyticsConfig().setBatchingEnabled(true).setBatchSize(2)).build();
@@ -230,9 +226,6 @@ void testDeepClone() throws Exception {
@Test
void testStats() throws Exception {
- HttpClient client = mock(HttpClient.class);
- when(client.post(ArgumentMatchers.any())).thenReturn(new HttpResponse().setStatusCode(200));
-
GoogleAnalytics ga = GoogleAnalytics.builder().withHttpClient(client).withConfig(
new GoogleAnalyticsConfig().setGatherStats(true).setBatchingEnabled(true).setBatchSize(2)).build();
@@ -268,4 +261,19 @@ void testAnyHit() throws Exception {
anyhit2.adwordsId("adsid789");
assertThat(sv.adwordsId()).isNotEqualTo(anyhit2.adwordsId());
}
+
+ @Test
+ void testAnonymizeUserIp() throws Exception {
+ String userIp = "176.134.201.004";
+
+ GoogleAnalytics ga = GoogleAnalytics.builder().withHttpClient(client).withConfig(new GoogleAnalyticsConfig()).build();
+ GoogleAnalyticsResponse resp = ga.screenView().userIp(userIp).send();
+ assertThat(resp.getRequestParams().get(GoogleAnalyticsParameter.USER_IP.getParameterName())).isEqualTo(userIp);
+
+ GoogleAnalytics ga2 = GoogleAnalytics.builder().withHttpClient(client).withConfig(
+ new GoogleAnalyticsConfig().setAnonymizeUserIp(true)).build();
+ GoogleAnalyticsResponse resp2 = ga2.screenView().userIp(userIp).send();
+ assertThat(resp2.getRequestParams().get(GoogleAnalyticsParameter.USER_IP.getParameterName())).isEqualTo("176.134.201.0");
+
+ }
}
From 1b9273f9328cf4296009ce662360eb38d7590a0a Mon Sep 17 00:00:00 2001
From: Santhosh Kumar
Date: Sun, 19 May 2019 19:12:11 -0700
Subject: [PATCH 09/11] Add support for validating hits #48
---
pom.xml | 8 ++-
.../GoogleAnalyticsConfig.java | 56 +++++++++++++++++++
.../hitdebug/HitParsingResult.java | 38 +++++++++++++
.../hitdebug/HitValidationResponse.java | 31 ++++++++++
.../hitdebug/ParserMessage.java | 46 +++++++++++++++
.../httpclient/ApacheHttpClientImpl.java | 1 +
.../httpclient/HttpResponse.java | 23 ++++++++
.../internal/GoogleAnalyticsImpl.java | 3 +
.../request/GoogleAnalyticsResponse.java | 23 ++++++++
.../GoogleAnalyticsConfigTest.java | 21 +++++++
.../GoogleAnalyticsDebugTest.java | 53 ++++++++++++++++++
11 files changed, 302 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/com/brsanthu/googleanalytics/hitdebug/HitParsingResult.java
create mode 100644 src/main/java/com/brsanthu/googleanalytics/hitdebug/HitValidationResponse.java
create mode 100644 src/main/java/com/brsanthu/googleanalytics/hitdebug/ParserMessage.java
create mode 100644 src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsDebugTest.java
diff --git a/pom.xml b/pom.xml
index fe4448c..3558026 100644
--- a/pom.xml
+++ b/pom.xml
@@ -160,6 +160,13 @@
+
+ com.googlecode.json-simple
+ json-simple
+ 1.1.1
+ test
+
+
org.junit.jupiter
junit-jupiter-api
@@ -190,7 +197,6 @@
${mockito.version}
test
-
Google Analytics Java API
https://github.com/brsanthu/google-analytics-java
diff --git a/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfig.java b/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfig.java
index 1f171e2..93d4a32 100644
--- a/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfig.java
+++ b/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfig.java
@@ -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;
@@ -55,6 +57,7 @@ public class GoogleAnalyticsConfig {
private GoogleAnalyticsExceptionHandler exceptionHandler;
private boolean autoQueueTimeEnabled = true;
private boolean anonymizeUserIp = false;
+ private boolean hitDebug = false;
public RequestParameterDiscoverer getRequestParameterDiscoverer() {
return requestParameterDiscoverer;
@@ -277,6 +280,9 @@ public GoogleAnalyticsConfig setUseHttps(boolean useHttps) {
return this;
}
+ /**
+ * Future use and not used at the moment.
+ */
public boolean isValidate() {
return validate;
}
@@ -335,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;
}
@@ -456,4 +470,46 @@ public GoogleAnalyticsConfig setAnonymizeUserIp(boolean 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 (debugHttpUrl and
+ * debugHttpsUrl) which should return the hit validation response as part of http response. This would
+ * be captured as part of {@link GoogleAnalyticsResponse#getHttpResponse().getBody()}.
+ *
+ * Library provides convenient validation response models at com.brsanthu.googleanalytics.debug package
+ * to deserialize http response (which will be in json format) into.
+ *
+ * Note that to hit debug, disable batching as hit debug is not supported in batch mode.
+ *
+ * Deserialization itself is not part of the library to avoid the dependency.
+ *
+ * See this
+ * for more info.
+ */
+ public GoogleAnalyticsConfig setHitDebug(boolean validateHits) {
+ hitDebug = validateHits;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/brsanthu/googleanalytics/hitdebug/HitParsingResult.java b/src/main/java/com/brsanthu/googleanalytics/hitdebug/HitParsingResult.java
new file mode 100644
index 0000000..87671c7
--- /dev/null
+++ b/src/main/java/com/brsanthu/googleanalytics/hitdebug/HitParsingResult.java
@@ -0,0 +1,38 @@
+package com.brsanthu.googleanalytics.hitdebug;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class HitParsingResult {
+ private boolean valid;
+ private String hit;
+ private List parserMessage = new ArrayList<>();
+
+ public boolean isValid() {
+ return valid;
+ }
+
+ public HitParsingResult setValid(boolean valid) {
+ this.valid = valid;
+ return this;
+ }
+
+ public String getHit() {
+ return hit;
+ }
+
+ public HitParsingResult setHit(String hit) {
+ this.hit = hit;
+ return this;
+ }
+
+ public List getParserMessage() {
+ return parserMessage;
+ }
+
+ public HitParsingResult setParserMessage(List parserMessage) {
+ this.parserMessage = parserMessage;
+ return this;
+ }
+
+}
diff --git a/src/main/java/com/brsanthu/googleanalytics/hitdebug/HitValidationResponse.java b/src/main/java/com/brsanthu/googleanalytics/hitdebug/HitValidationResponse.java
new file mode 100644
index 0000000..5241cc5
--- /dev/null
+++ b/src/main/java/com/brsanthu/googleanalytics/hitdebug/HitValidationResponse.java
@@ -0,0 +1,31 @@
+package com.brsanthu.googleanalytics.hitdebug;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class HitValidationResponse {
+ private List hitParsingResult = new ArrayList<>();
+ private List parserMessage = new ArrayList<>();
+
+ public HitValidationResponse() {
+ // default
+ }
+
+ public List getHitParsingResult() {
+ return hitParsingResult;
+ }
+
+ public HitValidationResponse setHitParsingResult(List hitParsingResult) {
+ this.hitParsingResult = hitParsingResult;
+ return this;
+ }
+
+ public List getParserMessage() {
+ return parserMessage;
+ }
+
+ public HitValidationResponse setParserMessage(List parserMessage) {
+ this.parserMessage = parserMessage;
+ return this;
+ }
+}
diff --git a/src/main/java/com/brsanthu/googleanalytics/hitdebug/ParserMessage.java b/src/main/java/com/brsanthu/googleanalytics/hitdebug/ParserMessage.java
new file mode 100644
index 0000000..61b22cc
--- /dev/null
+++ b/src/main/java/com/brsanthu/googleanalytics/hitdebug/ParserMessage.java
@@ -0,0 +1,46 @@
+package com.brsanthu.googleanalytics.hitdebug;
+
+public class ParserMessage {
+ private String messageType;
+ private String description;
+ private String parameter;
+
+ public String getMessageType() {
+ return messageType;
+ }
+
+ public ParserMessage setMessageType(String messageType) {
+ this.messageType = messageType;
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public ParserMessage setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public String getParameter() {
+ return parameter;
+ }
+
+ public ParserMessage setParameter(String parameter) {
+ this.parameter = parameter;
+ return this;
+ }
+
+ public boolean isInfo() {
+ return "info".equalsIgnoreCase(messageType);
+ }
+
+ public boolean isWarn() {
+ return "warn".equalsIgnoreCase(messageType);
+ }
+
+ public boolean isError() {
+ return "error".equalsIgnoreCase(messageType);
+ }
+}
diff --git a/src/main/java/com/brsanthu/googleanalytics/httpclient/ApacheHttpClientImpl.java b/src/main/java/com/brsanthu/googleanalytics/httpclient/ApacheHttpClientImpl.java
index 75ed8cf..5e30837 100644
--- a/src/main/java/com/brsanthu/googleanalytics/httpclient/ApacheHttpClientImpl.java
+++ b/src/main/java/com/brsanthu/googleanalytics/httpclient/ApacheHttpClientImpl.java
@@ -101,6 +101,7 @@ public HttpResponse post(HttpRequest req) {
httpResp = execute(req.getUrl(), new UrlEncodedFormEntity(createNameValuePairs(req), StandardCharsets.UTF_8));
resp.setStatusCode(httpResp.getStatusLine().getStatusCode());
+ resp.setBody(EntityUtils.toString(httpResp.getEntity(), "UTF-8"));
} catch (Exception e) {
if (e instanceof UnknownHostException) {
diff --git a/src/main/java/com/brsanthu/googleanalytics/httpclient/HttpResponse.java b/src/main/java/com/brsanthu/googleanalytics/httpclient/HttpResponse.java
index ca337c3..96e0ed2 100644
--- a/src/main/java/com/brsanthu/googleanalytics/httpclient/HttpResponse.java
+++ b/src/main/java/com/brsanthu/googleanalytics/httpclient/HttpResponse.java
@@ -1,8 +1,13 @@
package com.brsanthu.googleanalytics.httpclient;
+import java.util.HashMap;
+import java.util.Map;
+
public class HttpResponse {
private int statusCode;
+ private String body;
+ private Map headers = new HashMap<>();
public int getStatusCode() {
return statusCode;
@@ -13,4 +18,22 @@ public HttpResponse setStatusCode(int statusCode) {
return this;
}
+ public String getBody() {
+ return body;
+ }
+
+ public HttpResponse setBody(String body) {
+ this.body = body;
+ return this;
+ }
+
+ public Map getHeaders() {
+ return headers;
+ }
+
+ public HttpResponse setHeaders(Map headers) {
+ this.headers = headers;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java b/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
index d5497a3..76743ea 100644
--- a/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
+++ b/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
@@ -219,8 +219,11 @@ protected GoogleAnalyticsResponse postSingle(GoogleAnalyticsRequest> gaReq) {
HttpResponse httpResp = httpClient.post(httpReq);
GoogleAnalyticsResponse response = new GoogleAnalyticsResponse();
+ response.setGoogleAnalyticsRequest(gaReq);
response.setStatusCode(httpResp.getStatusCode());
response.setRequestParams(httpReq.getBodyParams());
+ response.setHttpRequest(httpReq);
+ response.setHttpResponse(httpResp);
if (config.isGatherStats()) {
gatherStats(gaReq);
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java
index b4152a1..90af3f8 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java
@@ -12,6 +12,9 @@
import java.util.Map;
+import com.brsanthu.googleanalytics.httpclient.HttpRequest;
+import com.brsanthu.googleanalytics.httpclient.HttpResponse;
+
/**
* Response for GA tracking request.
*
@@ -21,6 +24,8 @@ public class GoogleAnalyticsResponse {
private int statusCode = 200;
private GoogleAnalyticsRequest> googleAnalyticsRequest;
private Map requestParams = null;
+ private HttpRequest httpRequest;
+ private HttpResponse httpResponse;
public Map getRequestParams() {
return requestParams;
@@ -55,4 +60,22 @@ public GoogleAnalyticsResponse setGoogleAnalyticsRequest(GoogleAnalyticsRequest<
this.googleAnalyticsRequest = googleAnalyticsRequest;
return this;
}
+
+ public HttpResponse getHttpResponse() {
+ return httpResponse;
+ }
+
+ public GoogleAnalyticsResponse setHttpResponse(HttpResponse httpResponse) {
+ this.httpResponse = httpResponse;
+ return this;
+ }
+
+ public HttpRequest getHttpRequest() {
+ return httpRequest;
+ }
+
+ public GoogleAnalyticsResponse setHttpRequest(HttpRequest httpRequest) {
+ this.httpRequest = httpRequest;
+ return this;
+ }
}
diff --git a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfigTest.java b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfigTest.java
index a287b82..c28019a 100644
--- a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfigTest.java
+++ b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsConfigTest.java
@@ -1,5 +1,6 @@
package com.brsanthu.googleanalytics;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import org.junit.jupiter.api.Test;
@@ -14,8 +15,28 @@ public void testDefaultConfig() throws Exception {
assertEquals(5, config.getMaxThreads());
assertEquals("http://www.google-analytics.com/collect", config.getHttpUrl());
assertEquals("https://www.google-analytics.com/collect", config.getHttpsUrl());
+ assertEquals("http://www.google-analytics.com/debug/collect", config.getHttpDebugUrl());
+ assertEquals("https://www.google-analytics.com/debug/collect", config.getHttpsDebugUrl());
assertEquals(80, config.getProxyPort());
assertEquals(true, config.isDiscoverRequestParameters());
assertEquals(false, config.isGatherStats());
}
+
+ @Test
+ void testGetUrl() throws Exception {
+
+ GoogleAnalyticsConfig config = new GoogleAnalyticsConfig();
+
+ assertThat(config.getUrl()).isEqualTo("https://www.google-analytics.com/collect");
+ config.setHitDebug(true);
+ assertThat(config.getUrl()).isEqualTo("https://www.google-analytics.com/debug/collect");
+
+ config.setHitDebug(false);
+ config.setUseHttps(false);
+
+ assertThat(config.getUrl()).isEqualTo("http://www.google-analytics.com/collect");
+ config.setHitDebug(true);
+ assertThat(config.getUrl()).isEqualTo("http://www.google-analytics.com/debug/collect");
+ }
+
}
diff --git a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsDebugTest.java b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsDebugTest.java
new file mode 100644
index 0000000..c49023b
--- /dev/null
+++ b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsDebugTest.java
@@ -0,0 +1,53 @@
+package com.brsanthu.googleanalytics;
+
+import static com.brsanthu.googleanalytics.internal.Constants.TEST_TRACKING_ID;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import com.brsanthu.googleanalytics.request.GoogleAnalyticsResponse;
+
+public class GoogleAnalyticsDebugTest {
+
+ private static GoogleAnalytics ga = null;
+
+ @BeforeAll
+ public static void setup() {
+ ga = GoogleAnalytics.builder().withTrackingId(TEST_TRACKING_ID).withAppName("Junit Test").withAppVersion("1.0.0").withConfig(
+ new GoogleAnalyticsConfig().setHitDebug(true)).build();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testPageViewDebug() throws Exception {
+ GoogleAnalyticsResponse response = ga.pageView("http://www.google.com", "Search").send();
+
+ // Sample response from GA
+ // @formatter:off
+ /*
+ {
+ "hitParsingResult": [ {
+ "valid": true,
+ "parserMessage": [ ],
+ "hit": "/debug/collect?dt=Search\u0026de=UTF-8\u0026qt=1\u0026t=pageview\u0026av=1.0.0\u0026v=1\u0026ul=en-US\u0026dl=http://www.google.com\u0026an=Junit Test\u0026tid=UA-612100-12\u0026cid=7beb1a85-2a9e-440f-8e2d-5e91f8a7e708"
+ } ],
+ "parserMessage": [ {
+ "messageType": "INFO",
+ "description": "Found 1 hit in the request."
+ } ]
+ }
+ */
+ // @formatter:on
+ String originalResponse = response.getHttpResponse().getBody();
+ JSONParser parser = new JSONParser();
+ JSONObject json = (JSONObject) parser.parse(originalResponse);
+ assertEquals(200, response.getStatusCode());
+ assertEquals(true, ((Map) ((JSONArray) json.get("hitParsingResult")).get(0)).get("valid"));
+ }
+}
From fcf5f8f236c21b653f4c6a85b4ba3f90f0e3e309 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar
Date: Sun, 19 May 2019 19:28:01 -0700
Subject: [PATCH 10/11] Add builder support for GoogleAnalyticsExecutor #53
---
.../GoogleAnalyticsBuilder.java | 8 ++++++-
.../internal/GoogleAnalyticsImpl.java | 17 ++++++++++++---
.../request/GoogleAnalyticsResponse.java | 6 ++++--
.../googleanalytics/GoogleAnalyticsTest.java | 21 +++++++++++++++++++
4 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsBuilder.java b/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsBuilder.java
index 4f5e43d..e0c6f56 100644
--- a/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsBuilder.java
+++ b/src/main/java/com/brsanthu/googleanalytics/GoogleAnalyticsBuilder.java
@@ -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());
@@ -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() {
diff --git a/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java b/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
index 76743ea..87728f8 100644
--- a/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
+++ b/src/main/java/com/brsanthu/googleanalytics/internal/GoogleAnalyticsImpl.java
@@ -68,14 +68,17 @@ public class GoogleAnalyticsImpl implements GoogleAnalytics, GoogleAnalyticsExec
protected final DefaultRequest defaultRequest;
protected final HttpClient httpClient;
protected final ExecutorService executor;
+ protected final GoogleAnalyticsExecutor googleAnalyticsExecutor;
protected GoogleAnalyticsStatsImpl stats = new GoogleAnalyticsStatsImpl();
protected List currentBatch = new ArrayList<>();
- public GoogleAnalyticsImpl(GoogleAnalyticsConfig config, DefaultRequest defaultRequest, HttpClient httpClient, ExecutorService executor) {
+ public GoogleAnalyticsImpl(GoogleAnalyticsConfig config, DefaultRequest defaultRequest, HttpClient httpClient, ExecutorService executor,
+ GoogleAnalyticsExecutor googleAnalyticsExecutor) {
this.config = config;
this.defaultRequest = defaultRequest;
this.httpClient = httpClient;
this.executor = executor;
+ this.googleAnalyticsExecutor = googleAnalyticsExecutor;
}
@Override
@@ -88,16 +91,24 @@ public DefaultRequest getDefaultRequest() {
}
@Override
- public Future postAsync(GoogleAnalyticsRequest> request) {
+ public Future postAsync(GoogleAnalyticsRequest> gaReq) {
+ if (googleAnalyticsExecutor != null) {
+ return googleAnalyticsExecutor.postAsync(gaReq);
+ }
+
if (!config.isEnabled()) {
return null;
}
- return executor.submit(() -> post(request));
+ return executor.submit(() -> post(gaReq));
}
@Override
public GoogleAnalyticsResponse post(GoogleAnalyticsRequest> gaReq) {
+ if (googleAnalyticsExecutor != null) {
+ return googleAnalyticsExecutor.post(gaReq);
+ }
+
GoogleAnalyticsResponse response = new GoogleAnalyticsResponse();
response.setGoogleAnalyticsRequest(gaReq);
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java
index 90af3f8..291be2b 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsResponse.java
@@ -31,12 +31,14 @@ public Map getRequestParams() {
return requestParams;
}
- public void setRequestParams(Map postedParms) {
+ public GoogleAnalyticsResponse setRequestParams(Map postedParms) {
requestParams = postedParms;
+ return this;
}
- public void setStatusCode(int statusCode) {
+ public GoogleAnalyticsResponse setStatusCode(int statusCode) {
this.statusCode = statusCode;
+ return this;
}
public int getStatusCode() {
diff --git a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
index c77df79..8316308 100644
--- a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
+++ b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
@@ -11,6 +11,7 @@
import static org.mockito.Mockito.when;
import java.time.ZonedDateTime;
+import java.util.concurrent.Future;
import java.util.stream.IntStream;
import org.junit.jupiter.api.BeforeAll;
@@ -22,6 +23,7 @@
import com.brsanthu.googleanalytics.request.AnyHit;
import com.brsanthu.googleanalytics.request.DefaultRequest;
import com.brsanthu.googleanalytics.request.GoogleAnalyticsParameter;
+import com.brsanthu.googleanalytics.request.GoogleAnalyticsRequest;
import com.brsanthu.googleanalytics.request.GoogleAnalyticsResponse;
import com.brsanthu.googleanalytics.request.ScreenViewHit;
@@ -274,6 +276,25 @@ void testAnonymizeUserIp() throws Exception {
new GoogleAnalyticsConfig().setAnonymizeUserIp(true)).build();
GoogleAnalyticsResponse resp2 = ga2.screenView().userIp(userIp).send();
assertThat(resp2.getRequestParams().get(GoogleAnalyticsParameter.USER_IP.getParameterName())).isEqualTo("176.134.201.0");
+ }
+
+ @Test
+ void testCustomExecutor() throws Exception {
+ GoogleAnalyticsExecutor exector = new GoogleAnalyticsExecutor() {
+ @Override
+ public Future postAsync(GoogleAnalyticsRequest> request) {
+ return null;
+ }
+
+ @Override
+ public GoogleAnalyticsResponse post(GoogleAnalyticsRequest> request) {
+ return new GoogleAnalyticsResponse().setStatusCode(400);
+ }
+ };
+
+ GoogleAnalytics ga = GoogleAnalytics.builder().withGoogleAnalyticsExecutor(exector).build();
+ GoogleAnalyticsResponse resp = ga.screenView().send();
+ assertThat(resp.getStatusCode()).isEqualTo(400);
}
}
From 6ac22c58de42c6baf421b14e46c2939c3bfe7716 Mon Sep 17 00:00:00 2001
From: Santhosh Kumar
Date: Mon, 20 May 2019 08:59:57 -0700
Subject: [PATCH 11/11] Change deepClone to clone #52
---
.../googleanalytics/request/GoogleAnalyticsRequest.java | 5 +++--
.../com/brsanthu/googleanalytics/GoogleAnalyticsTest.java | 4 ++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
index c8a1ed9..686de5d 100644
--- a/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
+++ b/src/main/java/com/brsanthu/googleanalytics/request/GoogleAnalyticsRequest.java
@@ -70,7 +70,7 @@
* @author Santhosh Kumar
*/
@SuppressWarnings("unchecked")
-public class GoogleAnalyticsRequest {
+public class GoogleAnalyticsRequest implements Cloneable {
public static final String HIT_SCREENVIEW = "screenview";
public static final String HIT_PAGEVIEW = "pageview";
@@ -1915,7 +1915,8 @@ public ZonedDateTime occurredAt() {
* Deep clones this hit and returns new request of same type. Any changes made to this request after this call, will
* not be reflected in the returned instance.
*/
- public T deepClone() {
+ @Override
+ public T clone() {
try {
GoogleAnalyticsRequest clonedReq = this.getClass().newInstance();
clonedReq.occurredAt = ZonedDateTime.now();
diff --git a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
index 8316308..11fd188 100644
--- a/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
+++ b/src/test/java/com/brsanthu/googleanalytics/GoogleAnalyticsTest.java
@@ -217,7 +217,7 @@ void testAutoQueueTimeBatch() throws Exception {
@Test
void testDeepClone() throws Exception {
ScreenViewHit screenhit1 = ga.screenView().adwordsId("test1");
- ScreenViewHit screenhit2 = screenhit1.deepClone();
+ ScreenViewHit screenhit2 = screenhit1.clone();
screenhit1.adwordsId("test1updated");
@@ -259,7 +259,7 @@ void testAnyHit() throws Exception {
anyhit1.adwordsId("adsid456");
assertThat(sv.adwordsId()).isEqualTo(anyhit1.adwordsId());
- AnyHit anyhit2 = sv.deepClone().asAnyHit();
+ AnyHit anyhit2 = sv.clone().asAnyHit();
anyhit2.adwordsId("adsid789");
assertThat(sv.adwordsId()).isNotEqualTo(anyhit2.adwordsId());
}