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

com.axway.ats.log.autodb.LoadQueuesState Maven / Gradle / Ivy

/*
 * Copyright 2017 Axway Software
 * 
 * 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 com.axway.ats.log.autodb;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import com.axway.ats.log.autodb.exceptions.CheckpointAlreadyStartedException;
import com.axway.ats.log.autodb.exceptions.CheckpointNotStartedException;
import com.axway.ats.log.autodb.exceptions.LoadQueueAlreadyStartedException;
import com.axway.ats.log.autodb.exceptions.NoSuchLoadQueueException;
import com.axway.ats.log.autodb.exceptions.ThreadAlreadyRegisteredWithLoadQueueException;
import com.axway.ats.log.autodb.exceptions.ThreadNotRegisteredWithLoadQueue;

/**
 * Keeps queue info as names and DB IDs, 
 * associating running threads and checkpoints running for each thread.
 */
public class LoadQueuesState {

    /**
     * This map holds the IDs of all started queues:
     *     Map
     */
    private Map             queueNamesToDbIds;

    /**
     * Each thread must first be registered with a queue if a checkpoint
     * is to be started.
     *
     * This map keeps all threads per queue:
     *     Map>
     */
    private Map>       threadsPerQueue;

    /**
     * This map keeps current checkpoints per thread. Several started at particular moment are supported.
     * This allows to keep track of nested or interweaving tasks/checkpoints.
     *     Map
     */
    private Map> checkpointsPerThread;

    /**
     * Constructor
     */
    public LoadQueuesState() {

        //use tree maps for better performance when searching
        this.queueNamesToDbIds = new TreeMap();
        this.threadsPerQueue = new TreeMap>();
        this.checkpointsPerThread = new HashMap>();
    }

    /**
     * Add a load queue to the currently executed load queues
     *
     * @param name name of the load queue
     * @param dbId the load queue id
     * @throws LoadQueueAlreadyStartedException if the load queue has already been added
     */
    public synchronized void addLoadQueue( String name, int dbId ) throws LoadQueueAlreadyStartedException {

        if( queueNamesToDbIds.containsKey( name ) ) {
            throw new LoadQueueAlreadyStartedException( name );
        }

        queueNamesToDbIds.put( name, dbId );
        threadsPerQueue.put( dbId, new ArrayList() );
    }

    /**
     * Remove the load queue from the list of active load queues
     *
     * @param name name of the load queue
     * @param id the load queue id
     * @throws NoSuchLoadQueueException if such load queue has not been started
     */
    public synchronized void removeLoadQueue( String name, int id ) throws NoSuchLoadQueueException {

        if( !queueNamesToDbIds.containsKey( name ) ) {
            throw new NoSuchLoadQueueException( name );
        }

        queueNamesToDbIds.remove( name );
        threadsPerQueue.remove( id );
    }

    /**
     * Check if a load queue with the given name is in the list of active load queues
     *
     * @param name name of the load queue
     * @return true if this load queue is in the list
     */
    public synchronized boolean isLoadQueueRunning( String name ) {

        return queueNamesToDbIds.containsKey( name );
    }

    /**
     * Register the given thread with a load queue. All checkpoints coming from this
     * thread will be assigned to the specified load queue
     *
     * @param threadName name of the thread to register
     * @param loadQueueId the load queue id
     * @throws NoSuchLoadQueueException if such load queue has not been started
     * @throws ThreadAlreadyRegisteredWithLoadQueueException if this thread has already been registered
     */
    public synchronized void registerThreadWithLoadQueue( String threadName,
                                                          int loadQueueId ) throws NoSuchLoadQueueException,
                                                                            ThreadAlreadyRegisteredWithLoadQueueException {

        List threadNames = threadsPerQueue.get( loadQueueId );
        if( threadNames == null ) {
            throw new NoSuchLoadQueueException( loadQueueId );
        }

        if( threadNames.contains( threadName ) ) {
            throw new ThreadAlreadyRegisteredWithLoadQueueException( threadName );
        }

        threadNames.add( threadName );
        clearThreadAllCheckpoints( threadName );
    }

    /**
     * Return the id of the load queue with the specified name
     *
     * @param loadQueueName the name of the load queue to look for
     * @return the load queue id
     * @throws NoSuchLoadQueueException if such load queue has not been started
     */
    public synchronized int getLoadQueueId( String loadQueueName ) throws NoSuchLoadQueueException {

        if( !queueNamesToDbIds.containsKey( loadQueueName ) ) {
            throw new NoSuchLoadQueueException( loadQueueName );
        }

        return queueNamesToDbIds.get( loadQueueName );
    }

    /**
     * Return the id of the load queue which this thread is assigned to
     * @param threadName this thread name
     * @return
     * @throws ThreadNotRegisteredWithLoadQueue
     */
    public synchronized int getLoadQueueIdForThread( String threadName ) throws ThreadNotRegisteredWithLoadQueue {

        for( Entry> loadQueueEntry : threadsPerQueue.entrySet() ) {
            List threads = loadQueueEntry.getValue();
            for( String thread : threads ) {
                if( thread.equals( threadName ) ) {
                    return loadQueueEntry.getKey();
                }
            }
        }

        throw new ThreadNotRegisteredWithLoadQueue( threadName );
    }

    /**
     * Start a checkpoint
     *
     * @param startedCheckpointInfo info about this checkpoint. It is expected to already be persisted in the DB
     * @param threadName name of the thread which start the checkpoint
     * @param startTime the time at which this checkpoint started
     * @throws ThreadNotRegisteredWithLoadQueue if the thread which tries to start the checkpoint
     * is not registered with the checkpoint
     * @throws CheckpointAlreadyStartedException if the checkpoint has been started in this thread already
     */
    public synchronized void startCheckpoint( CheckpointInfo startedCheckpointInfo,
                                              String threadName ) throws ThreadNotRegisteredWithLoadQueue,
                                                                  CheckpointAlreadyStartedException {

        Set currentCheckpointInfoSet = checkpointsPerThread.get( threadName );
        if( currentCheckpointInfoSet == null ) {
            throw new ThreadNotRegisteredWithLoadQueue( threadName );
        }
        CheckpointInfo checkpointInfoWithThisName = null;
        for( CheckpointInfo checkpointInfo : currentCheckpointInfoSet ) {
            if( checkpointInfo.getName().equals( startedCheckpointInfo.getName() ) ) {
                checkpointInfoWithThisName = checkpointInfo;
                break;
            }
        }

        if( checkpointInfoWithThisName != null && checkpointInfoWithThisName.isRunning() ) {
            throw new CheckpointAlreadyStartedException( startedCheckpointInfo.getName(), threadName );
        }

        registerCheckpointWithThread( threadName, startedCheckpointInfo );
    }

    /**
     * End a checkpoint
     *
     * @param threadName name of the thread which ends the checkpoint
     * @param checkpointName the name of the checkpoint
     * @param endTime the time at which this checkpoint ended
     * @throws ThreadNotRegisteredWithLoadQueue if the thread which tries to end the checkpoint
     * is not registered with the checkpoint
     * @throws CheckpointNotStartedException if the checkpoint has not been started at all
     */
    public synchronized CheckpointInfo endCheckpoint( String threadName, String checkpointName,
                                                      long endTime ) throws ThreadNotRegisteredWithLoadQueue,
                                                                     CheckpointNotStartedException {

        Set currentCheckpointInfoSet = checkpointsPerThread.get( threadName );
        if( currentCheckpointInfoSet == null ) {
            throw new ThreadNotRegisteredWithLoadQueue( threadName );
        }

        Iterator iterator = currentCheckpointInfoSet.iterator();
        CheckpointInfo currentCheckpointInfo = null, tempCheckpoint = null;
        while( iterator.hasNext() && currentCheckpointInfo == null ) {
            tempCheckpoint = ( CheckpointInfo ) iterator.next();
            if( checkpointName.equals( tempCheckpoint.getName() ) ) {
                currentCheckpointInfo = tempCheckpoint;
            }
        }

        if( currentCheckpointInfo == null || !currentCheckpointInfo.isRunning() ) {
            throw new CheckpointNotStartedException( checkpointName, threadName );
        }

        // clean current checkpoint from the set associated to this thread,
        // but return this checkpoint as we need it when ending the checkpoint in the DB
        clearThreadCheckpoint( threadName, currentCheckpointInfo );

        return currentCheckpointInfo;
    }

    /**
     * Clear all load queue data
     */
    public synchronized void clearAll() {

        queueNamesToDbIds.clear();
        threadsPerQueue.clear();
        checkpointsPerThread.clear();
    }

    private void registerCheckpointWithThread( String threadName,
                                               CheckpointInfo checkpointInfo ) throws CheckpointAlreadyStartedException {

        Set set = checkpointsPerThread.get( threadName );
        if( set == null ) {
            set = new HashSet();
            checkpointsPerThread.put( threadName, set );
        }
        boolean newlyAdded = set.add( checkpointInfo );
        if( !newlyAdded ) {
            throw new CheckpointAlreadyStartedException( checkpointInfo.getName(), threadName );
        }
    }

    private void clearThreadCheckpoint( String threadName, CheckpointInfo checkpointInfoForRemove ) {

        Set set = checkpointsPerThread.get( threadName );
        set.remove( checkpointInfoForRemove );
    }

    private void clearThreadAllCheckpoints( String threadName ) {

        Set set = checkpointsPerThread.get( threadName );
        if( set != null ) {
            set.clear();
        } else { // initialize - put empty set
            set = new HashSet();
            checkpointsPerThread.put( threadName, set );
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy