edu.kit.dama.rest.client.generic.KIT_DM_REST_CLIENT.java Source code

Java tutorial

Introduction

Here is the source code for edu.kit.dama.rest.client.generic.KIT_DM_REST_CLIENT.java

Source

/*
 * Copyright 2015 Karlsruhe Institute of Technology.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package edu.kit.dama.rest.client.generic;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.kit.dama.client.exception.BaseMetadataException;
import edu.kit.jcommander.generic.status.CommandStatus;
import edu.kit.jcommander.generic.status.Status;
import edu.kit.lsdf.adalapi.AbstractFile;
import edu.kit.dama.mdm.admin.UserGroup;
import edu.kit.dama.mdm.base.DigitalObject;
import edu.kit.dama.mdm.base.Investigation;
import edu.kit.dama.mdm.base.Study;
import edu.kit.dama.mdm.base.UserData;
import edu.kit.dama.rest.SimpleRESTContext;
import edu.kit.dama.rest.client.generic.helper.CustomOutputObject;
import edu.kit.dama.rest.client.generic.helper.RESTClientHelper;
import edu.kit.dama.staging.entities.download.DOWNLOAD_STATUS;
import edu.kit.dama.staging.entities.download.DownloadInformation;
import edu.kit.dama.staging.entities.ingest.INGEST_STATUS;
import edu.kit.dama.staging.entities.ingest.IngestInformation;
import org.apache.commons.lang.time.DateUtils;

/**
 * This is the generic client which will perform various operations such as 1.
 * Create base metadata i.e. Base metadata for Study Investigation and
 * DigitalObject 2. Perform DataIngest in KIT DM 3. Get List of all IngestedData
 * from KITDM 4. Perform Download of data specified by the digital object ID
 *
 * @author kb3353
 *
 */
public final class KIT_DM_REST_CLIENT {

    /**
     * Logger for debug messages.
     */
    static final Logger LOGGER = LoggerFactory.getLogger(KIT_DM_REST_CLIENT.class);
    /**
     * Number of trials before skip upload.
     */
    static final int NO_OF_TRIALS = 3;
    /**
     * Wait time in seconds before retry failed transfer.
     */
    static final int RETRY_DELAY_IN_SECONDS = 10;
    /**
     * Instance accessing REST services on a higher level.
     */
    private static RESTClientHelper clientHelper;

    /**
     * Initialize the REST client.
     * <b>This method has to be called first!</b>
     *
     * @param restContext AAI context for the REST services.
     * @param baseURL Base URL of the KIT DataManager.
     */
    public static void initialize(SimpleRESTContext restContext, String baseURL) {
        clientHelper = new RESTClientHelper(restContext, baseURL);
    }

    /**
     * This is a Utility Class and hence does not require any public constructor
     *
     */
    private KIT_DM_REST_CLIENT() {

    }

    /**
     * This method can be used to create the base metadata for the data which you
     * wish to ingest/upload. The method will create the base metadata for Study,
     * Investigation and Digital Data.
     *
     * @param defaultStudy The default study metadata
     * @param defaultInvestigation The default investigation metadata
     * @param digitalObject The default digital object metadata
     * @param group the group under which the basemetadata will be created for
     * e.g. eCodicology_group or NANOSCOPY_GROUP
     *
     * @return CommandStatus or OperationStatus
     */
    public static CommandStatus createBaseMetaData(Study defaultStudy, Investigation defaultInvestigation,
            DigitalObject digitalObject, String group) {
        LOGGER.debug(
                "Creating base metadata for study: '{}'\ninvestigation: '{}'\ndigital data '{}' for group '{}'",
                defaultStudy.getTopic(), defaultInvestigation.getTopic(), digitalObject.getLabel(), group);

        CommandStatus status = null;

        // Check user validity
        UserGroup nanoscoypGroupID = clientHelper.getSpecificGroupID(group);

        if (nanoscoypGroupID.getGroupId() == null) {
            String message = "Unable to create the study as following group: " + group + " does not exists";
            LOGGER.error(message);
            status = new CommandStatus(Status.FAILED, new BaseMetadataException(message), defaultStudy);
            return status;
        }
        Study nanoscopyStudy = clientHelper.createStudy(nanoscoypGroupID.getGroupId(), defaultStudy);

        Investigation nanoscopyInvestigation = clientHelper.createInvestigation(group, nanoscopyStudy,
                defaultInvestigation);
        if (nanoscopyInvestigation == null) {
            String message = "Unable to create the investigation: " + defaultInvestigation.getTopic();
            LOGGER.error(message);
            status = new CommandStatus(Status.FAILED, new BaseMetadataException(message), defaultInvestigation);
            return status;
        }
        DigitalObject nanoscopyDigitalObject;
        try {
            nanoscopyDigitalObject = clientHelper.createNanoscopyDigitalObject(group,
                    nanoscopyInvestigation.getInvestigationId(), digitalObject);
        } catch (Exception ex) {
            String message = "Unable to add the digital object: " + digitalObject.getLabel()
                    + " to the investigation: " + defaultInvestigation.getTopic();
            LOGGER.error(message + ex);
            status = new CommandStatus(Status.FAILED, new BaseMetadataException(message + ex), digitalObject);
            return status;
        }

        status = new CommandStatus(Status.SUCCESSFUL, null, nanoscopyDigitalObject);
        return status;
    }

    /**
     * This method can be used to list the already ingested and available digital
     * data from the KIT DM.
     * <b>Attention:</b> If there are more than 10 entries only the last 10
     * entries are listed.
     *
     * @param group specifying under which the ingested metadata will be searched
     * @return CommandStatus
     */
    public static CommandStatus listContent(String group) {

        LOGGER.debug("Generating list of available data for group: " + group);

        List<IngestInformation> listEntries = clientHelper.getIngestInformationIDs(100,
                INGEST_STATUS.INGEST_FINISHED.getId());
        CommandStatus status = new CommandStatus(Status.SUCCESSFUL);

        // Get all IngestID
        // Get all Information for 'maxEntries' IDs
        int maxEntries = 10;
        int startIndex = 0;
        int noOfEntries = listEntries.size();

        List<IngestInformation> subList;
        if (noOfEntries < maxEntries) {
            subList = listEntries.subList(startIndex, noOfEntries);
        } else {
            // If more than 'maxEntries' the show only the last 'maxEntries'
            startIndex = noOfEntries - maxEntries;
            subList = listEntries.subList(startIndex, noOfEntries);
        }
        List<IngestInformation> ingestInformation = clientHelper.getIngestInformation(subList);
        // Get Detailed Information for each DigitalObject
        List<DigitalObject> digitalObjectInformationById = clientHelper.getDigitalObjectInformationById(group,
                ingestInformation);
        List<CustomOutputObject> customObjectsList = new ArrayList<>();

        for (DigitalObject digitalObject : digitalObjectInformationById) {
            UserData specificUser = clientHelper.getSpecificUser(digitalObject.getUploader().getUserId());
            CustomOutputObject customObject = new CustomOutputObject.CustomOutputObjectBuilder(specificUser,
                    digitalObject).build();
            customObjectsList.add(customObject);
        }
        status.setReturnObject(customObjectsList);

        return status;
    }

    /**
     * This method can be used to upload/ingest the data into the KIT Data
     * Manager. The data will be transfered to KIT Data Manger via the WebDav
     * protocol using ADALAPI AbstractFile
     *
     * @param digitalObjectID The data identified by the digital object which will
     * be downloaded
     * @param accessMethod The accessmethod is the protocol that will be used to
     * perform download for e.g. WebDav
     * @param dataSource The directory on the local machine the data will ingested
     * from.
     * @return CommandStatus or OperationStatus
     * @throws FileNotFoundException will be thrown if the dataSource is not a
     * valid File or Directory
     */
    public static CommandStatus performDataIngest(String digitalObjectID, String accessMethod, File dataSource)
            throws FileNotFoundException {
        return performDataIngest(digitalObjectID, accessMethod, dataSource, null);
    }

    /**
     * This method can be used to upload/ingest the data into the KIT Data
     * Manager. The data will be transfered to KIT Data Manger via the WebDav
     * protocol using ADALAPI AbstractFile
     *
     * @param digitalObjectID The data identified by the digital object which will
     * be downloaded
     * @param accessMethod The accessmethod is the protocol that will be used to
     * perform download for e.g. WebDav
     * @param dataSource The directory on the local machine the data will ingested
     * from.
     * @param groupId The group the digital object belongs to.
     * @return CommandStatus or OperationStatus
     * @throws FileNotFoundException will be thrown if the dataSource is not a
     * valid File or Directory
     */
    public static CommandStatus performDataIngest(String digitalObjectID, String accessMethod, File dataSource,
            String groupId) throws FileNotFoundException {

        LOGGER.debug("Performing data ingest for digital object identified by: " + digitalObjectID
                + " from data source at path: " + dataSource.getAbsolutePath());

        if (!(dataSource.isFile()) && (!dataSource.isDirectory())) {
            LOGGER.error("Incorrect data source", new FileNotFoundException(dataSource.getAbsolutePath()));
        }
        CommandStatus status = new CommandStatus(Status.FAILED);

        IngestInformation createdIngestEntity = clientHelper.createIngestEntity(digitalObjectID, accessMethod,
                groupId);
        LOGGER.debug("Created ingest entity in database for digital data: " + digitalObjectID);
        IngestInformation ingestInformation = clientHelper
                .getSpecifiedIngestInformation(createdIngestEntity.getId());

        if (ingestInformation.getStatus() == INGEST_STATUS.PRE_INGEST_SCHEDULED.getId()) {
            int index = 0;
            while (index < NO_OF_TRIALS) {
                status = clientHelper.performIngestADALAPI(dataSource, ingestInformation);
                if (status.getStatus().isSuccess()) {
                    break;
                }
                index++;
                LOGGER.warn(
                        "Try #{}: Ingest failed for digital object identified by: '{}' from data source at path: '{}'",
                        index, digitalObjectID, dataSource.getAbsolutePath());

                //wait retry delay
                try {
                    Thread.sleep(RETRY_DELAY_IN_SECONDS * DateUtils.MILLIS_PER_SECOND);
                } catch (InterruptedException ie) {
                }
            }
        }
        return status;
    }

    /**
     * This method can be used to upload/ingest the data into the KIT Data
     * Manager. The data will be transfered to KIT Data Manger via the WebDav
     * protocol using Data Transfer Client
     *
     * @param digitalObjectID The data identified by the digital object which will
     * be downloaded
     * @param accessMethod The accessmethod is the protocol that will be used to
     * perform download for e.g. WebDav
     * @param dataSource The directory on the local machine the data will ingested
     * from.
     * @return CommandStatus object containing the result if the transfer was
     * successful or not
     * @throws FileNotFoundException will be thrown if the dataSource is not a
     * valid File or Directory
     */
    public static CommandStatus performDataIngestTransferClient(String digitalObjectID, String accessMethod,
            File dataSource) throws FileNotFoundException {
        return performDataIngestTransferClient(digitalObjectID, accessMethod, dataSource, null);
    }

    /**
     * This method can be used to upload/ingest the data into the KIT Data
     * Manager. The data will be transfered to KIT Data Manger via the WebDav
     * protocol using Data Transfer Client
     *
     * @param digitalObjectID The data identified by the digital object which will
     * be downloaded
     * @param accessMethod The accessmethod is the protocol that will be used to
     * perform download for e.g. WebDav
     * @param dataSource The directory on the local machine the data will ingested
     * from.
     * @param groupId The groupID the digital object belongs to.
     * @return CommandStatus object containing the result if the transfer was
     * successful or not
     * @throws FileNotFoundException will be thrown if the dataSource is not a
     * valid File or Directory
     */
    public static CommandStatus performDataIngestTransferClient(String digitalObjectID, String accessMethod,
            File dataSource, String groupId) throws FileNotFoundException {

        LOGGER.debug("Performing data ingest for digital object identified by: " + digitalObjectID
                + " from data source at path: " + dataSource.getAbsolutePath());
        LOGGER.debug("User group: " + groupId);

        if (!(dataSource.isFile()) && (!dataSource.isDirectory())) {
            LOGGER.error("Incorrect data source", new FileNotFoundException(dataSource.getAbsolutePath()));
        }
        CommandStatus status = new CommandStatus(Status.FAILED);

        IngestInformation createdIngestEntity = clientHelper.createIngestEntity(digitalObjectID, accessMethod,
                groupId);
        LOGGER.debug("Created ingest entity in database for digital data: " + digitalObjectID);
        IngestInformation ingestInformation = clientHelper
                .getSpecifiedIngestInformation(createdIngestEntity.getId());

        if (ingestInformation.getStatus() == INGEST_STATUS.PRE_INGEST_SCHEDULED.getId()) {
            status = clientHelper.performIngestDataTransferClient(dataSource, ingestInformation);
        }
        return status;
    }

    /**
     * This method can be used to download the actual digital data onto your local
     * machine using ADALAPI The method uses WebDav protocol to download the data.
     *
     * @param accessMethod The accessmethod is the protocol that will be used to
     * perform download for e.g. WebDav
     * @param digitalObjectID The data identified by the digital object which will
     * be downloaded
     * @param destination The directory on the local machine where the data will
     * be downloaded
     *
     * @return CommandStatus Status of the command (success or failed).
     * @throws FileNotFoundException will be thrown if the destination is not a
     * valid directory
     */
    public static CommandStatus performDataDownload(String accessMethod, String digitalObjectID, File destination)
            throws FileNotFoundException {
        return performDataDownload(accessMethod, digitalObjectID, destination, null);
    }

    /**
     * This method can be used to download the actual digital data onto your local
     * machine using ADALAPI The method uses WebDav protocol to download the data.
     *
     * @param accessMethod The accessmethod is the protocol that will be used to
     * perform download for e.g. WebDav
     * @param digitalObjectID The data identified by the digital object which will
     * be downloaded
     * @param destination The directory on the local machine where the data will
     * be downloaded
     * @param groupId The groupID the digital object belongs to.
     *
     * @return CommandStatus Status of the command (success or failed).
     * @throws FileNotFoundException will be thrown if the destination is not a
     * valid directory
     */
    public static CommandStatus performDataDownload(String accessMethod, String digitalObjectID, File destination,
            String groupId) throws FileNotFoundException {
        LOGGER.debug("Performing data download for digital object identified by: " + digitalObjectID
                + " to data destination at path: " + destination.getAbsolutePath());
        LOGGER.debug("User group: " + groupId);

        if (!destination.isDirectory()) {
            LOGGER.error("Invalid directory: " + destination.getAbsolutePath());
            throw new FileNotFoundException(destination.getAbsolutePath());
        }

        CommandStatus commandStatus = new CommandStatus(Status.FAILED);
        LOGGER.debug("Creating download entity in database for digital data: " + digitalObjectID);
        DownloadInformation createdDownload = clientHelper.createDownloadEntity(digitalObjectID, accessMethod,
                groupId);

        if (createdDownload == null) {
            LOGGER.error("ERROR Unable to create download entity for digital data: " + digitalObjectID);
            return commandStatus;
        }

        int status = clientHelper.checkDownloadStatus(createdDownload.getId());

        if (status == DOWNLOAD_STATUS.DOWNLOAD_READY.getId()) {
            DownloadInformation dataToDownload = clientHelper.getDownloadInformation(createdDownload.getId());
            if (dataToDownload != null) {
                LOGGER.debug("Starting download for requested digital data: " + digitalObjectID);
                AbstractFile downloadedContent = clientHelper.performDataDownloadADALAPI(accessMethod,
                        dataToDownload, destination);
                commandStatus.setReturnObject(downloadedContent);
                commandStatus.setStatusCode(Status.SUCCESSFUL);
            }
        }
        return commandStatus;
    }

    /**
     * This method can be used to download the actual digital data onto your local
     * machine using Data Transfer Client The method uses WebDav protocol to
     * download the data.
     *
     * @param accessMethod The accessmethod is the protocol that will be used to
     * perform download for e.g. WebDav
     * @param digitalObjectID The data identified by the digital object which will
     * be downloaded
     * @param localDestination The directory on the local machine where the data
     * will be downloaded
     *
     * @return CommandStatus
     * @throws FileNotFoundException will be thrown if the destination is not a
     * valid directory
     */
    public static CommandStatus performDataDownloadDataTransferClient(String accessMethod, String digitalObjectID,
            File localDestination) throws FileNotFoundException {
        return performDataDownloadDataTransferClient(accessMethod, digitalObjectID, localDestination, null);
    }

    /**
     * This method can be used to download the actual digital data onto your local
     * machine using Data Transfer Client The method uses WebDav protocol to
     * download the data.
     *
     * @param accessMethod The accessmethod is the protocol that will be used to
     * perform download for e.g. WebDav
     * @param digitalObjectID The data identified by the digital object which will
     * be downloaded
     * @param localDestination The directory on the local machine where the data
     * will be downloaded
     * @param groupId The groupID the digital object belongs to.
     *
     * @return CommandStatus
     * @throws FileNotFoundException will be thrown if the destination is not a
     * valid directory
     */
    public static CommandStatus performDataDownloadDataTransferClient(String accessMethod, String digitalObjectID,
            File localDestination, String groupId) throws FileNotFoundException {

        LOGGER.debug("Performing data download for digital object identified by: " + digitalObjectID
                + " to data destination at path: " + localDestination.getAbsolutePath());
        LOGGER.debug("User group: " + groupId);
        if (!localDestination.isDirectory()) {
            LOGGER.error("Invalid directory: " + localDestination.getAbsolutePath());
            throw new FileNotFoundException(localDestination.getAbsolutePath());
        }

        CommandStatus commandStatus = new CommandStatus(Status.FAILED);
        LOGGER.debug("Creating download entity in database for digital data: " + digitalObjectID);
        DownloadInformation createdDownload = clientHelper.createDownloadEntity(digitalObjectID, accessMethod,
                groupId);

        if (createdDownload == null) {
            LOGGER.error("ERROR Unable to create download entity for digital data: " + digitalObjectID);
            return commandStatus;
        }

        int status = clientHelper.checkDownloadStatus(createdDownload.getId());

        if (status == DOWNLOAD_STATUS.DOWNLOAD_READY.getId()) {
            DownloadInformation dataToDownload = clientHelper.getDownloadInformation(createdDownload.getId());
            if (dataToDownload != null) {
                LOGGER.debug("Starting download for requested digital data: " + digitalObjectID);
                AbstractFile downloadedContent = clientHelper.performDataDownloadDataTransferClient(accessMethod,
                        dataToDownload, localDestination);
                commandStatus.setReturnObject(downloadedContent);
                commandStatus.setStatusCode(Status.SUCCESSFUL);
            }
        }
        return commandStatus;
    }

}