View Javadoc

1   /*
2    * #%L
3    * Bitrepository Audit Trail Service
4    * 
5    * $Id$
6    * $HeadURL$
7    * %%
8    * Copyright (C) 2010 - 2012 The State and University Library, The Royal Library and The State Archives, Denmark
9    * %%
10   * This program is free software: you can redistribute it and/or modify
11   * it under the terms of the GNU Lesser General Public License as 
12   * published by the Free Software Foundation, either version 2.1 of the 
13   * License, or (at your option) any later version.
14   * 
15   * This program is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   * GNU General Lesser Public License for more details.
19   * 
20   * You should have received a copy of the GNU General Lesser Public 
21   * License along with this program.  If not, see
22   * <http://www.gnu.org/licenses/lgpl-2.1.html>.
23   * #L%
24   */
25  package org.bitrepository.audittrails.webservice;
26  
27  import java.io.IOException;
28  import java.io.OutputStream;
29  import java.util.Calendar;
30  import java.util.Date;
31  
32  import javax.ws.rs.Consumes;
33  import javax.ws.rs.DefaultValue;
34  import javax.ws.rs.FormParam;
35  import javax.ws.rs.POST;
36  import javax.ws.rs.Path;
37  import javax.ws.rs.Produces;
38  import javax.ws.rs.WebApplicationException;
39  import javax.ws.rs.core.MediaType;
40  import javax.ws.rs.core.Response;
41  import javax.ws.rs.core.StreamingOutput;
42  
43  import org.bitrepository.audittrails.AuditTrailService;
44  import org.bitrepository.audittrails.AuditTrailServiceFactory;
45  import org.bitrepository.audittrails.store.AuditEventIterator;
46  import org.bitrepository.bitrepositoryelements.AuditTrailEvent;
47  import org.bitrepository.bitrepositoryelements.FileAction;
48  import org.bitrepository.common.utils.CalendarUtils;
49  import org.bitrepository.common.utils.TimeUtils;
50  import org.json.JSONException;
51  import org.json.JSONObject;
52  import org.slf4j.Logger;
53  import org.slf4j.LoggerFactory;
54  
55  @Path("/AuditTrailService")
56  
57  public class RestAuditTrailService {
58      /** The log.*/
59      private Logger log = LoggerFactory.getLogger(getClass());
60      private AuditTrailService service;
61      private final static String JSON_LIST_START = "[";
62      private final static String JSON_LIST_END = "]";
63      private final static String JSON_LIST_SEPERATOR = ",";
64      
65      public RestAuditTrailService() {
66          service = AuditTrailServiceFactory.getAuditTrailService();	
67      }
68          
69      @POST
70      @Path("/queryAuditTrailEvents/")
71      @Consumes("application/x-www-form-urlencoded")
72      @Produces("application/json")
73      public StreamingOutput queryAuditTrailEvents(
74              @FormParam("fromDate") String fromDate,
75              @FormParam("toDate") String toDate,
76              @FormParam("fileID") String fileID,
77              @FormParam("reportingComponent") String reportingComponent,
78              @FormParam("actor") String actor,
79              @FormParam("action") String action,
80              @FormParam("collectionID") String collectionID,
81              @FormParam("fingerprint") String fingerprint,
82              @FormParam("operationID") String operationID,
83              @DefaultValue("1000") @FormParam("maxAudittrails") Integer maxResults) {
84          Date from = makeDateObject(fromDate);
85          Date to = makeDateObject(toDate);
86          
87          final int maxAudits = maxResults;
88          final AuditEventIterator it = service.queryAuditTrailEventsByIterator(from, to, contentOrNull(fileID),
89                  collectionID, contentOrNull(reportingComponent), contentOrNull(actor), filterAction(action), 
90                  contentOrNull(fingerprint), contentOrNull(operationID));
91          if(it != null) {     
92              return new StreamingOutput() {
93                  public void write(OutputStream output) throws IOException, WebApplicationException {
94                      try {
95                          AuditTrailEvent event;
96                          int numAudits = 0;
97                          output.write(JSON_LIST_START.getBytes());
98                          while((event = it.getNextAuditTrailEvent()) != null && numAudits < maxAudits) {
99                              if(numAudits >= 1) {
100                                 output.write(JSON_LIST_SEPERATOR.getBytes());
101                             }
102                             output.write(makeJSONEntry(event).toString().getBytes());
103                             numAudits++;
104                         }
105                         output.write(JSON_LIST_END.getBytes());
106                     } catch (Exception e) {
107                         throw new WebApplicationException(e);
108                     } finally {
109                         try {
110                             if(it != null) {
111                                 it.close();
112                             }
113                         } catch (Exception e) {
114                             log.error("Caught exception when closing AuditEventIterator", e);
115                             throw new WebApplicationException(e);
116                         }
117                     }
118                 }
119             };
120         } else {
121             throw new WebApplicationException(Response.status(Response.Status.NO_CONTENT)
122                     .entity("Failed to get audit trails from database")
123                     .type(MediaType.TEXT_PLAIN)
124                     .build());
125         }
126     }
127 
128     @POST
129     @Path("/collectAuditTrails/")
130     @Produces("text/html")
131     public String collectAuditTrails() {
132         service.collectAuditTrails();
133         return "Started audittrails collection";
134     }
135     
136     private JSONObject makeJSONEntry(AuditTrailEvent event) {
137         JSONObject obj = new JSONObject();
138         try {
139             obj.put("fileID", event.getFileID());
140             obj.put("reportingComponent", event.getReportingComponent());
141             obj.put("actor", contentOrEmptyString(event.getActorOnFile()));
142             obj.put("action", event.getActionOnFile());
143             obj.put("timeStamp", TimeUtils.shortDate(
144                     CalendarUtils.convertFromXMLGregorianCalendar(event.getActionDateTime())));
145             obj.put("info", contentOrEmptyString(event.getInfo()));
146             obj.put("auditTrailInfo", contentOrEmptyString(event.getAuditTrailInformation()));
147             obj.put("fingerprint", contentOrEmptyString(event.getCertificateID()));
148             obj.put("operationID", contentOrEmptyString(event.getOperationID()));
149             return obj;
150         } catch (JSONException e) {
151             return (JSONObject) JSONObject.NULL;
152         }
153     }
154     
155     private FileAction filterAction(String action) {
156         if(action.equals("ALL")) {
157             return null;
158         } else {
159             return FileAction.fromValue(action);
160         }
161     }
162     
163     private Date makeDateObject(String dateStr) {
164         if(dateStr == null || dateStr.trim().isEmpty()) {
165             return null;
166         } else {
167             String[] components = dateStr.split("/");
168             int year = Integer.parseInt(components[2]);
169             int month = Integer.parseInt(components[0]);
170             int day = Integer.parseInt(components[1]);
171             Calendar time = Calendar.getInstance();
172             time.set(year, (month - 1), day);
173             
174             return time.getTime();
175         }
176     }
177     
178     private String contentOrEmptyString(String input) {
179         if(input == null) {
180             return "";
181         } else {
182             return input.trim();
183         }
184     }
185     
186     private String contentOrNull(String input) {
187         if(input != null && input.trim().isEmpty()) {
188             return null;
189         } else {
190             return input.trim();
191         }
192     }
193 }