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    protected TransientStore getTransientStore() {
078        return Framework.getService(TransientStoreService.class).getStore(transientStoreName);
079    }
080
081    /** Gets the batch parameters, or {@code null} if the batch is not found. */
082    protected Map<String, Serializable> getBatchParameters(String batchId) {
083        TransientStore transientStore = getTransientStore();
084        Map<String, Serializable> parameters = transientStore.getParameters(batchId);
085        if (parameters == null) {
086            if (isEmpty(batchId) || !transientStore.exists(batchId)) {
087                return null;
088            }
089            parameters = new HashMap<>();
090        }
091        // check that this batch is for this handler
092        String handlerName = (String) parameters.remove(BATCH_HANDLER_NAME);
093        if (handlerName != null && !handlerName.equals(getName())) {
094            return null;
095        }
096        return parameters;
097    }
098
099    @Override
100    public Batch newBatch(String batchId) {
101        TransientStore transientStore = getTransientStore();
102        if (isEmpty(batchId)) {
103            batchId = generateBatchId();
104        } else if (!Framework.getService(ConfigurationService.class).isBooleanPropertyTrue(CLIENT_BATCH_ID_FLAG)) {
105            throw new NuxeoException(String.format(
106                    "Cannot initialize upload batch with a given id since configuration property %s is not set to true",
107                    CLIENT_BATCH_ID_FLAG));
108        }
109
110        // That's the way of storing an empty entry
111        log.debug("Initializing batch with id: " + batchId);
112        transientStore.setCompleted(batchId, false);
113        transientStore.putParameter(batchId, BATCH_HANDLER_NAME, getName());
114        return new Batch(batchId);
115    }
116
117    protected String generateBatchId() {
118        return "batchId-" + UUID.randomUUID();
119    }
120
121}