/******************************************************************************* * Copyright (c) 2007 Cambridge Semantics Incorporated. * 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: * Cambridge Semantics Incorporated *******************************************************************************/ package org.openanzo.client.cli; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import javax.jms.TextMessage; import org.openanzo.analysis.RequestHandler; import org.openanzo.analysis.RequestRecorder; import org.openanzo.combus.ActiveMqProvider; import org.openanzo.combus.CombusConnection; import org.openanzo.datasource.IAuthorizationService; import org.openanzo.datasource.IModelService; import org.openanzo.datasource.IQueryService; import org.openanzo.datasource.IReplicationService; import org.openanzo.datasource.IResetService; import org.openanzo.datasource.IUpdateService; import org.openanzo.rdf.Constants; import org.openanzo.rdf.URI; import org.openanzo.rdf.Constants.COMBUS; import org.openanzo.services.AnzoPrincipal; import org.openanzo.services.IExecutionService; import org.openanzo.services.INotificationRegistrationService; import org.openanzo.services.IOperationContext; import org.openanzo.services.impl.BaseOperationContext; /** * * @author Ben Szekely ( <a href="mailto:ben@cambridgesemantics.com">ben@cambridgesemantics.com </a>) * */ public class PlaybackHandler implements RequestHandler { private final Map<String, String> credentials; private Map<String, CombusConnection> connections = new HashMap<String, CombusConnection>(); private final String host; private final int port; private final boolean useSsl; private long timeout = 60000; private final Set<String> allowedDestinations; private final String bodyPattern; private final HashMap<String, List<String>> propFilter; long overallStartTime = 0; long totalRequestsSent = 0; long requestDurationTotal = 0; private boolean firstRequest = true; SortedMap<String, Long> perOperationDurationTotals = new TreeMap<String, Long>(); SortedMap<String, Long> perOperationCounts = new TreeMap<String, Long>(); private final int id; private static final Map<String, String> SERVICES = new HashMap<String, String>(); static { SERVICES.put(COMBUS.REPLICATION_SERVICE_QUEUE, IReplicationService.SERVICE_NAME); SERVICES.put(COMBUS.QUERY_SERVICE_QUEUE, IQueryService.SERVICE_NAME); SERVICES.put(COMBUS.MODEL_SERVICE_QUEUE, IModelService.SERVICE_NAME); SERVICES.put(COMBUS.AUTHORIZATION_SERVICE_QUEUE, IAuthorizationService.SERVICE_NAME); SERVICES.put(COMBUS.NOTIFICATION_SERVICE_QUEUE, INotificationRegistrationService.SERVICE_NAME); SERVICES.put(COMBUS.UPDATE_SERVICE_QUEUE, IUpdateService.SERVICE_NAME); SERVICES.put(COMBUS.RESET_SERVICE_QUEUE, IResetService.SERVICE_NAME); SERVICES.put(COMBUS.EXECUTION_SERVICE_QUEUE, IExecutionService.SERVICE_NAME); } /** * Create a playback handler * * @param id * id of the playback * @param credentials * credentials to use for connection * @param host * hostname for server * @param port * port for server * @param useSsl * use ssl * @param timeout * timeout for operations * @param bodyPattern * * @param allowedDestinations * * @param propFilter */ public PlaybackHandler(int id, HashMap<String, String> credentials, String host, int port, boolean useSsl, String timeout, String bodyPattern, Set<String> allowedDestinations, HashMap<String, List<String>> propFilter) { this.id = id; this.credentials = credentials; this.host = host; this.port = port; this.useSsl = useSsl; if (timeout != null) { this.timeout = Long.parseLong(timeout); } this.allowedDestinations = allowedDestinations; this.bodyPattern = bodyPattern; this.propFilter = propFilter; } public Object handleRequest(String body, Map<String, String> properties, String requestUser, String runAsUser, String destination, String jmsCorrelationId) throws Exception { if (id > 0) { jmsCorrelationId = jmsCorrelationId + "-" + id; } if (firstRequest) { overallStartTime = System.currentTimeMillis(); firstRequest = false; } String service = SERVICES.get(destination); if (service == null && allowedDestinations == null) { throw new CommandException("Unknown destination: " + destination); } if (allowedDestinations != null && !allowedDestinations.contains(service)) { return null; } if (bodyPattern != null && body.indexOf(bodyPattern) == -1) { return null; } if (propFilter != null) { boolean found = false; for (String prop : propFilter.keySet()) { List<String> vals = propFilter.get(prop); for (String val : vals) { if (prop.equals(RequestRecorder.REQUEST_USER)) { if (requestUser.indexOf(val) != -1) { found = true; break; } } if (prop.equals(RequestRecorder.REQUEST_RUN_AS_USER)) { if (runAsUser.indexOf(val) != -1) { found = true; break; } } if (prop.equals(RequestRecorder.DESTINATION)) { if (destination.indexOf(val) != -1) { found = true; break; } } if (prop.equals(RequestRecorder.JMS_CORRELATION_ID)) { if (jmsCorrelationId.indexOf(val) != -1) { found = true; break; } } String propVal = properties.get(prop); if (propVal != null && propVal.indexOf(val) != -1) { found = true; break; } } if (found) { break; } } if (!found) { return null; } } CombusConnection connection = connections.get(requestUser); if (connection == null) { connection = new CombusConnection(new ActiveMqProvider(false), requestUser, credentials.get(requestUser), host, port, useSsl); connection.connect(); connections.put(requestUser, connection); } String user = requestUser; if (runAsUser != null) { user = runAsUser; } AnzoPrincipal principal = new AnzoPrincipal(user, null, Collections.<URI> emptySet(), false, Constants.DEFAULT_ANONYMOUS_USER.equals(user)); IOperationContext ctx = new BaseOperationContext("playback: " + properties.get("operation"), jmsCorrelationId, principal); TextMessage request = connection.createMessage(); request.setText(body); for (String name : properties.keySet()) { request.setStringProperty(name, properties.get(name)); } String operation = properties.get("operation"); System.out.println("Client (" + id + ") Request sent " + operation + "(" + jmsCorrelationId + ") "); long start = System.currentTimeMillis(); TextMessage response = connection.requestResponse(ctx, service, request, timeout); long end = System.currentTimeMillis(); long requestDuration = end - start; System.out.println("Client (" + id + ") Request complete " + operation + "(" + jmsCorrelationId + ") " + requestDuration); requestDurationTotal += requestDuration; totalRequestsSent++; Long current = perOperationDurationTotals.get(operation); perOperationDurationTotals.put(operation, (current == null ? 0 : current.longValue()) + requestDuration); current = perOperationCounts.get(operation); perOperationCounts.put(operation, (current == null ? 0 : current.longValue()) + 1); return response; } public void handleResponse(String body, Map<String, String> properties, Map<String, String> analysisProperties, String jmsCorrelationId) { // nothing to do here. } }