Added statistics recording to API

(required changes in DSpace API!)

Also some changes to make REST API work better with XML output.
Added Checksum and sequenceId to Bitstream.
This commit is contained in:
Anja Le Blanc
2013-10-23 14:17:01 +01:00
parent d595481467
commit 6d8417c9af
17 changed files with 702 additions and 22 deletions

View File

@@ -381,6 +381,124 @@ public class ElasticSearchLogger {
} }
} }
public void post(DSpaceObject dspaceObject, String ip, String userAgent, String xforwarderfor, EPerson currentUser) {
//log.info("DS-ES post for type:"+dspaceObject.getType() + " -- " + dspaceObject.getName());
client = ElasticSearchLogger.getInstance().getClient();
boolean isSpiderBot = SpiderDetector.isSpider(ip);
try {
if (isSpiderBot &&
!ConfigurationManager.getBooleanProperty("usage-statistics", "logBots", true)) {
return;
}
// Save our basic info that we already have
if (isUseProxies() && xforwarderfor != null) {
/* This header is a comma delimited list */
for (String xfip : xforwarderfor.split(",")) {
/* proxy itself will sometime populate this header with the same value in
remote address. ordering in spec is vague, we'll just take the last
not equal to the proxy
*/
if (!xforwarderfor.contains(ip)) {
ip = xfip.trim();
}
}
}
XContentBuilder docBuilder = null;
docBuilder = XContentFactory.jsonBuilder().startObject();
docBuilder.field("ip", ip);
docBuilder.field("id", dspaceObject.getID());
// The numerical constant that represents the DSpaceObject TYPE. i.e. 0=bitstream, 2=item, ...
docBuilder.field("typeIndex", dspaceObject.getType());
// The text that represent the DSpaceObject TYPE. i.e. BITSTREAM, ITEM, COLLECTION, COMMUNITY
docBuilder.field("type", Constants.typeText[dspaceObject.getType()]);
// Save the current time
docBuilder.field("time", DateFormatUtils.format(new Date(), DATE_FORMAT_8601));
if (currentUser != null) {
docBuilder.field("epersonid", currentUser.getID());
}
try {
String dns = DnsLookup.reverseDns(ip);
docBuilder.field("dns", dns.toLowerCase());
} catch (Exception e) {
log.error("Failed DNS Lookup for IP:" + ip);
log.debug(e.getMessage(), e);
}
// Save the location information if valid, save the event without
// location information if not valid
Location location = locationService.getLocation(ip);
if (location != null
&& !("--".equals(location.countryCode)
&& location.latitude == -180 && location.longitude == -180)) {
try {
docBuilder.field("continent", LocationUtils
.getContinentCode(location.countryCode));
} catch (Exception e) {
System.out
.println("COUNTRY ERROR: " + location.countryCode);
}
docBuilder.field("countryCode", location.countryCode);
docBuilder.field("city", location.city);
docBuilder.field("latitude", location.latitude);
docBuilder.field("longitude", location.longitude);
docBuilder.field("isBot", isSpiderBot);
if (userAgent != null) {
docBuilder.field("userAgent", userAgent);
}
}
if (dspaceObject instanceof Bitstream) {
Bitstream bit = (Bitstream) dspaceObject;
Bundle[] bundles = bit.getBundles();
docBuilder.field("bundleName").startArray();
for (Bundle bundle : bundles) {
docBuilder.value(bundle.getName());
}
docBuilder.endArray();
}
storeParents(docBuilder, getParents(dspaceObject));
docBuilder.endObject();
if (docBuilder != null) {
IndexRequestBuilder irb = client.prepareIndex(indexName, indexType)
.setSource(docBuilder);
//log.info("Executing document insert into index");
if(client == null) {
log.error("Hey, client is null");
}
irb.execute().actionGet();
}
} catch (RuntimeException re) {
log.error("RunTimer in ESL:\n" + ExceptionUtils.getStackTrace(re));
throw re;
} catch (Exception e) {
log.error(e.getMessage());
} finally {
client.close();
}
}
public static String getClusterName() { public static String getClusterName() {
return clusterName; return clusterName;
} }

View File

@@ -243,6 +243,39 @@ public class SolrLogger
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }
} }
public static void postView(DSpaceObject dspaceObject,
String ip, String userAgent, String xforwarderfor, EPerson currentUser) {
if (solr == null || locationService == null) {
return;
}
try {
SolrInputDocument doc1 = getCommonSolrDoc(dspaceObject, ip, userAgent, xforwarderfor,
currentUser);
if (doc1 == null)
return;
if (dspaceObject instanceof Bitstream) {
Bitstream bit = (Bitstream) dspaceObject;
Bundle[] bundles = bit.getBundles();
for (Bundle bundle : bundles) {
doc1.addField("bundleName", bundle.getName());
}
}
doc1.addField("statistics_type", StatisticsType.VIEW.text());
solr.add(doc1);
// commits are executed automatically using the solr autocommit
// solr.commit(false, false);
} catch (RuntimeException re) {
throw re;
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
/** /**
* Returns a solr input document containing common information about the statistics * Returns a solr input document containing common information about the statistics
@@ -346,6 +379,92 @@ public class SolrLogger
return doc1; return doc1;
} }
private static SolrInputDocument getCommonSolrDoc(DSpaceObject dspaceObject, String ip, String userAgent, String xforwarderfor, EPerson currentUser) throws SQLException {
boolean isSpiderBot = SpiderDetector.isSpider(ip);
if(isSpiderBot &&
!ConfigurationManager.getBooleanProperty("usage-statistics", "logBots", true))
{
return null;
}
SolrInputDocument doc1 = new SolrInputDocument();
// Save our basic info that we already have
if (isUseProxies() && xforwarderfor != null) {
/* This header is a comma delimited list */
for (String xfip : xforwarderfor.split(",")) {
/* proxy itself will sometime populate this header with the same value in
remote address. ordering in spec is vague, we'll just take the last
not equal to the proxy
*/
if (!xforwarderfor.contains(ip)) {
ip = xfip.trim();
}
}
doc1.addField("ip", ip);
try
{
String dns = DnsLookup.reverseDns(ip);
doc1.addField("dns", dns.toLowerCase());
}
catch (Exception e)
{
log.error("Failed DNS Lookup for IP:" + ip);
log.debug(e.getMessage(),e);
}
// Save the location information if valid, save the event without
// location information if not valid
if(locationService != null)
{
Location location = locationService.getLocation(ip);
if (location != null
&& !("--".equals(location.countryCode)
&& location.latitude == -180 && location.longitude == -180))
{
try
{
doc1.addField("continent", LocationUtils
.getContinentCode(location.countryCode));
}
catch (Exception e)
{
System.out
.println("COUNTRY ERROR: " + location.countryCode);
}
doc1.addField("countryCode", location.countryCode);
doc1.addField("city", location.city);
doc1.addField("latitude", location.latitude);
doc1.addField("longitude", location.longitude);
doc1.addField("isBot",isSpiderBot);
if(userAgent != null)
{
doc1.addField("userAgent", userAgent);
}
}
}
}
if(dspaceObject != null){
doc1.addField("id", dspaceObject.getID());
doc1.addField("type", dspaceObject.getType());
storeParents(doc1, dspaceObject);
}
// Save the current time
doc1.addField("time", DateFormatUtils.format(new Date(), DATE_FORMAT_8601));
if (currentUser != null)
{
doc1.addField("epersonid", currentUser.getID());
}
return doc1;
}
public static void postSearch(DSpaceObject resultObject, HttpServletRequest request, EPerson currentUser, public static void postSearch(DSpaceObject resultObject, HttpServletRequest request, EPerson currentUser,
List<String> queries, int rpp, String sortBy, String order, int page, DSpaceObject scope) { List<String> queries, int rpp, String sortBy, String order, int page, DSpaceObject scope) {
try try

View File

@@ -31,13 +31,18 @@ public class SolrLoggerUsageEventListener extends AbstractUsageEventListener {
if(event instanceof UsageEvent) if(event instanceof UsageEvent)
{ {
log.debug("Usage event received " + ((UsageEvent)event).getName());
try{ try{
UsageEvent ue = (UsageEvent)event; UsageEvent ue = (UsageEvent)event;
EPerson currentUser = ue.getContext() == null ? null : ue.getContext().getCurrentUser(); EPerson currentUser = ue.getContext() == null ? null : ue.getContext().getCurrentUser();
if(UsageEvent.Action.VIEW == ue.getAction()){ if(UsageEvent.Action.VIEW == ue.getAction()){
SolrLogger.postView(ue.getObject(), ue.getRequest(), currentUser); if(ue.getRequest()!=null){
SolrLogger.postView(ue.getObject(), ue.getRequest(), currentUser);
} else {
SolrLogger.postView(ue.getObject(), ue.getIp(), ue.getUserAgent(), ue.getXforwarderfor(), currentUser);
}
}else }else
if(UsageEvent.Action.SEARCH == ue.getAction()){ if(UsageEvent.Action.SEARCH == ue.getAction()){
UsageSearchEvent usageSearchEvent = (UsageSearchEvent) ue; UsageSearchEvent usageSearchEvent = (UsageSearchEvent) ue;

View File

@@ -52,6 +52,12 @@ public class UsageEvent extends Event {
private transient HttpServletRequest request; private transient HttpServletRequest request;
private transient String ip;
private transient String userAgent;
private transient String xforwarderfor;
private transient Context context; private transient Context context;
private transient DSpaceObject object; private transient DSpaceObject object;
@@ -86,6 +92,39 @@ public class UsageEvent extends Event {
eventName.append(objText).append(":"); eventName.append(objText).append(":");
} }
eventName.append(action.text()); eventName.append(action.text());
return eventName.toString();
}
private static String checkParams(Action action, Context context, DSpaceObject object)
{
StringBuilder eventName = new StringBuilder();
if(action == null)
{
throw new IllegalStateException("action cannot be null");
}
// if(action != Action.WORKFLOW)
// {
// throw new IllegalStateException("request cannot be null");
// }
if(context == null)
{
throw new IllegalStateException("context cannot be null");
}
if(action != Action.WORKFLOW && action != Action.SEARCH && object == null)
{
throw new IllegalStateException("object cannot be null");
}else
if(object != null){
String objText = Constants.typeText[object.getType()].toLowerCase();
eventName.append(objText).append(":");
}
eventName.append(action.text());
return eventName.toString(); return eventName.toString();
} }
@@ -124,10 +163,72 @@ public class UsageEvent extends Event {
this.object = object; this.object = object;
} }
public UsageEvent(Action action, String ip, String userAgent, String xforwarderfor, Context context, DSpaceObject object)
{
super(checkParams(action, context, object));
this.action = action;
this.setResourceReference(object != null ? Constants.typeText[object.getType()].toLowerCase() + ":" + object.getID() : null);
switch(action)
{
case CREATE:
case UPDATE:
case DELETE:
case WITHDRAW:
case REINSTATE:
case ADD:
case REMOVE:
this.setModify(true);
break;
default :
this.setModify(false);
}
if(context != null && context.getCurrentUser() != null)
{
this.setUserId(
String.valueOf(context.getCurrentUser().getID()));
}
this.request = null;
this.ip = ip;
this.userAgent = userAgent;
this.xforwarderfor = xforwarderfor;
this.context = context;
this.object = object;
}
public HttpServletRequest getRequest() { public HttpServletRequest getRequest() {
return request; return request;
} }
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUserAgent() {
return userAgent;
}
public void setUserAgent(String userAgent) {
this.userAgent = userAgent;
}
public String getXforwarderfor() {
return xforwarderfor;
}
public void setXforwarderfor(String xforwarderfor) {
this.xforwarderfor = xforwarderfor;
}
public void setRequest(HttpServletRequest request) { public void setRequest(HttpServletRequest request) {
this.request = request; this.request = request;
} }

View File

@@ -53,6 +53,13 @@ View information about a bitstream
View/Download a specific Bitstream View/Download a specific Bitstream
- http://localhost:8080/rest/bitstreams/:ID/retrieve - http://localhost:8080/rest/bitstreams/:ID/retrieve
####Statistics
Recording of statistics for view of items or download of bitstreams (set stats = true in rest.cfg to enable stats recording)
http://localhost:8080/rest/items/:ID?userIP=ip&userAgent=userAgent&xforwarderfor=xforwarderfor
If no parameters are given the details of httprequest sender are used in statistics.
This enables tools to record the details of their user rather then themselves.
###Handles ###Handles
Lookup a DSpaceObject by its Handle, this produces the name/ID, that you lookup in /bitstreams, /items, /collections, /communities Lookup a DSpaceObject by its Handle, this produces the name/ID, that you lookup in /bitstreams, /items, /collections, /communities
- http://localhost:8080/rest/handle/{prefix}/{suffix} - http://localhost:8080/rest/handle/{prefix}/{suffix}

View File

@@ -38,6 +38,59 @@
<artifactId>jersey-json</artifactId> <artifactId>jersey-json</artifactId>
<version>1.17.1</version> <version>1.17.1</version>
</dependency> </dependency>
<!-- Spring 3 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!-- Jersey + Spring -->
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>1.8</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use DSpace, for now, an older version to minimize spring generated dependency on Discovery --> <!-- Use DSpace, for now, an older version to minimize spring generated dependency on Discovery -->
<dependency> <dependency>
@@ -60,12 +113,21 @@
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version> <version>3.1.0</version>
<scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.atteo</groupId> <groupId>org.atteo</groupId>
<artifactId>evo-inflector</artifactId> <artifactId>evo-inflector</artifactId>
<version>1.0.1</version> <version>1.0.1</version>
</dependency> </dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-services</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>

View File

@@ -10,10 +10,17 @@ package org.dspace.rest;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.AuthorizeManager; import org.dspace.authorize.AuthorizeManager;
import org.dspace.core.Context; import org.dspace.content.DSpaceObject;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants;
import org.dspace.rest.common.Bitstream; import org.dspace.rest.common.Bitstream;
import org.dspace.usage.UsageEvent;
import org.dspace.utils.DSpace;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*; import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.io.IOException; import java.io.IOException;
@@ -30,6 +37,12 @@ import java.sql.SQLException;
public class BitstreamResource { public class BitstreamResource {
Logger log = Logger.getLogger(BitstreamResource.class); Logger log = Logger.getLogger(BitstreamResource.class);
private static org.dspace.core.Context context; private static org.dspace.core.Context context;
private static final boolean writeStatistics;
static{
writeStatistics=ConfigurationManager.getBooleanProperty("rest","stats",false);
}
//BitstreamList - Not Implemented //BitstreamList - Not Implemented
@@ -39,7 +52,7 @@ public class BitstreamResource {
public Bitstream getBitstream(@PathParam("bitstream_id") Integer bitstream_id, @QueryParam("expand") String expand) { public Bitstream getBitstream(@PathParam("bitstream_id") Integer bitstream_id, @QueryParam("expand") String expand) {
try { try {
if(context == null || !context.isValid()) { if(context == null || !context.isValid()) {
context = new Context(); context = new org.dspace.core.Context();
//Failed SQL is ignored as a failed SQL statement, prevent: current transaction is aborted, commands ignored until end of transaction block //Failed SQL is ignored as a failed SQL statement, prevent: current transaction is aborted, commands ignored until end of transaction block
context.getDBConnection().setAutoCommit(true); context.getDBConnection().setAutoCommit(true);
} }
@@ -59,7 +72,9 @@ public class BitstreamResource {
@GET @GET
@Path("/{bitstream_id}/retrieve") @Path("/{bitstream_id}/retrieve")
public javax.ws.rs.core.Response getFile(@PathParam("bitstream_id") final Integer bitstream_id) { public javax.ws.rs.core.Response getFile(@PathParam("bitstream_id") final Integer bitstream_id,
@QueryParam("userIP") String user_ip, @QueryParam("userAgent") String user_agent, @QueryParam("xforwarderfor") String xforwarderfor,
@Context HttpHeaders headers, @Context HttpServletRequest request) {
try { try {
if(context == null || !context.isValid() ) { if(context == null || !context.isValid() ) {
context = new org.dspace.core.Context(); context = new org.dspace.core.Context();
@@ -69,6 +84,10 @@ public class BitstreamResource {
org.dspace.content.Bitstream bitstream = org.dspace.content.Bitstream.find(context, bitstream_id); org.dspace.content.Bitstream bitstream = org.dspace.content.Bitstream.find(context, bitstream_id);
if(AuthorizeManager.authorizeActionBoolean(context, bitstream, org.dspace.core.Constants.READ)) { if(AuthorizeManager.authorizeActionBoolean(context, bitstream, org.dspace.core.Constants.READ)) {
if(writeStatistics){
writeStats(bitstream_id, user_ip, user_agent, xforwarderfor, headers, request);
}
return Response.ok(bitstream.retrieve()).type(bitstream.getFormat().getMIMEType()).build(); return Response.ok(bitstream.retrieve()).type(bitstream.getFormat().getMIMEType()).build();
} else { } else {
throw new WebApplicationException(Response.Status.UNAUTHORIZED); throw new WebApplicationException(Response.Status.UNAUTHORIZED);
@@ -85,4 +104,37 @@ public class BitstreamResource {
throw new WebApplicationException(Response.Status.UNAUTHORIZED); throw new WebApplicationException(Response.Status.UNAUTHORIZED);
} }
} }
private void writeStats(Integer bitstream_id, String user_ip, String user_agent,
String xforwarderfor, HttpHeaders headers,
HttpServletRequest request) {
try{
DSpaceObject bitstream = DSpaceObject.find(context, Constants.BITSTREAM, bitstream_id);
if(user_ip==null || user_ip.length()==0){
new DSpace().getEventService().fireEvent(
new UsageEvent(
UsageEvent.Action.VIEW,
request,
context,
bitstream));
} else{
new DSpace().getEventService().fireEvent(
new UsageEvent(
UsageEvent.Action.VIEW,
user_ip,
user_agent,
xforwarderfor,
context,
bitstream));
}
log.debug("fired event");
} catch(SQLException ex){
log.error("SQL exception can't write usageEvent \n" + ex);
}
}
} }

View File

@@ -9,13 +9,21 @@ package org.dspace.rest;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeManager; import org.dspace.authorize.AuthorizeManager;
import org.dspace.core.Context; import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*; import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.sql.SQLException; import java.sql.SQLException;
import org.dspace.content.DSpaceObject;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants;
import org.dspace.usage.UsageEvent;
import org.dspace.utils.DSpace;
/** /**
* Created with IntelliJ IDEA. * Created with IntelliJ IDEA.
* User: peterdietz * User: peterdietz
@@ -25,7 +33,15 @@ import java.sql.SQLException;
*/ */
@Path("/items") @Path("/items")
public class ItemsResource { public class ItemsResource {
Logger log = Logger.getLogger(ItemsResource.class);
private static final boolean writeStatistics;
static{
writeStatistics=ConfigurationManager.getBooleanProperty("rest","stats",false);
}
/** log4j category */
private static final Logger log = Logger.getLogger(ItemsResource.class);
//ItemList - Not Implemented //ItemList - Not Implemented
private static org.dspace.core.Context context; private static org.dspace.core.Context context;
@@ -33,10 +49,14 @@ public class ItemsResource {
@GET @GET
@Path("/{item_id}") @Path("/{item_id}")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public org.dspace.rest.common.Item getItem(@PathParam("item_id") Integer item_id, @QueryParam("expand") String expand) throws WebApplicationException{ public org.dspace.rest.common.Item getItem(@PathParam("item_id") Integer item_id, @QueryParam("expand") String expand,
@QueryParam("userIP") String user_ip, @QueryParam("userAgent") String user_agent, @QueryParam("xforwarderfor") String xforwarderfor,
@Context HttpHeaders headers, @Context HttpServletRequest request) throws WebApplicationException {
try { try {
if(context == null || !context.isValid()) { if(context == null || !context.isValid()) {
context = new Context(); context = new org.dspace.core.Context();
//Failed SQL is ignored as a failed SQL statement, prevent: current transaction is aborted, commands ignored until end of transaction block //Failed SQL is ignored as a failed SQL statement, prevent: current transaction is aborted, commands ignored until end of transaction block
context.getDBConnection().setAutoCommit(true); context.getDBConnection().setAutoCommit(true);
} }
@@ -44,6 +64,9 @@ public class ItemsResource {
org.dspace.content.Item item = org.dspace.content.Item.find(context, item_id); org.dspace.content.Item item = org.dspace.content.Item.find(context, item_id);
if(AuthorizeManager.authorizeActionBoolean(context, item, org.dspace.core.Constants.READ)) { if(AuthorizeManager.authorizeActionBoolean(context, item, org.dspace.core.Constants.READ)) {
if(writeStatistics){
writeStats(item_id, user_ip, user_agent, xforwarderfor, headers, request);
}
return new org.dspace.rest.common.Item(item, expand, context); return new org.dspace.rest.common.Item(item, expand, context);
} else { } else {
throw new WebApplicationException(Response.Status.UNAUTHORIZED); throw new WebApplicationException(Response.Status.UNAUTHORIZED);
@@ -54,4 +77,38 @@ public class ItemsResource {
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
} }
} }
private void writeStats(Integer item_id, String user_ip, String user_agent,
String xforwarderfor, HttpHeaders headers,
HttpServletRequest request) {
try{
DSpaceObject item = DSpaceObject.find(context, Constants.ITEM, item_id);
if(user_ip==null || user_ip.length()==0){
new DSpace().getEventService().fireEvent(
new UsageEvent(
UsageEvent.Action.VIEW,
request,
context,
item));
} else{
new DSpace().getEventService().fireEvent(
new UsageEvent(
UsageEvent.Action.VIEW,
user_ip,
user_agent,
xforwarderfor,
context,
item));
}
log.debug("fired event");
} catch(SQLException ex){
log.error("SQL exception can't write usageEvent \n" + ex);
}
}
} }

View File

@@ -31,9 +31,11 @@ public class Bitstream extends DSpaceObject {
private String description; private String description;
private String format; private String format;
private String mimeType; private String mimeType;
private String sizeBytes; private Long sizeBytes;
private DSpaceObject parentObject; private DSpaceObject parentObject;
private String retrieveLink; private String retrieveLink;
private CheckSum checkSum;
private Integer sequenceId;
public Bitstream() { public Bitstream() {
@@ -59,9 +61,14 @@ public class Bitstream extends DSpaceObject {
description = bitstream.getDescription(); description = bitstream.getDescription();
format = bitstream.getFormatDescription(); format = bitstream.getFormatDescription();
sizeBytes = bitstream.getSize() + ""; sizeBytes = bitstream.getSize();
retrieveLink = "/bitstreams/" + bitstream.getID() + "/retrieve"; retrieveLink = "/bitstreams/" + bitstream.getID() + "/retrieve";
mimeType = bitstream.getFormat().getMIMEType(); mimeType = bitstream.getFormat().getMIMEType();
sequenceId = bitstream.getSequenceID();
CheckSum checkSum = new CheckSum();
checkSum.setCheckSumAlgorith(bitstream.getChecksumAlgorithm());
checkSum.setValue(bitstream.getChecksum());
this.setCheckSum(checkSum);
if(expandFields.contains("parent") || expandFields.contains("all")) { if(expandFields.contains("parent") || expandFields.contains("all")) {
parentObject = new DSpaceObject(bitstream.getParentObject()); parentObject = new DSpaceObject(bitstream.getParentObject());
@@ -74,11 +81,47 @@ public class Bitstream extends DSpaceObject {
} }
} }
public String getBundleName() { public Integer getSequenceId() {
return sequenceId;
}
public void setSequenceId(Integer sequenceId) {
this.sequenceId = sequenceId;
}
public String getBundleName() {
return bundleName; return bundleName;
} }
public String getDescription() { public void setBundleName(String bundleName) {
this.bundleName = bundleName;
}
public void setDescription(String description) {
this.description = description;
}
public void setFormat(String format) {
this.format = format;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
public void setSizeBytes(Long sizeBytes) {
this.sizeBytes = sizeBytes;
}
public void setParentObject(DSpaceObject parentObject) {
this.parentObject = parentObject;
}
public void setRetrieveLink(String retrieveLink) {
this.retrieveLink = retrieveLink;
}
public String getDescription() {
return description; return description;
} }
@@ -90,7 +133,7 @@ public class Bitstream extends DSpaceObject {
return mimeType; return mimeType;
} }
public String getSizeBytes() { public Long getSizeBytes() {
return sizeBytes; return sizeBytes;
} }
@@ -101,4 +144,13 @@ public class Bitstream extends DSpaceObject {
public DSpaceObject getParentObject() { public DSpaceObject getParentObject() {
return parentObject; return parentObject;
} }
public CheckSum getCheckSum() {
return checkSum;
}
public void setCheckSum(CheckSum checkSum) {
this.checkSum = checkSum;
}
} }

View File

@@ -0,0 +1,31 @@
package org.dspace.rest.common;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
@XmlType
public class CheckSum{
String checkSumAlgorithm;
String value;
public CheckSum(){}
@XmlAttribute(name="checkSumAlgorithm")
public String getCheckSumAlgorith() {
return checkSumAlgorithm;
}
public void setCheckSumAlgorith(String checkSumAlgorith) {
this.checkSumAlgorithm = checkSumAlgorith;
}
@XmlValue
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@@ -36,7 +36,6 @@ public class Collection extends DSpaceObject {
private Community parentCommunity; private Community parentCommunity;
private List<Community> parentCommunityList = new ArrayList<Community>(); private List<Community> parentCommunityList = new ArrayList<Community>();
@XmlElement(name = "items")
private List<Item> items = new ArrayList<Item>(); private List<Item> items = new ArrayList<Item>();
//Collection-Metadata //Collection-Metadata

View File

@@ -33,7 +33,6 @@ public class Community extends DSpaceObject{
//Exandable relationships //Exandable relationships
private Bitstream logo; private Bitstream logo;
@XmlElement(name = "parentCommunity")
private Community parentCommunity; private Community parentCommunity;
private String copyrightText, introductoryText, shortDescription, sidebarText; private String copyrightText, introductoryText, shortDescription, sidebarText;
@@ -42,7 +41,6 @@ public class Community extends DSpaceObject{
@XmlElement(name = "subcommunities", required = true) @XmlElement(name = "subcommunities", required = true)
private List<Community> subCommunities = new ArrayList<Community>(); private List<Community> subCommunities = new ArrayList<Community>();
@XmlElement(name = "collections")
private List<Collection> collections = new ArrayList<Collection>(); private List<Collection> collections = new ArrayList<Collection>();
public Community(){} public Community(){}

View File

@@ -34,6 +34,7 @@ public class DSpaceObject {
@XmlElement(name = "link", required = true) @XmlElement(name = "link", required = true)
private String link; private String link;
@XmlElement(required = true)
private ArrayList<String> expand = new ArrayList<String>(); private ArrayList<String> expand = new ArrayList<String>();
public DSpaceObject() { public DSpaceObject() {

View File

@@ -42,10 +42,8 @@ public class Item extends DSpaceObject {
List<Community> parentCommunityList; List<Community> parentCommunityList;
@XmlElement(name = "metadata", required = true)
List<MetadataEntry> metadata; List<MetadataEntry> metadata;
@XmlElement(name = "bitstreams")
List<Bitstream> bitstreams; List<Bitstream> bitstreams;
public Item(){} public Item(){}
@@ -167,4 +165,25 @@ public class Item extends DSpaceObject {
public List<Community> getParentCommunityList() { public List<Community> getParentCommunityList() {
return parentCommunityList; return parentCommunityList;
} }
public void setParentCollection(Collection parentCollection) {
this.parentCollection = parentCollection;
}
public void setParentCollectionList(List<Collection> parentCollectionList) {
this.parentCollectionList = parentCollectionList;
}
public void setParentCommunityList(List<Community> parentCommunityList) {
this.parentCommunityList = parentCommunityList;
}
@XmlElement(required = true)
public void setMetadata(List<MetadataEntry> metadata) {
this.metadata = metadata;
}
public void setBitstreams(List<Bitstream> bitstreams) {
this.bitstreams = bitstreams;
}
} }

View File

@@ -12,9 +12,53 @@
xmlns="http://www.springframework.org/schema/beans" xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"> http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- Acquires the DSpace Utility Class with initialized Service Manager --> <!-- Acquires the DSpace Utility Class with initialized Service Manager -->
<bean id="dspace" class="org.dspace.utils.DSpace"/> <bean id="dspace" class="org.dspace.utils.DSpace"/>
</beans>
<!-- Acquires reference to EventService -->
<bean id="dspace.eventService" factory-bean="dspace" factory-method="getEventService"/>
<!-- Inject the Default LoggerUsageEventListener into the EventService -->
<bean class="org.dspace.usage.LoggerUsageEventListener">
<property name="eventService" >
<ref bean="dspace.eventService"/>
</property>
</bean>
<!-- Inject the Default LoggerUsageEventListener into the EventService -->
<bean class="org.dspace.statistics.SolrLoggerUsageEventListener">
<property name="eventService" >
<ref bean="dspace.eventService"/>
</property>
</bean>
<!-- Elastic Search -->
<!--<bean class="org.dspace.statistics.ElasticSearchLoggerEventListener">
<property name="eventService">
<ref bean="dspace.eventService" />
</property>
</bean>-->
<!--
Uncomment to enable TabFileUsageEventListener
<bean class="org.dspace.app.statistics.TabFileUsageEventListener">
<property name="eventService" >
<ref bean="dspace.eventService"/>
</property>
</bean>
-->
<!--
Uncomment to enable PassiveUsageEventListener
<bean class="org.dspace.app.statistics.PassiveUsageEventListener">
<property name="eventService" >
<ref bean="dspace.eventService"/>
</property>
</bean>
-->
</beans>

View File

@@ -15,7 +15,7 @@
id="WebApp_ID" version="2.5"> id="WebApp_ID" version="2.5">
<servlet> <servlet>
<servlet-name>DSpace REST API</servlet-name> <servlet-name>DSpace REST API</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param> <init-param>
<!-- <!--
The jersey ServletContainer will look for our Root Resource Class The jersey ServletContainer will look for our Root Resource Class
@@ -91,6 +91,13 @@
<listener> <listener>
<listener-class>org.dspace.servicemanager.servlet.DSpaceKernelServletContextListener</listener-class> <listener-class>org.dspace.servicemanager.servlet.DSpaceKernelServletContextListener</listener-class>
</listener> </listener>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app> </web-app>

View File

@@ -0,0 +1,8 @@
#---------------------------------------------------------------#
#--------------------REST CONFIGURATIONS------------------------#
#---------------------------------------------------------------#
# These configs are used by the REST module #
#---------------------------------------------------------------#
# record stats in DSpace statistics module
stats = true