All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.duracloud.snapshot.service.impl.ContentPropertiesWriter Maven / Gradle / Ivy

There is a newer version: 4.0.0
Show newest version
/*
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 *
 *     http://duracloud.org/license/
 */
package org.duracloud.snapshot.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.duracloud.chunk.manifest.ChunksManifest;
import org.duracloud.client.ContentStore;
import org.duracloud.common.retry.Retriable;
import org.duracloud.common.retry.Retrier;
import org.duracloud.error.ContentStoreException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.ItemWriteListener;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.item.ItemWriter;

/**
 * @author Daniel Bernstein 
 *         Date: Aug 22, 2014
 */
public class ContentPropertiesWriter extends StepExecutionSupport
    implements ItemWriter, ItemWriteListener {
    private static Logger log = LoggerFactory.getLogger(ContentPropertiesWriter.class);
    private String destinationSpaceId;
    private ContentStore contentStore;
    private String storeId;
    private String storageProviderType;

    /**
     * @param contentStore
     * @param destinationSpaceId
     */
    public ContentPropertiesWriter(ContentStore contentStore, String destinationSpaceId) {
        this.contentStore = contentStore;
        this.destinationSpaceId = destinationSpaceId;
        this.storeId = contentStore.getStoreId();
        this.storageProviderType = contentStore.getStorageProviderType();
        log.debug("constructed ContentPropertiesWriter for destination spaceId ({}), " + "storeId ({}), storeType({})",
                  destinationSpaceId,
                  storeId,
                  storageProviderType);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.batch.core.StepExecutionListener#afterStep(org.
     * springframework.batch.core.StepExecution)
     */
    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        ExitStatus status = stepExecution.getExitStatus();
        List errors = getErrors();
        if (errors.size() > 0) {
            status = status.and(ExitStatus.FAILED);

            for (String error : errors) {
                status = status.addExitDescription(error);
            }

            failExecution();
            resetContextState();
            
            log.error("content properties step finished with errors: step_execution_id={} "
                + "job_execution_id={} store_id={} status=\"{}\"",
                      stepExecution.getId(),
                      stepExecution.getJobExecutionId(),
                      contentStore.getStoreId(),
                      status);
        } else {

            status = status.and(ExitStatus.COMPLETED);
            log.info("content properties step finished: step_execution_id={} "
                + "job_execution_id={} store_id={}  exit_status={} ",
                     stepExecution.getId(),
                     stepExecution.getJobExecutionId(),
                     contentStore.getStoreId(),
                     status);
        }

        return status;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.springframework.batch.core.ItemWriteListener#afterWrite(java.util
     * .List)
     */
    @Override
    public void afterWrite(List items) {
        addToItemsRead(items.size());
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.springframework.batch.core.ItemWriteListener#beforeWrite(java.util
     * .List)
     */
    @Override
    public void beforeWrite(List items) {
        log.debug("firing beforeWrite {}", items);

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.springframework.batch.core.ItemWriteListener#onWriteError(java.lang
     * .Exception, java.util.List)
     */
    @Override
    public void onWriteError(Exception exception, List items) {
        log.error("firing onWriteError: currrently not handling: exception message=" + exception.getMessage(),
                  exception);
        for (ContentProperties props : items) {
            addError("item failed: " + props + "; exception="+exception.getMessage());
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.batch.item.ItemWriter#write(java.util.List)
     */
    @Override
    public void write(List items) throws Exception {
        for (final ContentProperties props : items) {
            new Retrier().execute(new Retriable() {

                @Override
                public Object retry() throws Exception {
                    try {
                    contentStore.setContentProperties(destinationSpaceId, props.getContentId(), props.getProperties());
                    log.debug("wrote content properties ({}) to space ({}) on store ({}/{}):",
                              props,
                              destinationSpaceId,
                              storeId,
                              storageProviderType);
                    return null;
                    }catch(ContentStoreException ex){
                        log.warn("failed to update content properties ({}) to space({}); on store({}/{}). Trying with chunk manifest extension.",
                                 props,
                                 destinationSpaceId,
                                 storeId,
                                 storageProviderType);

                        //make sure the chunk manifest's properties are layed on top of the stitched file 
                        //properties to ensure that mutable "system-ish" properties such as content type are not
                        //overwritten.
                        String manifestId = props.getContentId() + ChunksManifest.manifestSuffix;
                        Map properties = new HashMap<>(props.getProperties());
                        Map chunkManifestProperties =
                            contentStore.getContentProperties(destinationSpaceId, manifestId);
                        properties.putAll(chunkManifestProperties);
                        contentStore.setContentProperties(destinationSpaceId,
                                                          manifestId,
                                                          properties);                        
                        return null;
                    }
                }
            });
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy