org.eclipse.smila.connectivity.framework.impl.AgentControllerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.smila.connectivity.framework.impl.AgentControllerImpl.java

Source

/***********************************************************************************************************************
 * Copyright (c) 2008 empolis GmbH and brox IT Solutions GmbH. All rights reserved. This program and the accompanying
 * materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: Daniel Stucky (empolis GmbH) - initial API and implementation Sebastian Voigt (brox IT Solutions GmbH)
 **********************************************************************************************************************/
package org.eclipse.smila.connectivity.framework.impl;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.smila.connectivity.ConnectivityException;
import org.eclipse.smila.connectivity.ConnectivityId;
import org.eclipse.smila.connectivity.deltaindexing.DeltaIndexingException;
import org.eclipse.smila.connectivity.deltaindexing.DeltaIndexingSessionException;
import org.eclipse.smila.connectivity.framework.Agent;
import org.eclipse.smila.connectivity.framework.AgentController;
import org.eclipse.smila.connectivity.framework.AgentState;
import org.eclipse.smila.connectivity.framework.schema.config.DataConnectionID.DataConnectionType;
import org.eclipse.smila.connectivity.framework.schema.config.DataSourceConnectionConfig;
import org.eclipse.smila.connectivity.framework.schema.config.DeltaIndexingType;
import org.eclipse.smila.connectivity.framework.util.AgentControllerCallback;
import org.eclipse.smila.datamodel.DataFactory;
import org.eclipse.smila.datamodel.DataFactoryCreator;
import org.eclipse.smila.datamodel.Record;
import org.osgi.service.component.ComponentContext;

/**
 * Basic Implementation of a AgentController.
 */
public class AgentControllerImpl extends AbstractController implements AgentController, AgentControllerCallback {

    /** The Constant BUNDLE_ID. */
    private static final String BUNDLE_ID = "org.eclipse.smila.connectivity.framework";

    /**
     * The LOG.
     */
    private final Log _log = LogFactory.getLog(AgentControllerImpl.class);

    /**
     * The record factory.
     */
    private final DataFactory _recordFactory = DataFactoryCreator.createDefaultFactory();

    /**
     * A Map of active Agents.
     */
    private final java.util.Map<String, Agent> _activeAgents;

    /**
     * A Map of AgentStates.
     */
    private final java.util.Map<String, AgentState> _agentStates;

    /**
     * Default Constructor.
     */
    public AgentControllerImpl() {
        if (_log.isTraceEnabled()) {
            _log.trace("Creating AgentControllerImpl");
        }
        _activeAgents = new HashMap<String, Agent>();
        _agentStates = new HashMap<String, AgentState>();
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.smila.connectivity.framework.AgentController#startAgent(String)
     */
    @Override
    public int startAgent(final String dataSourceId) throws ConnectivityException {
        // check parameters
        if (dataSourceId == null) {
            final String msg = "Parameter dataSourceId is null";
            if (_log.isErrorEnabled()) {
                _log.error(msg);
            }
            throw new NullPointerException(msg);
        }

        // check if data source is already used by another agent
        if (_activeAgents.containsKey(dataSourceId)) {
            throw new ConnectivityException("Can't start a new agent for DataSourceId '" + dataSourceId
                    + "'. An agent is already started for it.");
        }

        try {
            final DataSourceConnectionConfig configuration = getConfiguration(BUNDLE_ID, dataSourceId);
            final Agent agent = createInstance(Agent.class, configuration.getDataConnectionID().getId());
            final int jobId = agent.hashCode();

            // initialize the AgentState
            final AgentState agentState = new AgentState();
            agentState.setJobId(Integer.toString(jobId));
            _agentStates.put(dataSourceId, agentState);

            String sessionId = null;
            if (doDeltaIndexing(configuration.getDeltaIndexing())) {
                sessionId = getDeltaIndexingManager().init(dataSourceId);
            }

            // start agent
            agent.start(this, agentState, configuration, sessionId);
            _activeAgents.put(dataSourceId, agent);
            return jobId;
        } catch (final ConnectivityException e) {
            throw e;
        } catch (final Exception e) {
            final String msg = "Error during start of agent using DataSourceId '" + dataSourceId + "'";
            if (_log.isErrorEnabled()) {
                _log.error(msg, e);
            }
            throw new ConnectivityException(msg, e);
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.smila.connectivity.framework.AgentController#stopAgent(String)
     */
    @Override
    public void stopAgent(final String dataSourceId) throws ConnectivityException {
        // check parameters
        if (dataSourceId == null) {
            final String msg = "Parameter dataSourceId is null";
            if (_log.isErrorEnabled()) {
                _log.error(msg);
            }
            throw new NullPointerException(msg);
        }

        final Agent agent = _activeAgents.get(dataSourceId);
        if (agent == null) {
            final String msg = "Could not stop Agent for DataSourceId '" + dataSourceId
                    + "'. No agent has been started for it.";
            if (_log.isErrorEnabled()) {
                _log.error(msg);
            }
            throw new ConnectivityException(msg);
        }
        // stop agent
        try {
            agent.stop();
        } catch (Exception e) {
            final String msg = "Error while stopping agent for DataSourceId '" + dataSourceId + "'";
            if (_log.isErrorEnabled()) {
                _log.error(msg, e);
            }
            throw new ConnectivityException(msg, e);
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.smila.connectivity.framework.AgentController#hasActiveAgents()
     */
    @Override
    public boolean hasActiveAgents() throws ConnectivityException {
        return !_activeAgents.isEmpty();
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.smila.connectivity.framework.AgentController#getAgentTasksState()
     */
    @Override
    public Map<String, AgentState> getAgentTasksState() {
        final HashMap<String, AgentState> states = new HashMap<String, AgentState>();
        states.putAll(_agentStates);
        return states;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.smila.connectivity.framework.AgentController#getAvailableAgents()
     */
    @Override
    public Collection<String> getAvailableAgents() {
        return getAvailableFactories();
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.smila.connectivity.framework.AgentController#getAvailableConfigurations()
     */
    @Override
    public Collection<String> getAvailableConfigurations() {
        return getConfigurations(BUNDLE_ID, DataConnectionType.AGENT);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.smila.connectivity.framework.util.AgentControllerCallback#add(String, DeltaIndexingType, Record,
     *      String)
     */
    @Override
    public void add(final String sessionId, final DeltaIndexingType deltaIndexingType, final Record record,
            final String hash) {
        if (record != null) {
            // set jobId as annotation on record
            JobIdHelper.setJobIdAttribute(record, _agentStates.get(record.getSource()));

            try {
                boolean isUpdate = true;
                if (doCheckForUpdate(deltaIndexingType)) {
                    isUpdate = getDeltaIndexingManager().checkForUpdate(sessionId,
                            new ConnectivityId(record.getSource(), record.getId()), hash);
                }
                if (isUpdate) {
                    // TODO: add compound management
                    final boolean isCompound = false;

                    // add record to connectivity manager
                    getConnectivityManager().add(new Record[] { record });

                    // set delta indexing visited flag
                    if (doDeltaIndexing(deltaIndexingType)) {
                        getDeltaIndexingManager().visit(sessionId,
                                new ConnectivityId(record.getSource(), record.getId()), hash, isCompound);
                    }

                    // execute delta delete for compounds only
                    if (isCompound) {
                        deleteDelta(sessionId, deltaIndexingType, record.getId());
                    }

                    // getPerformanceCounterHelper().incrementRecords();
                } // if
            } catch (final RuntimeException e) {
                // getPerformanceCounterHelper().addCriticalException(e);
                throw e;
            } catch (final Exception e) {
                // getPerformanceCounterHelper().addCriticalException(e);
                if (_log.isErrorEnabled()) {
                    final String msg = "Error while adding record '" + record.getId() + "' of source with id '"
                            + record.getSource() + "'.";
                    _log.error(msg, e);
                }
            }

        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.smila.connectivity.framework.util.AgentControllerCallback#delete(String, DeltaIndexingType, Id)
     */
    @Override
    public void delete(final String sessionId, final DeltaIndexingType deltaIndexingType, final ConnectivityId id) {
        if (id != null) {
            final String dataSourceId = id.getDataSourceId();
            try {
                // TODO: add compound management
                final Record record = _recordFactory.createRecord();
                JobIdHelper.setJobIdAttribute(record, _agentStates.get(record.getSource()));
                getConnectivityManager().delete(new Record[] { record });

                // remove entry from delta indexing
                if (doDeltaDelete(deltaIndexingType)) {
                    getDeltaIndexingManager().delete(sessionId, id);
                }

                // TODO: make sure delete also deletes elements of compounds, additional method in DIManager ?

            } catch (final RuntimeException e) {
                // getPerformanceCounterHelper().addCriticalException(e);
                throw e;
            } catch (final ConnectivityException e) {
                // getPerformanceCounterHelper().addException(e);
                if (_log.isErrorEnabled()) {
                    final String msg = "Error while deleting records for DataSourceId '" + dataSourceId + "'";
                    _log.error(msg, e);
                }
            } catch (final DeltaIndexingSessionException e) {
                // getPerformanceCounterHelper().addCriticalException(e);
                if (_log.isErrorEnabled()) {
                    final String msg = "Error while deleting records for DataSourceId '" + dataSourceId + "'";
                    _log.error(msg, e);
                }
            } catch (final DeltaIndexingException e) {
                // getPerformanceCounterHelper().addException(e);
                if (_log.isErrorEnabled()) {
                    final String msg = "Error while deleting records for DataSourceId '" + dataSourceId + "'";
                    _log.error(msg, e);
                }
            }
        } // if
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.smila.connectivity.framework.util.AgentControllerCallback#unregister(String, DeltaIndexingType,
     *      String)
     */
    @Override
    public void unregister(final String sessionId, final DeltaIndexingType deltaIndexingType,
            final String dataSourceId) {
        _activeAgents.remove(dataSourceId);

        if (doDeltaIndexing(deltaIndexingType)) {
            try {
                getDeltaIndexingManager().finish(sessionId);
            } catch (Exception e) {
                if (_log.isErrorEnabled()) {
                    final String msg = "Error finishing delta indexing for DataSourceId '" + dataSourceId + "'";
                    _log.error(msg, e);
                }
            }
        }
    }

    /**
     * Deletes all elements of a compound id of a delta indexing run that were not visited.
     * 
     * @param sessionId
     *          the delta indexing session id
     * @param deltaIndexingType
     *          the DeltaIndexingType
     * @param compoundId
     *          the id of the compound record
     * @return the number of deleted Ids
     */
    private int deleteDelta(final String sessionId, final DeltaIndexingType deltaIndexingType,
            final String compoundId) {
        int count = 0;
        if (doDeltaDelete(deltaIndexingType)) {
            try {
                final Iterator<ConnectivityId> it = getDeltaIndexingManager().obsoleteIdIterator(sessionId,
                        compoundId);
                if (it != null) {
                    while (it.hasNext()) {
                        final ConnectivityId id = it.next();
                        if (id != null) {
                            getDeltaIndexingManager().delete(sessionId, it.next());
                            count++;
                        }
                    } // while
                } // if
            } catch (final Exception e) {
                final String msg = "Error during execution of deleteDelta for compoundId " + compoundId;
                if (_log.isErrorEnabled()) {
                    _log.error(msg, e);
                }
            }
        } // if
        return count;
    }

    /**
     * DS deactivate method.
     * 
     * @param context
     *          the ComponentContext
     * 
     * @throws Exception
     *           if any error occurs
     */
    protected void deactivate(final ComponentContext context) throws Exception {
        if (_log.isInfoEnabled()) {
            _log.info("Deactivating AgentController");
        }
        _lock.writeLock().lock();
        try {
            final Iterator<Map.Entry<String, Agent>> it = _activeAgents.entrySet().iterator();
            while (it.hasNext()) {
                final Map.Entry<String, Agent> entry = it.next();
                try {
                    if (entry.getValue() != null) {
                        entry.getValue().stop();
                    }
                } catch (Exception e) {
                    if (_log.isErrorEnabled()) {
                        _log.error("Error stopping Agent for data source " + entry.getKey(), e);
                    }
                }
            }
        } finally {
            _lock.writeLock().unlock();
        }
    }
}