package org.gbif.ipt.service.manage; import org.gbif.ipt.action.BaseAction; import org.gbif.ipt.model.Ipt; import org.gbif.ipt.model.Organisation; import org.gbif.ipt.model.Resource; import org.gbif.ipt.model.User; import org.gbif.ipt.model.voc.PublicationStatus; import org.gbif.ipt.service.AlreadyExistingException; import org.gbif.ipt.service.DeletionNotAllowedException; import org.gbif.ipt.service.ImportException; import org.gbif.ipt.service.InvalidConfigException; import org.gbif.ipt.service.InvalidFilenameException; import org.gbif.ipt.service.PublicationException; import org.gbif.ipt.service.manage.impl.ResourceManagerImpl; import org.gbif.ipt.task.StatusReport; import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; import javax.annotation.Nullable; import com.google.common.collect.ListMultimap; import com.google.inject.ImplementedBy; /** * This interface details ALL methods associated with the main resource entity. * The manager keeps a map of the basic metadata and authorisation information in memory, but further details like the * full EML or mapping configuration is stored in files and loaded into manager sessions when needed. */ @ImplementedBy(ResourceManagerImpl.class) public interface ResourceManager { /** * Cancels publishing. * * @param shortname Resource shortname * @param action action * * @return result of trying to cancel publishing: was successful or not */ boolean cancelPublishing(String shortname, BaseAction action); /** * Create a new Resource. * * @param shortname Resource's shortName * @param type resource type * @param dwca DwC-A file * @param creator Creator User * @param action action * * @return Resource newly created, or null if it couldn't be created successfully * * @throws AlreadyExistingException if Resource already existed * @throws ImportException if a problem occurred importing the DwC-A file * @throws org.gbif.ipt.service.InvalidFilenameException if source filename contained an illegal character */ Resource create(String shortname, String type, File dwca, User creator, BaseAction action) throws AlreadyExistingException, ImportException, InvalidFilenameException; /** * Create a new Resource. * * @param shortname Resource's shortName * @param type resource type * @param creator Creator User * * @return Resource newly created, or null if it couldn't be created successfully * * @throws AlreadyExistingException if Resource already existed */ Resource create(String shortname, String type, User creator) throws AlreadyExistingException; /** * Deletes a Resource. * * @param resource Resource * @param remove whether the resource folder should be deleted from the data directory during deletion * * @throws IOException if deletion could not be completed * @throws DeletionNotAllowedException if deletion was not allowed to be completed */ void delete(Resource resource, boolean remove) throws IOException, DeletionNotAllowedException; /** * Gets a resource by its shortName. * * @param shortname Resource shortName * * @return Resource, or null if none was found for this shortName */ Resource get(String shortname); /** * Validate if the EML file exists for a specific resource in the data directory. * * @param shortName Resource shortname * * @return true if EML File exists, and false otherwise. */ boolean isEmlExisting(String shortName); /** * Checks whether the resource is currently locked or not. It then checks if the task is done or not. If done * successfully, the remaining steps in publishing are executed. If it failed for any reason, * the previous published version is restored. * * @param shortname Resource shortname * @param action the action to use for logging messages * * @return true if resource is currently locked for any management. */ boolean isLocked(String shortname, BaseAction action); /** * Defaults BaseAction to null. * * @see org.gbif.ipt.service.manage.ResourceManager#isLocked(String, org.gbif.ipt.action.BaseAction) */ boolean isLocked(String shortname); /** * Returns the latest resources ,ordered by last modified date. * * @param startPage start page * @param pageSize page size * * @return list of resources, or an empty list if none were found */ List<Resource> latest(int startPage, int pageSize); /** * list all resources in the IPT. * * @return list of resources, or an empty list if none were found */ List<Resource> list(); /** * list all resources in the IPT having a certain publication status. * * @param status PublicationStatus * * @return list of resources, or an empty list if none were found */ List<Resource> list(PublicationStatus status); /** * List all resources in the IPT whose last published version was public (at the time of publication). This * is used to populate the list of resources publicly shown on the IPT home page. * </br> * If a resource is registered with GBIF, it is assumed the resource is public and therefore is included in the list. * Please note only resource published using IPT v2.2 or later store a VersionHistory. * * @return list of resources, or an empty list if none were found */ List<Resource> listPublishedPublicVersions(); /** * list all resource that can be managed by a given user. * * @param user User * * @return list of resources, or an empty list if none were found */ List<Resource> list(User user); /** * Load all configured resources from the data directory into memory. * We do not keep the EML or mapping configuration in memory for all resources, but we * maintain a map of the basic metadata and authorisation information in this manager. * * @param resourcesDir resources directory (inside data directory) * @param creator User that created resource (only used to populate creator when missing) * @return number of configured resources loaded into memory */ int load(File resourcesDir, @Nullable User creator); /** * Publishes a new version of a resource including generating a darwin core archive and issuing a new EML version. * * @param resource Resource * @param version version number of eml/rft/archive to be published * @param action the action to use for logging messages to * * @return true if a new asynchronous DwC-A generation job has been issued which requires some mapped data * * @throws PublicationException if resource was already registered * @throws InvalidConfigException if resource or metadata could not be saved */ boolean publish(Resource resource, BigDecimal version, @Nullable BaseAction action) throws PublicationException; /** * Registers the resource with the GBIF Registry. Instead of registering a new resource, the resource can instead * update an existing registered resource if a UUID corresponding to an existing registered resource (owned by the * specified organization) is found in the resource's alternate identifiers list. * * @param resource the published resource * @param organisation the organization that owns the resource * @param ipt the ipt that the resource will be published through * @param action Action used to show log messages on UI */ void register(Resource resource, Organisation organisation, Ipt ipt, BaseAction action) throws InvalidConfigException; /** * Persists the whole resource configuration *but* not the EML file. * * @param resource Resource */ void save(Resource resource) throws InvalidConfigException; /** * Save the eml file of a resource only. Complementary method to @See save(Resource). * * @param resource Resource */ void saveEml(Resource resource) throws InvalidConfigException; /** * Return status report of current task either running or on queue for the requested resource or null if none exists. * * @param shortname for the resource * * @return status report of current task either running or on queue for the requested resource or null if none exists */ @Nullable StatusReport status(String shortname); /** * Update the registration of the resource with the GBIF Registry. This is always done as part of a resource * publication. * * @param resource the published resource * @param action the action to use for logging messages * * @throws PublicationException (TYPE.REGISTRY) if update was unsuccessful */ void updateRegistration(Resource resource, BaseAction action) throws PublicationException; /** * Makes a resource private. * * @param resource Resource * @param action the action to use for logging messages * * @throws InvalidConfigException if resource was already registered */ void visibilityToPrivate(Resource resource, BaseAction action) throws InvalidConfigException; /** * Makes a resource public. * * @param resource Resource * @param action the action to use for logging messages * * @throws InvalidConfigException if resource was already registered */ void visibilityToPublic(Resource resource, BaseAction action) throws InvalidConfigException; /** * This method rolls back a pending version (a version being published that can't finish successfully). This method * must be called when publication fails, for whatever reason. * </br> * This method deletes the pending version's DwC-A, RTF, and EML files. * </br> * This method then restores the resource (version) back to the last successfully published version. This includes * updating the resource's version history, last publication date, version, etc. * * @param resource resource * @param rollingBack version to rollback * @param action action */ void restoreVersion(Resource resource, BigDecimal rollingBack, @Nullable BaseAction action); /** * Turn resource publicationMode to OFF. * * @param resource resource */ void publicationModeToOff(Resource resource); /** * Updates the resource's alternative identifier for the IPT URL to the resource, and saves the EML afterward. * This identifier should only exist for the resource, if its visibility is public. * If the resource visibility is set to private, this method should be called to ensure the identifier is removed. * Any time the baseURL changes, this method must be called for all public resources so that this identifier * will be updated. This method will remove an IPT URL identifier with the wrong baseURL by matching the * RESOURCE_PUBLIC_LINK_PART, updating it with one having the latest baseURL. * * @param resource resource * * @return resource with the IPT URL alternate identifier for the resource updated */ Resource updateAlternateIdentifierForIPTURLToResource(Resource resource); /* * Return the ThreadPoolExecutor. * * @return the ThreadPoolExecutor */ ThreadPoolExecutor getExecutor(); /** * Return the Futures map, representing all publishing jobs that have been fired. * * @return the Futures map */ Map<String, Future<Map<String, Integer>>> getProcessFutures(); /** * Return the failures map, representing all publishing jobs that have failed. * </br> * This map can be queried, to find out which resources have failed publishing jobs. * </br> * Auto-publication for a resource halts, if there have been 3 failed publish events. A successful publish event run * manually, is needed to clear the failed publish events for the resource. * * @return map of resource name (key) to List of Date when publishing job failed */ ListMultimap<String, Date> getProcessFailures(); /** * Check if the maximum number of publish event failures has occurred for a resource. * * @param resource resource * * @return true if publication has failed the maximum allowed times for a given resource */ boolean hasMaxProcessFailures(Resource resource); }