View Javadoc

1   /*
2    * Copyright 2015 Data Archiving and Networked Services (an institute of
3    * Koninklijke Nederlandse Akademie van Wetenschappen), King's College London,
4    * Georg-August-Universitaet Goettingen Stiftung Oeffentlichen Rechts
5    *
6    * Licensed under the EUPL, Version 1.1 or – as soon they will be approved by
7    * the European Commission - subsequent versions of the EUPL (the "Licence");
8    * You may not use this work except in compliance with the Licence.
9    * You may obtain a copy of the Licence at:
10   *
11   * https://joinup.ec.europa.eu/software/page/eupl
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the Licence is distributed on an "AS IS" basis,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the Licence for the specific language governing
17   * permissions and limitations under the Licence.
18   */
19  
20  package eu.ehri.extension;
21  
22  import eu.ehri.extension.base.AbstractAccessibleResource;
23  import eu.ehri.extension.base.AbstractResource;
24  import eu.ehri.extension.base.GetResource;
25  import eu.ehri.project.api.EventsApi;
26  import eu.ehri.project.core.Tx;
27  import eu.ehri.project.definitions.Entities;
28  import eu.ehri.project.exceptions.AccessDenied;
29  import eu.ehri.project.exceptions.ItemNotFound;
30  import eu.ehri.project.models.base.Accessible;
31  import eu.ehri.project.models.events.SystemEvent;
32  import org.neo4j.graphdb.GraphDatabaseService;
33  
34  import javax.ws.rs.DefaultValue;
35  import javax.ws.rs.GET;
36  import javax.ws.rs.Path;
37  import javax.ws.rs.PathParam;
38  import javax.ws.rs.Produces;
39  import javax.ws.rs.QueryParam;
40  import javax.ws.rs.core.Context;
41  import javax.ws.rs.core.MediaType;
42  import javax.ws.rs.core.Response;
43  
44  /**
45   * Provides a web service interface for the Event model. Note: Event instances
46   * are created by the system, so we do not have create/update/delete methods
47   * here.
48   * <p>
49   * The following query parameters apply to all actions in this
50   * resource to apply filtering to the event streams.
51   * <p>
52   * <dl>
53   * <dt>eventTypes</dt><dd>Filter events by type</dd>
54   * <dt>itemTypes</dt><dd>Filter events based on the item type of their subjects</dd>
55   * <dt>itemIds</dt><dd>Filter events pertaining to specific item IDs</dd>
56   * <dt>users</dt><dd>Filter events based on the user IDs they involve</dd>
57   * <dt>from</dt><dd>Exclude events prior to this date (ISO 8601 format)</dd>
58   * <dt>to</dt><dd>Exclude events after this date (ISO 8601 format)</dd>
59   * </dl>
60   * <p>
61   * Additionally the aggregate* end-points accept an <code>aggregation</code>
62   * parameter that groups sequential events according to one of two different
63   * strategies:
64   * <dl>
65   * <dt>user</dt>
66   * <dd>Groups sequential events of all types that are initiated by the same actioner</dd>
67   * <dt>strict</dt>
68   * <dd>
69   * Groups sequential events that:
70   * <ul>
71   * <li>have the same type</li>
72   * <li>have the same actioner</li>
73   * <li>have the same subjects</li>
74   * <li>have the same scope</li>
75   * <li>have the same log message</li>
76   * </ul>
77   * </dd>
78   * </dl>
79   * <p>
80   * Additionally, aggregation can be disabled by using <code>aggregation=off</code>.
81   * <p>
82   * Standard paging parameters apply to all end-points.
83   */
84  @Path(AbstractResource.RESOURCE_ENDPOINT_PREFIX + "/" + Entities.SYSTEM_EVENT)
85  public class SystemEventResource extends AbstractAccessibleResource<SystemEvent>
86          implements GetResource {
87  
88  
89      public SystemEventResource(@Context GraphDatabaseService database) {
90          super(database, SystemEvent.class);
91      }
92  
93      @GET
94      @Produces(MediaType.APPLICATION_JSON)
95      @Path("{id:[^/]+}")
96      @Override
97      public Response get(@PathParam("id") String id) throws ItemNotFound {
98          return getItem(id);
99      }
100 
101     /**
102      * List aggregated global events. Standard list parameters for paging apply.
103      *
104      * @param aggregation The manner in which to aggregate the results, accepting
105      *                    "user", "strict" or "off" (no aggregation). Default is
106      *                    "user".
107      */
108     @GET
109     @Produces(MediaType.APPLICATION_JSON)
110     public Response list(
111             @QueryParam(AGGREGATION_PARAM) @DefaultValue("user") EventsApi.Aggregation aggregation) {
112         try (final Tx tx = beginTx()) {
113             EventsApi eventsApi = getEventsApi()
114                     .withAggregation(aggregation);
115             Response response = streamingListOfLists(eventsApi::aggregate);
116             tx.success();
117             return response;
118         }
119     }
120 
121     /**
122      * Fetch a page of subjects for a given event.
123      *
124      * @param id the event id
125      * @return a list of subject items
126      */
127     @GET
128     @Produces(MediaType.APPLICATION_JSON)
129     @Path("{id:[^/]+}/subjects")
130     public Response pageSubjectsForEvent(@PathParam("id") String id)
131             throws ItemNotFound, AccessDenied {
132         try (final Tx tx = beginTx()) {
133             SystemEvent event = api().detail(id, cls);
134             // Subjects are only serialized to depth 1 for efficiency...
135             Response response = streamingPage(() -> getQuery()
136                             .page(event.getSubjects(), Accessible.class),
137                     getSerializer().withDepth(1).withCache());
138             tx.success();
139             return response;
140         }
141     }
142 }