/**
 * JBoss, Home of Professional Open Source.
 * Copyright 2014-2020 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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 org.jboss.pnc.common.concurrent;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Sequence {

    private static final Map<Integer, SequenceGenerator> instance = new ConcurrentHashMap<>();
    private static final int INSTANCE_KEY = 0;

    public static Long nextId() {
        SequenceGenerator sequenceGenerator = instance.computeIfAbsent(INSTANCE_KEY, k -> new SequenceGenerator());
        return sequenceGenerator.nextId();
    }
}

/**
 * JBoss, Home of Professional Open Source.
 * Copyright 2014-2020 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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 org.jboss.pnc.common.concurrent;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A class for generating 64-bit unique IDs at high scale. The IDs generated by this service are roughly time sortable.
 *
 * The ID generation follows Twitter snowflake pattern and the IDs are made up of the following components:
 *
 * Epoch timestamp in millisecond precision - 41 bits (gives us 69 years with a custom epoch) Configured machine id - 10
 * bits (gives us up to 1024 machines) Sequence number - 12 bits (A local counter per machine that rolls over every
 * 4096)
 */
public class Sequence {

    private static final Map<Integer, Sequence> instance = new ConcurrentHashMap<>(1, 1.0f);
    private static final int INSTANCE_KEY = 0;

    /**
     * If nodeId is used, it can be set only once and have to be set before the first nextId() call. If nodeId is not
     * explicitly defined it's calculated based on machines mac address.
     *
     * @param nodeId an int value between (inclusive) 0 and 1023.
     */
    public static void setNodeId(int nodeId) {
        getInstance(nodeId);
    }

    public static Long nextId() {
        return getInstance(null).sequenceGenerator.nextId();
    }

    private static Sequence getInstance(Integer nodeId) {
        return instance.computeIfAbsent(INSTANCE_KEY, k -> new Sequence(nodeId));
    }

    private SequenceGenerator sequenceGenerator;

    private Sequence(Integer nodeId) {
        if (sequenceGenerator != null && nodeId != null) {
            throw new IllegalStateException("NodeId have to be called only once and before first call to nextId().");
        }
        if (nodeId == null) {
            sequenceGenerator = new SequenceGenerator();
        } else {
            sequenceGenerator = new SequenceGenerator(nodeId);
        }
    }
}

Add an option to define nodeId for sequence generator.