GoogleAnalyticsClient.java
package uk.gov.dhsc.htbhf.claimant.reporting;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import uk.gov.dhsc.htbhf.claimant.exception.GoogleAnalyticsException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.stream.Collectors;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.MediaType.TEXT_PLAIN;
/**
* Service for interacting with google analytics measurement protocol.
* See https://developers.google.com/analytics/devguides/collection/protocol/v1/
*/
@Component
@Slf4j
public class GoogleAnalyticsClient {
private static final String REPORT_ENDPOINT = "/collect";
private final URI googleAnalyticsUri;
private final RestTemplate restTemplate;
public GoogleAnalyticsClient(@Value("${google-analytics.base-uri}") String baseUri,
RestTemplate restTemplate) throws URISyntaxException {
this.googleAnalyticsUri = new URI(baseUri + REPORT_ENDPOINT);
this.restTemplate = restTemplate;
}
public void reportEvent(Map<String, String> reportProperties) {
String payload = createQueryStringWithUrlEncodedValues(reportProperties);
HttpHeaders headers = new HttpHeaders();
// Google analytics requires plain text for the content type.
headers.setContentType(TEXT_PLAIN);
RequestEntity<String> requestEntity = new RequestEntity<>(payload, headers, POST, googleAnalyticsUri);
try {
ResponseEntity<Void> responseEntity = restTemplate.exchange(requestEntity, Void.class);
checkResponseIsOk(responseEntity.getStatusCode());
} catch (RestClientException e) {
log.error("Exception caught trying to post to {}", googleAnalyticsUri.toString());
throw new GoogleAnalyticsException(e, googleAnalyticsUri.toString());
}
}
private String createQueryStringWithUrlEncodedValues(Map<String, String> reportProperties) {
return reportProperties.entrySet().stream()
.map(entry -> entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), UTF_8))
.collect(Collectors.joining("&"));
}
private void checkResponseIsOk(HttpStatus status) {
if (status != OK) {
log.error("Expecting response status from google analytics to be OK, instead received {}", status);
throw new GoogleAnalyticsException(status);
}
}
}