/* * Copyright (c) 2008-2011 EMC Corporation * All Rights Reserved */ package com.emc.storageos.db.client; import java.net.URI; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutorService; import org.joda.time.DateTime; import com.emc.storageos.db.client.constraint.Constraint; import com.emc.storageos.db.client.constraint.QueryResultList; import com.emc.storageos.db.client.model.DataObject; import com.emc.storageos.db.client.model.NamedURI; import com.emc.storageos.db.client.model.NoInactiveIndex; import com.emc.storageos.db.client.model.Operation; import com.emc.storageos.db.client.model.TimeSeries; import com.emc.storageos.db.client.model.TimeSeriesSerializer; import com.emc.storageos.db.exceptions.DatabaseException; import com.emc.storageos.model.ResourceOperationTypeEnum; import com.emc.storageos.svcs.errorhandling.model.ServiceCoded; /** * The main database client API */ public interface DbClient { /** * Queries for object with given URI, working out the class type from the URI. Deserializes into a data object of given * class. * * @param id object id * @param <T> object type * @return deserialized object if record is located. null, if matching record does not * exist * @throws DatabaseException TODO */ DataObject queryObject(URI id); /** * Queries for object with given URI. Deserializes into a data object of given * class. * * @param clazz object type * @param id object id * @param <T> object type * @return deserialized object if record is located. null, if matching record does not * exist * @throws DatabaseException TODO */ <T extends DataObject> T queryObject(Class<T> clazz, URI id); /** * Same as queryObject(Class, URI). Takes NamedURI instead. * * @throws DatabaseException TODO */ <T extends DataObject> T queryObject(Class<T> clazz, NamedURI id); /** * Queries for objects with given URI's. Deserializes into a data object of given * class. Please use queryIterativeObjects instead if too many records in db * * * @param clazz object type * @param ids object ids * @param <T> object type * @return deserialized object list. non matching records are not returned * @throws DatabaseException */ <T extends DataObject> List<T> queryObject(Class<T> clazz, Collection<URI> ids); /** * Same as queryObject(Class, List<URI>). Filters on activeOnly record if specified. * Please use queryIterativeObjects instead if too many records in db. * * @param clazz object type * @param ids object ids * @param activeOnly * @return deserialized object list * @throws DatabaseException */ @Deprecated <T extends DataObject> List<T> queryObject(Class<T> clazz, Collection<URI> ids, boolean activeOnly); /** * Same as queryObject(Class, List<URI>). * Please use queryIterativeObjects instead if too many records in db. * * @param clazz object type * @param id object id * @return deserialized object list * @throws DatabaseException */ <T extends DataObject> List<T> queryObject(Class<T> clazz, URI... id); /** * Queries for objects with given URI's. Deserializes into a data object of given * class and returns them as an iterator. This method is different from * queryObject(Class<T> clazz, List<URI>) in a way that it won't load the entire * list of objects into memory at once.if you are dealing with a larger list of * objects, use this method instead of queryObject(Class<T> clazz, List<URI>) * * @param clazz object type * @param id object id * @param <T> object type * @return deserialized object as an Interator. non matching records are not returned * @throws DatabaseException TODO */ <T extends DataObject> Iterator<T> queryIterativeObjects(Class<T> clazz, Collection<URI> id); /** * Same as {@link DbClient#queryIterativeObjects(Class, Collection)}. Filters on activeOnly record if specified. * * @param clazz * @param ids * @param activeOnly * @return * @throws DatabaseException */ <T extends DataObject> Iterator<T> queryIterativeObjects(final Class<T> clazz, Collection<URI> ids, final boolean activeOnly); /** * Queries for a particular field on objects with the given URIs * * @param clazz object type * @param ids object uris * @param fieldName field name to get value of * @param <T> object type * @return deserialized field values for the objects if record is located, * else null * @throws DatabaseException TODO */ <T extends DataObject> List<T> queryObjectField(Class<T> clazz, String fieldName, Collection<URI> ids); /** * Queries for a particular field on objects with the given URIs. * Deserializes into a data object of given class and returns them as an iterator. * This method is different from queryObjectField(Class<T> clazz, String fieldName, List<URI> ids) * in a way that it won't load the entire list of objects into memory at once.if you are dealing * with a larger list of objects, please use this method. * * * @param clazz object type * @param ids object uris * @param fieldName field name to get value of * @param <T> object type * @return deserialized object as an Interator. non matching records are not returned * @throws DatabaseException TODO */ <T extends DataObject> Iterator<T> queryIterativeObjectField(Class<T> clazz, String fieldName, Collection<URI> ids); /** * Aggregate fields for the column by using the provided Aggregator. * This funciton is similar to queryObjectField but it supplies the field values into Aggregator * instead of deserializing objects of the clazz * * * @param clazz * @param ids * @param aggregator * @param <T> * @throws DatabaseException */ <T extends DataObject> void aggregateObjectField(Class<T> clazz, Iterator<URI> ids, DbAggregatorItf aggregator); /** * Return references for objects with given type * * @param clazz object type * @param activeOnly if true, gets only active object ids * @return * @throws DatabaseException TODO */ <T extends DataObject> List<URI> queryByType(Class<T> clazz, boolean activeOnly); /** * Return references for objects with given type * * @param clazz object type * @param activeOnly if true, gets only active object ids * @param startId the resource ID (execlusive) where the query begins * @param count the max number of records returned * @return * @throws DatabaseException */ <T extends DataObject> List<URI> queryByType(Class<T> clazz, boolean activeOnly, URI startId, int count); /** * Query for object of given type that is marked as inactive before specified time. * * @param clazz * @param timeBefore * @param result * @param <T> * @throws DatabaseException */ <T extends DataObject> void queryInactiveObjects(Class<T> clazz, long timeBefore, QueryResultList<URI> result); /** * Queries for objects with given constraint. See constraint package for availabile * options. * * This interface is deprecated. Use queryByConstraint(Constraint, Constraint.QueryResult). * * @param constraint one of available constraints from constraint package * @return list of object URI's that match given constraint * @throws DatabaseException TODO */ @Deprecated List<URI> queryByConstraint(Constraint constraint); /** * Queries for objects with given constraint. See constraint package for * availabile options. * * @param constraint one of available constraints from constraint package * @param result out parameter where query results will be added to * @throws DatabaseException TODO */ <T> void queryByConstraint(Constraint constraint, QueryResultList<T> result); /** * Queries for objects with given constraint start from some resource. See constraint package for * availabile options. * * @param constraint one of available constraints from constraint package * @param result out parameter where query results will be added to * @param startId where the query starts * @param maxCount the max number of resources returned by this query * * @throws DatabaseException TODO */ <T> void queryByConstraint(Constraint constraint, QueryResultList<T> result, URI startId, int maxCount); /** * Returns the count of objects with the given type which have the given URI in the specified * columnField. * * @param type * @param columnField * @param uri * @throws DatabaseException TODO */ Integer countObjects(Class<? extends DataObject> type, String columnField, URI uri); /** * Persists given new object to DB. DataObject.id field must be filled in. This method * should only be used to persists new objects that doesn't exist in DB. * * @param object object to persist * @param <T> data objects * @throws DatabaseException TODO */ <T extends DataObject> void createObject(T object); /** * Persists given list of new objects to DB. DataObject.id field must be filled in. * This method should only be used to persists new objects that doesn't exist in DB. * * @param object object to persist * @param <T> data objects * @throws DatabaseException TODO */ <T extends DataObject> void createObject(Collection<T> objects); /** * See createObject(List<T>) * * @throws DatabaseException TODO */ <T extends DataObject> void createObject(T... object); /** * @deprecated use {@link DbClient#updateObject(T)} instead */ @Deprecated <T extends DataObject> void persistObject(T object); /** * @deprecated use {@link DbClient#updateObject(Collection)} instead */ @Deprecated <T extends DataObject> void persistObject(Collection<T> objects); /** * @deprecated use {@link DbClient#updateObject(T...)} instead */ @Deprecated <T extends DataObject> void persistObject(T... object); /** * @deprecated use {@link DbClient#updateObject(T)} instead */ @Deprecated <T extends DataObject> void updateAndReindexObject(T object); /** * @deprecated use {@link DbClient#updateObject(Collection)} instead */ @Deprecated <T extends DataObject> void updateAndReindexObject(Collection<T> objects); /** * @deprecated use {@link DbClient#updateObject(T...)} instead */ @Deprecated <T extends DataObject> void updateAndReindexObject(T... object); /** * Updates given existing object to DB, also synchronously updates the index fields if needed. * <p/> * DataObject.id field must be filled in. This method * only updates non null fields to DB (meaning partial write is possible). For example, * if FileShare.label field is not set but DB already has label field persisted, it won't * overwrite existing label field when this FileShare object is updated. * <p/> * For StringMap and StringSet, you can also incrementally add and remove entries by inserting * only new elements into them. In order to incrementally remove elements, see javadoc for * these two types. * * @param object object to update * @param <T> data objects * @throws DatabaseException TODO */ <T extends DataObject> void updateObject(T object); /** * Updates given list of existing objects to DB. DataObject.id field must be filled in. * This method only updates non null fields to DB (meaning partial write is possible). * * @param objects objects to update * @param <T> data objects * @throws DatabaseException TODO */ <T extends DataObject> void updateObject(Collection<T> objects); /** * @see DbClient#updateObject(Collection) */ <T extends DataObject> void updateObject(T... object); /** * Convenience method for setting operation status to ready for given object * * @param clazz * @param id * @param opId * @return TODO * @throws DatabaseException */ Operation ready(Class<? extends DataObject> clazz, URI id, String opId); /** * Convenience method for setting operation status to ready for given object * * @param clazz * @param id * @param opId * @param message * @return TODO * @throws DatabaseException */ Operation ready(Class<? extends DataObject> clazz, URI id, String opId, String message); /** * Convenience method for setting operation status to pending for given * object * * @param clazz * @param id * @param opId * @return TODO * @throws DatabaseException */ Operation pending(Class<? extends DataObject> clazz, URI id, String opId, String message); /** * Convenience method for setting operation status to pending for given * object; optionally, the start time can be reset * * @param clazz resource class type * @param id resource id * @param opId operation/task/request id (maps to requestId in Task) * @param message * @param resetStartTime resets the start time on the tasks if true * @return */ Operation pending(Class<? extends DataObject> clazz, URI id, String opId, String message, boolean resetStartTime); /** * Sets operation status to suspended. This means that it is not currently executing, but * has been suspended because of a request to suspend the step. * @param clazz * @param id * @param opId * @param message * @return * @throws DatabaseException */ public Operation suspended_no_error(Class<? extends DataObject> clazz, URI id, String opId, String message) throws DatabaseException; public Operation suspended_no_error(Class<? extends DataObject> clazz, URI id, String opId) throws DatabaseException; /** * Sets operation status to suspended. This means that it is not currently executing, but * has been suspended because of an error. * @param clazz * @param id * @param opId * @param message * @return * @throws DatabaseException */ public Operation suspended_error(Class<? extends DataObject> clazz, URI id, String opId, ServiceCoded serviceCoded) throws DatabaseException; /** * Convenience method for setting operation status to error for given object * * @param clazz * @param id * @param serviceCode * @return TODO * @throws DatabaseException */ Operation error(Class<? extends DataObject> clazz, URI id, String opId, ServiceCoded serviceCoded); /** * Convenience method for setting operation status for given object * * @param clazz * @param id * @param opId * @param status * @throws DatabaseException TODO */ @Deprecated void setStatus(Class<? extends DataObject> clazz, URI id, String opId, String status); /** * Convenience method for setting operation status for given object * * @param clazz * @param id * @param opId * @param status * @param message * @throws DatabaseException */ @Deprecated void setStatus(Class<? extends DataObject> clazz, URI id, String opId, String status, String message); /** * Convenience method for creating and setting the operation status for * given object This method will set the starttime of the Operation to * current calendar time. If the passed in opertion object has start time * set, that will be overwritten by the current calendar time. * * @param clazz * @param id - uuid of the resource * @param opId - task or operation id * @param newOperation - operation object * @throws DatabaseException */ Operation createTaskOpStatus(Class<? extends DataObject> clazz, URI id, String opId, Operation newOperation); /** * Convenience method for creating and setting the operation status for * given object. This method will set the start time of the Operation to * current calendar time. * * @param clazz * @param id - uuid of the resource * @param opId - task or operation id * @param type - type of operation * @throws DatabaseException */ Operation createTaskOpStatus(Class<? extends DataObject> clazz, URI id, String opId, ResourceOperationTypeEnum type); /** * Convenience method for creating and setting the operation status for * given object. This method will set the start time of the Operation to * current calendar time. * * @param clazz * @param id - uuid of the resource * @param opId - task or operation id * @param type - type of operation * @param associatedResources - list of associated resources to the task * @throws DatabaseException */ Operation createTaskOpStatus(Class<? extends DataObject> clazz, URI id, String opId, ResourceOperationTypeEnum type, String associatedResources); /** * Convenience method for updating the operation status for given object * * @param clazz * @param id - uuid of the resource * @param opId - task or operation id * @param updateOperation - operation object that contains the new opStatus. * @throws DatabaseException TODO */ @Deprecated // As public, should be changed to protected when no longer called from outside this class hierarchy. Operation updateTaskOpStatus(Class<? extends DataObject> clazz, URI id, String opId, Operation updateOperation); /** * Marks an object for deletion. Note that DB does not remove an object immediately * after it's marked for deletion. This is done for a couple of reasons * * 1. avoid lost update problems during concurrent delete / update * 2. to give clients a chance to verify object status prior to removal from db * * DB svc will periodically purge objects older than preconfigured time period. * * @param object object to mark for deletion * @throws DatabaseException TODO */ void markForDeletion(DataObject object); /** * Marks a list of objects for deletion. Note that DB does not remove an object immediately * after it's marked for deletion. This is done for a couple of reasons * * 1. avoid lost update problems during concurrent delete / update * 2. to give clients a chance to verify object status prior to removal from db * * DB svc will periodically purge objects older than preconfigured time period. * * @param object list of objects to mark for deletion * @throws DatabaseException TODO */ void markForDeletion(Collection<? extends DataObject> objects); /** * See markForDeletion(List) * * @throws DatabaseException TODO */ <T extends DataObject> void markForDeletion(T... object); /** * This method will do different operation according whether object class has * {@link com.emc.storageos.db.client.model.NoInactiveIndex} annotation. * * <p> * If data object has NoInactiveIndex annotation, this method will delete object immediately from DB * <p> * If data object doesn't have NoInactiveIndex annotation, this method will internally call {@link DbClient#markForDeletion()} * * @see NoInactiveIndex * @see DbClient#markForDeletion() * * @param object array of objects to delete * @throws DatabaseException TODO */ void removeObject(DataObject... object); /** * Inserts time series data of given type. Time series implementation * implements TimeSeries<T> interface. EventTimeSeries is an example of such * implementation for event data. For other types of time series data, You * can follow EventTimeSeries template. * * Note that shard and bucket granularity are defined using annotations in * your TimeSeries implementation. * * Time series is organized (in the DB) in the following manner * * If bucket granularity is specified as HOURLY and shard count is 10 * * 1. For every hour time bucket(UTC time), there will be 10 rows. 2. * Insertion will spread across those 10 rows for the same hour 3. Each time * series data point will have insertion time uuid as column id and * serialized content as value * * Consistency level of one is used for insertion. This means that * read-after-write is not guaranteed in a cluster. Query clients should not * expect all results to be present when querying the current time bucket * * @param tsType time series implementation class (such as EventTimeSeries, * for example) * @param data time series data points to insert * @param <T> * @return bucket / row ID where this batch of time series data was stored * @throws DatabaseException TODO */ <T extends TimeSeriesSerializer.DataPoint> String insertTimeSeries( Class<? extends TimeSeries> tsType, T... data); /** * Inserts a data point of time series with given timestamp. * * This API is for testing convenience only. We should not use it in normal * code path. * * @param tsType time series implementation class (such as EventTimeSeries, * for example) * @param time timestamp * @param data time series data point to insert * @return bucket / row ID where this batch of time series data was stored * @throws DatabaseException TODO */ <T extends TimeSeriesSerializer.DataPoint> String insertTimeSeries( Class<? extends TimeSeries> tsType, DateTime time, T data); /** * Queries time series data for given time bucket. For example, if time * series class specifies HOURLY bucket and timeBucket argument is 2012-4-16 * 1:10:00 UTC time, this query will retrieves data from all shards for an * hour bucket for 2012-4-16 1:00:00 UTC time. * * This method will call TimeSeriesQueryResult#data for every record found * in that time bucket. Note that callbacks will done from multiple threads * using workerThreads executor service. * * Note that executor service should limit the number of threads used for * parallel execution (fixed thread pool, for example). For each shard in a * given time bucket, default implementation will launch a parallel queries. * * @param tsType See insertTimeSeries for explanation of what time series * class is * @param timeBucket time bucket * @param callback result callback * @param workerThreads executor service to use for running parallel queries * @param <T> * @throws DatabaseException TODO */ <T extends TimeSeriesSerializer.DataPoint> void queryTimeSeries( Class<? extends TimeSeries> tsType, DateTime timeBucket, TimeSeriesQueryResult<T> callback, ExecutorService workerThreads); /** * Overload of queryTimeSeries(TimeSeries, DateTime, TImeSeriesQueryResult, * ExecutorService) that takes non default TimeBucket. Note that bucket must * be be same or finer granularity than what's specified in TimeSeries type. * For example, you may use MINUTE and HOUR buckets when time series type is * specified with HOUR bucket. * * @throws DatabaseException TODO */ <T extends TimeSeriesSerializer.DataPoint> void queryTimeSeries( Class<? extends TimeSeries> tsType, DateTime timeBucket, TimeSeriesMetadata.TimeBucket bucket, TimeSeriesQueryResult<T> callback, ExecutorService workerThreads); /** * Queries metadata for give time series data type * * @param tsType time series class (like EventTimeSeries) * @return * @throws DatabaseException TODO */ TimeSeriesMetadata queryTimeSeriesMetadata(Class<? extends TimeSeries> tsType); /** * Starts DB connection pool */ void start(); /** * Shuts down DB connection pool */ void stop(); <T extends DataObject> Collection<T> queryObjectFields(Class<T> clazz, Collection<String> fieldNames, Collection<URI> ids); <T extends DataObject> Iterator<T> queryIterativeObjectFields(Class<T> clazz, Collection<String> fieldNames, Collection<URI> ids); /** * Get the DB schema version */ String getSchemaVersion(); /** * Retrieve the short ID of the local VDC * Deprecated; use VdcUtils.getLocakVcdId() instead * * @return the vdc id */ @Deprecated String getLocalShortVdcId(); /** * Get the full URN for the VDC referenced by the short vdcId * Deprecated; use VdcUtils.getVdcUrn() instead * * @param shortVdcId the vdc short id * @return the VDC object's full URN or null if not found */ @Deprecated URI getVdcUrn(String shortVdcId); /** * For a rebuild of the Vdc to Urn cache used for mapping short VDC ids * Deprecated; use VdcUtils.invalidateVdcUrnCache() instead */ @Deprecated void invalidateVdcUrnCache(); /** * Check if Geo db version is compatible or not in a federation. * * @param expectVersion version of Geo db * @return true if Geo db version in all vdcs of the federation is equals or high then expectVersion which indicates * the features for geoVersion can be enabled. Otherwise false; * */ boolean checkGeoCompatible(String expectVersion); /** * Check whether there is active and useful data in database. Don't check the data whose type is in excludeClasses * @return true if there are useful data */ boolean hasUsefulData(); }