001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2015-2016 ForgeRock AS.
015 */
016
017package org.forgerock.audit;
018
019import java.util.Collection;
020import java.util.Set;
021
022import org.forgerock.audit.events.handlers.AuditEventHandler;
023import org.forgerock.json.resource.ActionRequest;
024import org.forgerock.json.resource.ActionResponse;
025import org.forgerock.json.resource.CreateRequest;
026import org.forgerock.json.resource.DeleteRequest;
027import org.forgerock.json.resource.NotSupportedException;
028import org.forgerock.json.resource.PatchRequest;
029import org.forgerock.json.resource.QueryRequest;
030import org.forgerock.json.resource.QueryResourceHandler;
031import org.forgerock.json.resource.QueryResponse;
032import org.forgerock.json.resource.ReadRequest;
033import org.forgerock.json.resource.RequestHandler;
034import org.forgerock.json.resource.ResourceException;
035import org.forgerock.json.resource.ResourceResponse;
036import org.forgerock.json.resource.ServiceUnavailableException;
037import org.forgerock.json.resource.UpdateRequest;
038import org.forgerock.services.context.Context;
039import org.forgerock.util.promise.Promise;
040
041/**
042 * CREST {@link RequestHandler} responsible for storing and retrieving audit events.
043 * <p/>
044 * After construction, the AuditService will be in the 'STARTING' state until {@link #startup()} is called.
045 * When in the 'STARTING' state, a call to any method other than {@link #startup()} will lead to
046 * {@link ServiceUnavailableException}.
047 * <p/>
048 * After {@link #startup()} is called, assuming startup succeeds, the AuditService will then be in the
049 * 'RUNNING' state and further calls to {@link #startup()} will be ignored.
050 * <p/>
051 * Calling {@link #shutdown()} will put the AuditService into the 'SHUTDOWN' state; once shutdown, the
052 * AuditService will remain in this state and cannot be restarted. Further calls to {@link #shutdown()}
053 * will be ignored. When in the 'SHUTDOWN' state, a call to any method other than {@link #shutdown()} will
054 * lead to {@link ServiceUnavailableException}.
055 */
056public interface AuditService extends RequestHandler {
057
058    /**
059     * Gets an object from the audit logs by identifier. The returned object is not validated
060     * against the current schema and may need processing to conform to an updated schema.
061     * <p>
062     * The object will contain metadata properties, including object identifier {@code _id},
063     * and object version {@code _rev} to enable optimistic concurrency
064     * <p/>
065     * If this {@code AuditService} has been closed, the returned promise will resolve to a
066     * {@link ServiceUnavailableException}.
067     *
068     * {@inheritDoc}
069     */
070    @Override
071    Promise<ResourceResponse, ResourceException> handleRead(Context context, ReadRequest request);
072
073    /**
074     * Propagates the audit event to the {@link AuditEventHandler} objects that have been registered
075     * for the audit event topic.
076     * <p>
077     * This method sets the {@code _id} property to the assigned identifier for the object,
078     * and the {@code _rev} property to the revised object version (For optimistic concurrency).
079     * <p/>
080     * If this {@code AuditService} has been closed, the returned promise will resolve to a
081     * {@link ServiceUnavailableException}.
082     *
083     * {@inheritDoc}
084     */
085    @Override
086    Promise<ResourceResponse, ResourceException> handleCreate(Context context, CreateRequest request);
087
088    /**
089     * Audit service does not support changing audit entries.
090     * <p/>
091     * The returned promise will resolve to a {@link NotSupportedException}.
092     */
093    @Override
094    Promise<ResourceResponse, ResourceException> handleUpdate(Context context, UpdateRequest request);
095
096    /**
097     * Audit service does not support changing audit entries.
098     * <p/>
099     * The returned promise will resolve to a {@link NotSupportedException}.
100     */
101    @Override
102    Promise<ResourceResponse, ResourceException> handleDelete(Context context, DeleteRequest request);
103
104    /**
105     * Audit service does not support changing audit entries.
106     * <p/>
107     * The returned promise will resolve to a {@link NotSupportedException}.
108     */
109    @Override
110    Promise<ResourceResponse, ResourceException> handlePatch(Context context, PatchRequest request);
111
112    /**
113     * Performs the query on the specified object and returns the associated results.
114     * <p>
115     * Queries are parametric; a set of named parameters is provided as the query criteria.
116     * The query result is a JSON object structure composed of basic Java types.
117     *
118     * The returned map is structured as follow:
119     * <ul>
120     * <li>The top level map contains meta-data about the query, plus an entry with the actual result records.
121     * <li>The <code>QueryConstants</code> defines the map keys, including the result records (QUERY_RESULT)
122     * </ul>
123     * <p/>
124     * If this {@code AuditService} has been closed, the returned promise will resolve to a
125     * {@link ServiceUnavailableException}.
126     *
127     * {@inheritDoc}
128     */
129    @Override
130    Promise<QueryResponse, ResourceException> handleQuery(
131            Context context, QueryRequest request, QueryResourceHandler handler);
132
133    /**
134     * Audit service may support actions on the service itself or on handlers.
135     * <p>
136     * One of the following paths format is expected:
137     * <pre>
138     * [path-to-audit-service]?_action=XXX : call a global action on audit service
139     * [path-to-audit-service/[topic]?_action=XXX : call an action on audit service and a single topic
140     * [path-to-audit-service]?_action=XXX&handler=HHH : call on action on a specific handler
141     * [path-to-audit-service/[topic]?_action=XXX&handler=HHH : call on action on a specific handler and topic
142     * </pre>
143     */
144    @Override
145    Promise<ActionResponse, ResourceException> handleAction(Context context, ActionRequest request);
146
147    /**
148     * Gets the AuditService configuration.
149     *
150     * @return the audit service config
151     * @throws ServiceUnavailableException if the AuditService has been closed.
152     */
153    AuditServiceConfiguration getConfig() throws ServiceUnavailableException;
154
155    /**
156     * Returns the registered handler corresponding to provided name.
157     *
158     * @param handlerName
159     *            Name of the registered handler to retrieve.
160     * @return the handler, or {@code null} if no handler with the provided name
161     *         was registered to the service.
162     * @throws ServiceUnavailableException if the AuditService has been closed.
163     */
164    AuditEventHandler getRegisteredHandler(String handlerName) throws ServiceUnavailableException;
165
166    /**
167     * Returns the registered handlers.
168     *
169     * @return the handlers
170     * @throws ServiceUnavailableException if the AuditService has been closed.
171     */
172    Collection<AuditEventHandler> getRegisteredHandlers() throws ServiceUnavailableException;
173
174    /**
175     * Returns whether or not events of the specified topic will be handled.
176     *
177     * @param topic Identifies a category of events to which handlers may or may not be registered.
178     * @return whether handling of the specified topic is enabled.
179     * @throws ServiceUnavailableException if the AuditService has been closed.
180     */
181    boolean isAuditing(String topic) throws ServiceUnavailableException;
182
183    /**
184     * Returns the set of event topics (schemas) that the <code>AuditService</code> understands.
185     *
186     * @return The set of event topics.
187     * @throws ServiceUnavailableException if the AuditService has been closed.
188     */
189    Set<String> getKnownTopics() throws ServiceUnavailableException;
190
191    /**
192     * Allows this {@code AuditService} and all its {@link AuditEventHandler}s to perform any initialization that
193     * would be unsafe to do if any other instance of the {@code AuditService} were still running.
194     * @throws ServiceUnavailableException if the AuditService has been closed.
195     */
196    void startup() throws ServiceUnavailableException;
197
198    /**
199     * Closes this {@code AuditService} and all its {@link AuditEventHandler}s.
200     * <p/>
201     * This ensures that any buffered are flushed and all file handles / network connections are closed.
202     * <p/>
203     * Once {@code closed}, any further calls to this {@code AuditService} will throw, or return a promise
204     * that will resolve to, {@link ServiceUnavailableException}.
205     */
206    void shutdown();
207
208    /**
209     * Returns <tt>true</tt> if this object is running.
210     * <p/>
211     * This object will be in a 'running' state if {@link #startup()} completed successfully and {@link #shutdown()}
212     * has not yet been called.
213     *
214     * @return true if this object is running; false otherwise.
215     */
216    boolean isRunning();
217}