/**
* =============================================================================
*
* ORCID (R) Open Source
* http://orcid.org
*
* Copyright (c) 2012-2014 ORCID, Inc.
* Licensed under an MIT-Style License (MIT)
* http://orcid.org/open-source-license
*
* This copyright and license information (including a link to the full license)
* shall be included in its entirety in all copies or substantial portion of
* the software.
*
* =============================================================================
*/
package org.orcid.core.analytics;
import javax.ws.rs.core.HttpHeaders;
import org.eclipse.jetty.util.log.Log;
import org.orcid.core.analytics.client.AnalyticsClient;
import org.orcid.core.manager.ClientDetailsEntityCacheManager;
import org.orcid.core.manager.ProfileEntityCacheManager;
import org.orcid.persistence.jpa.entities.ClientDetailsEntity;
import org.orcid.persistence.jpa.entities.ProfileEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
public class AnalyticsProcess implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(AnalyticsProcess.class);
private static final String REMOTE_IP_HEADER_NAME = "X-FORWARDED-FOR";
private static final String PUBLIC_API_USER = "Public API user";
private static final String PUBLIC_API = "Public API";
private static final String MEMBER_API = "Member API";
private ContainerRequest request;
private ContainerResponse response;
private AnalyticsClient analyticsClient;
private String clientDetailsId;
private ClientDetailsEntityCacheManager clientDetailsEntityCacheManager;
private ProfileEntityCacheManager profileEntityCacheManager;
public boolean publicApi;
@Override
public void run() {
AnalyticsData data = getAnalyticsData();
analyticsClient.sendAnalyticsData(data);
}
public void setRequest(ContainerRequest request) {
this.request = request;
}
public void setResponse(ContainerResponse response) {
this.response = response;
}
public void setAnalyticsClient(AnalyticsClient analyticsClient) {
this.analyticsClient = analyticsClient;
}
public void setClientDetailsEntityCacheManager(ClientDetailsEntityCacheManager clientDetailsEntityCacheManager) {
this.clientDetailsEntityCacheManager = clientDetailsEntityCacheManager;
}
public void setClientDetailsId(String clientDetailsId) {
this.clientDetailsId = clientDetailsId;
}
public void setPublicApi(boolean publicApi) {
this.publicApi = publicApi;
}
public void setProfileEntityCacheManager(ProfileEntityCacheManager profileEntityCacheManager) {
this.profileEntityCacheManager = profileEntityCacheManager;
}
private AnalyticsData getAnalyticsData() {
String ip = request.getHeaderValue(REMOTE_IP_HEADER_NAME);
ip = maskIp(ip);
APIEndpointParser parser = new APIEndpointParser(request);
AnalyticsData analyticsData = new AnalyticsData();
analyticsData.setUrl(getUrlWithHashedOrcidId(parser.getOrcidId(), request.getAbsolutePath().toString()));
analyticsData.setClientDetailsString(getClientDetailsString());
analyticsData.setClientId(clientDetailsId != null ? clientDetailsId : ip);
analyticsData.setContentType(request.getHeaderValue(HttpHeaders.CONTENT_TYPE));
analyticsData.setUserAgent(request.getHeaderValue(HttpHeaders.USER_AGENT));
analyticsData.setResponseCode(response.getStatus());
analyticsData.setIpAddress(ip);
analyticsData.setCategory(parser.getCategory());
analyticsData.setApiVersion(getApiString(parser.getApiVersion()));
analyticsData.setMethod(request.getMethod());
return analyticsData;
}
private String maskIp(String ip) {
return ip.substring(0, ip.lastIndexOf(".")) + ".0";
}
private String getUrlWithHashedOrcidId(String orcidId, String url) {
if (orcidId == null) {
return url;
}
try {
ProfileEntity profile = profileEntityCacheManager.retrieve(orcidId);
return url.replace(orcidId, profile.getHashedOrcid());
} catch (IllegalArgumentException e) {
LOG.warn("Invalid ORCID iD supplied in API call, original URL will be posted to GA");
return url;
}
}
private String getApiString(String apiVersion) {
if (publicApi) {
return PUBLIC_API + " " + apiVersion;
}
return MEMBER_API + " " + apiVersion;
}
private String getClientDetailsString() {
if (clientDetailsId != null) {
ClientDetailsEntity client = clientDetailsEntityCacheManager.retrieve(clientDetailsId);
StringBuilder clientDetails = new StringBuilder(client.getClientType().value());
clientDetails.append(" | ");
clientDetails.append(client.getClientName());
clientDetails.append(" - ");
clientDetails.append(clientDetailsId);
return clientDetails.toString();
} else {
return PUBLIC_API_USER;
}
}
}