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