001/*
002 * (C) Copyright 2018 Nuxeo (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 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.uidgen;
020
021import static org.apache.commons.lang3.StringUtils.isBlank;
022
023import org.nuxeo.ecm.core.api.NuxeoException;
024import org.nuxeo.runtime.api.Framework;
025import org.nuxeo.runtime.kv.KeyValueService;
026import org.nuxeo.runtime.kv.KeyValueStore;
027import org.nuxeo.runtime.services.config.ConfigurationService;
028
029/**
030 * UID Sequencer based on a key/value store. The store is the same for all sequencers, but they are using different
031 * keys, prefixed by the sequencer name.
032 *
033 * @since 10.2
034 */
035public class KeyValueStoreUIDSequencer extends AbstractUIDSequencer {
036
037    /**
038     * Configuration property to specify the key/value store name. If none is specified, {@code sequence} is used.
039     */
040    public static final String STORE_NAME_PROPERTY = "nuxeo.uidseq.keyvaluestore.name";
041
042    public static final String DEFAULT_STORE_NAME = "sequence";
043
044    public static final String SEP = ".";
045
046    protected String storeName;
047
048    @Override
049    public void init() {
050        storeName = Framework.getService(ConfigurationService.class).getProperty(STORE_NAME_PROPERTY);
051        if (isBlank(storeName)) {
052            storeName = DEFAULT_STORE_NAME;
053        }
054    }
055
056    @Override
057    public void dispose() {
058        // nothing to do
059    }
060
061    protected KeyValueStore getStore() {
062        KeyValueStore store = Framework.getService(KeyValueService.class).getKeyValueStore(storeName);
063        if (store == null) {
064            throw new NuxeoException("Unknown key/value store: " + storeName);
065        }
066        return store;
067    }
068
069    protected String getKey(String key) {
070        return getName() + SEP + key;
071    }
072
073    @Override
074    public void initSequence(String key, long id) {
075        getStore().put(getKey(key), Long.valueOf(id));
076    }
077
078    @Override
079    public long getNextLong(String key) {
080        return getStore().addAndGet(getKey(key), 1);
081    }
082
083}