/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2010-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.sms.monitor.internal; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import org.opennms.core.tasks.Async; import org.opennms.core.tasks.Callback; import org.opennms.core.tasks.DefaultTaskCoordinator; import org.opennms.core.tasks.SequenceTask; import org.opennms.core.tasks.Task; import org.opennms.sms.monitor.MobileSequenceSession; import org.opennms.sms.monitor.internal.config.MobileSequenceConfig; import org.opennms.sms.monitor.internal.config.MobileSequenceTransaction; import org.opennms.sms.reflector.smsservice.MobileMsgResponse; /** * MobileSequenceExecution * * @author brozow * @version $Id: $ */ public class MobileSequenceExecution { // Use a LinkedHashMap to ensure transaction latencies are ordered. private Map<String, Number> m_responseTimes = new LinkedHashMap<String,Number>(); private Long m_startTime; private SequenceTask m_task; private MobileSequenceConfig m_sequenceConfig; private List<MobileTransactionExecution> m_transactionExecutions = new ArrayList<MobileTransactionExecution>(); /** * <p>Constructor for MobileSequenceExecution.</p> * * @param sequenceConfig a {@link org.opennms.sms.monitor.internal.config.MobileSequenceConfig} object. */ public MobileSequenceExecution(MobileSequenceConfig sequenceConfig) { m_sequenceConfig = sequenceConfig; for(MobileSequenceTransaction transaction : sequenceConfig.getTransactions()) { m_transactionExecutions.add(new MobileTransactionExecution(transaction)); } } /** * <p>getSequenceConfig</p> * * @return a {@link org.opennms.sms.monitor.internal.config.MobileSequenceConfig} object. */ public MobileSequenceConfig getSequenceConfig() { return m_sequenceConfig; } /** * <p>getTransactionExecutions</p> * * @return a {@link java.util.List} object. */ public List<MobileTransactionExecution> getTransactionExecutions() { return m_transactionExecutions; } /** * <p>getStartTime</p> * * @return a {@link java.lang.Long} object. */ public Long getStartTime() { return m_startTime; } /** * <p>setStartTime</p> * * @param startTime a {@link java.lang.Long} object. */ public void setStartTime(Long startTime) { m_startTime = startTime; } /** * <p>getResponseTimes</p> * * @return a {@link java.util.Map} object. */ public Map<String, Number> getResponseTimes() { return m_responseTimes; } /** * <p>end</p> */ public void end() { long end = System.currentTimeMillis(); getResponseTimes().put("response-time", Long.valueOf(end - (long) getStartTime())); } /** * <p>waitFor</p> * * @throws java.lang.InterruptedException if any. * @throws java.util.concurrent.ExecutionException if any. */ public void waitFor() throws InterruptedException, ExecutionException { Task task = getTask(); if (task == null) { throw new IllegalStateException("attempting to wait for the sequence to complete but the sequence has never been started!"); } task.waitFor(); end(); } /** * <p>getTask</p> * * @return a {@link org.opennms.core.tasks.SequenceTask} object. */ public SequenceTask getTask() { return m_task; } /** * <p>setTask</p> * * @param task a {@link org.opennms.core.tasks.SequenceTask} object. */ public void setTask(SequenceTask task) { m_task = task; } /** * <p>updateResults</p> * * @param session a {@link org.opennms.sms.monitor.MobileSequenceSession} object. * @throws java.lang.Throwable if any. */ public void updateResults(MobileSequenceSession session) throws Throwable { for(MobileTransactionExecution execution : getTransactionExecutions()) { MobileSequenceTransaction transaction = execution.getTransaction(); if (execution.getError() != null) { throw execution.getError(); } getResponseTimes().put(transaction.getLabel(session), execution.getLatency()); } } /** * <p>start</p> * * @param session a {@link org.opennms.sms.monitor.MobileSequenceSession} object. * @param coordinator a {@link org.opennms.core.tasks.DefaultTaskCoordinator} object. */ public void start(MobileSequenceSession session, DefaultTaskCoordinator coordinator) { setTask(coordinator.createSequence().get()); for (MobileTransactionExecution execution : getTransactionExecutions()) { getTask().add(createAsync(session, execution), null); } setStartTime(System.currentTimeMillis()); getTask().schedule(); } private Async<MobileMsgResponse> createAsync(final MobileSequenceSession session, final MobileTransactionExecution execution) { return new Async<MobileMsgResponse>() { public void submit(Callback<MobileMsgResponse> cb) { if (hasFailed()) { cb.complete(null); } else { execution.sendRequest(session, cb); } } }; } private boolean hasFailed() { for (MobileTransactionExecution execution : getTransactionExecutions()) { if (execution.getError() != null) { return true; } } return false; } }