001/*
002 * (C) Copyright 2018 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Luís Duarte
018 *     Florent Guillaume
019 */
020package org.nuxeo.ecm.automation.server.jaxrs.batch.handler;
021
022import static org.apache.commons.lang3.StringUtils.isEmpty;
023import static org.nuxeo.ecm.automation.server.jaxrs.batch.BatchManagerComponent.CLIENT_BATCH_ID_FLAG;
024
025import java.io.Serializable;
026import java.util.HashMap;
027import java.util.Map;
028import java.util.UUID;
029
030import org.apache.commons.logging.Log;
031import org.apache.commons.logging.LogFactory;
032import org.nuxeo.ecm.automation.server.jaxrs.batch.Batch;
033import org.nuxeo.ecm.automation.server.jaxrs.batch.BatchHandler;
034import org.nuxeo.ecm.core.api.NuxeoException;
035import org.nuxeo.ecm.core.transientstore.api.TransientStore;
036import org.nuxeo.ecm.core.transientstore.api.TransientStoreService;
037import org.nuxeo.runtime.api.Framework;
038import org.nuxeo.runtime.services.config.ConfigurationService;
039
040/**
041 * Abstract batch handler: common code.
042 *
043 * @since 10.1
044 */
045public abstract class AbstractBatchHandler implements BatchHandler {
046
047    private static final Log log = LogFactory.getLog(AbstractBatchHandler.class);
048
049    // property passed at initialization time
050    public static final String PROP_TRANSIENT_STORE_NAME = "transientStore";
051
052    /** Transient store key for the batch handler name. */
053    public static final String BATCH_HANDLER_NAME = "handler";
054
055    protected String name;
056
057    protected String transientStoreName;
058
059    @Override
060    public String getName() {
061        return name;
062    }
063
064    @Override
065    public void initialize(String name, Map<String, String> properties) {
066        this.name = name;
067        initialize(properties);
068    }
069
070    protected void initialize(Map<String, String> properties) {
071        if (isEmpty(properties.get(PROP_TRANSIENT_STORE_NAME))) {
072            throw new NuxeoException("Missing configuration property: " + PROP_TRANSIENT_STORE_NAME);
073        }
074        transientStoreName = properties.get(PROP_TRANSIENT_STORE_NAME);
075    }
076
077    @Override
078    public TransientStore getTransientStore() {
079        return Framework.getService(TransientStoreService.class).getStore(transientStoreName);
080    }
081
082    /** Gets the batch parameters, or {@code null} if the batch is not found. */
083    protected Map<String, Serializable> getBatchParameters(String batchId) {
084        TransientStore transientStore = getTransientStore();
085        Map<String, Serializable> parameters = transientStore.getParameters(batchId);
086        if (parameters == null) {
087            if (isEmpty(batchId) || !transientStore.exists(batchId)) {
088                return null;
089            }
090            parameters = new HashMap<>();
091        }
092        // check that this batch is for this handler
093        String handlerName = (String) parameters.remove(BATCH_HANDLER_NAME);
094        if (handlerName != null && !handlerName.equals(getName())) {
095            return null;
096        }
097        return parameters;
098    }
099
100    @Override
101    public Batch newBatch(String batchId) {
102        TransientStore transientStore = getTransientStore();
103        if (isEmpty(batchId)) {
104            batchId = generateBatchId();
105        } else if (!Framework.getService(ConfigurationService.class).isBooleanTrue(CLIENT_BATCH_ID_FLAG)) {
106            throw new NuxeoException(String.format(
107                    "Cannot initialize upload batch with a given id since configuration property %s is not set to true",
108                    CLIENT_BATCH_ID_FLAG));
109        }
110
111        // That's the way of storing an empty entry
112        log.debug("Initializing batch with id: " + batchId);
113        transientStore.setCompleted(batchId, false);
114        transientStore.putParameter(batchId, BATCH_HANDLER_NAME, getName());
115        Map<String, Serializable> parameters = new HashMap<>();
116        return new Batch(batchId, parameters, getName(), transientStore);
117    }
118
119    protected String generateBatchId() {
120        return "batchId-" + UUID.randomUUID();
121    }
122
123}