/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.communication.management.internal; import java.io.Serializable; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.logging.LogFactory; import org.osgi.framework.BundleContext; import de.rcenvironment.core.communication.api.CommunicationService; import de.rcenvironment.core.communication.api.LiveNetworkIdResolutionService; import de.rcenvironment.core.communication.api.PlatformService; import de.rcenvironment.core.communication.common.IdentifierException; import de.rcenvironment.core.communication.common.InstanceNodeSessionId; import de.rcenvironment.core.communication.management.BenchmarkService; import de.rcenvironment.core.communication.management.BenchmarkSetup; import de.rcenvironment.core.communication.management.RemoteBenchmarkService; import de.rcenvironment.core.toolkitbridge.transitional.ConcurrencyUtils; import de.rcenvironment.core.utils.common.security.AllowRemoteAccess; import de.rcenvironment.core.utils.common.textstream.TextOutputReceiver; /** * Default {@link BenchmarkService} implementation. * * @author Robert Mischke */ public class BenchmarkServiceImpl implements BenchmarkService, RemoteBenchmarkService { private CommunicationService commService; private PlatformService platformService; private LiveNetworkIdResolutionService idResolutionService; /** * Internal implementation of {@link BenchmarkSetup}. * * @author Robert Mischke */ private class BenchmarkSetupImpl implements BenchmarkSetup { private List<BenchmarkSubtaskImpl> subtasks; BenchmarkSetupImpl(List<BenchmarkSubtaskImpl> subtasks) { this.subtasks = subtasks; } @Override public List<BenchmarkSubtaskImpl> getSubtasks() { return subtasks; } } @Override public BenchmarkSetup parseBenchmarkDescription(String definition) { List<BenchmarkSubtaskImpl> subtasks = new ArrayList<BenchmarkSubtaskImpl>(); // TODO should use length constants instead; would be nice to also support instance ids and "upcast" Pattern cmdPattern = Pattern.compile("([0-9a-f]{32}(?::[0-9a-f]{10})?|\\*|\\*\\*)\\((\\d*),(\\d*),(\\d*),(\\d*),(\\d*)\\)"); Matcher matcher = cmdPattern.matcher(definition); while (matcher.find()) { String targetNodeString = matcher.group(1); int numMessages = parseInt(matcher.group(2), 1); int requestSize = parseInt(matcher.group(3), 1); int responseSize = parseInt(matcher.group(4), 1); int responseDelay = parseInt(matcher.group(5), 0); int numSenders = parseInt(matcher.group(6), 1); List<InstanceNodeSessionId> targetNodes = new ArrayList<InstanceNodeSessionId>(); if (targetNodeString.equals("*")) { // * = add all, except "self" Set<InstanceNodeSessionId> knownNodes = new HashSet<InstanceNodeSessionId>(commService.getReachableInstanceNodes()); knownNodes.remove(platformService.getLocalInstanceNodeSessionId()); targetNodes.addAll(knownNodes); } else if (targetNodeString.equals("**")) { // ** = add all, including "self" targetNodes.addAll(commService.getReachableInstanceNodes()); } else { try { targetNodes.add(idResolutionService.resolveInstanceNodeIdStringToInstanceNodeSessionId(targetNodeString)); } catch (IdentifierException e) { throw new IllegalArgumentException("Could not resolve '" + targetNodeString + "' to a valid node within the current network"); } } BenchmarkSubtaskImpl subtask = new BenchmarkSubtaskImpl(targetNodes, numMessages, requestSize, responseSize, responseDelay, numSenders); subtasks.add(subtask); } if (subtasks.isEmpty()) { throw new IllegalArgumentException("Malformed task definition: '" + definition + "'"); } return new BenchmarkSetupImpl(subtasks); } @Override public void executeBenchmark(BenchmarkSetup setup, TextOutputReceiver outputReceiver) { BenchmarkProcess benchmark = createBenchmarkProcess(setup, outputReceiver); benchmark.run(); } @Override public void asyncExecBenchmark(BenchmarkSetup setup, TextOutputReceiver outputReceiver) { BenchmarkProcess benchmark = createBenchmarkProcess(setup, outputReceiver); ConcurrencyUtils.getAsyncTaskService().execute(benchmark); } @Override @AllowRemoteAccess public Serializable respond(Serializable input, Integer respSize, Integer respDelay) { try { Thread.sleep(respDelay); } catch (InterruptedException e) { LogFactory.getLog(getClass()).warn("Interrupted while waiting to send benchmark response", e); } return new byte[respSize]; } protected void activate(BundleContext context) {} protected void bindCommunicationService(CommunicationService newCommunicationService) { this.commService = newCommunicationService; } protected void bindLiveNetworkIdResolutionService(LiveNetworkIdResolutionService newInstance) { this.idResolutionService = newInstance; } protected void bindPlatformService(PlatformService newService) { this.platformService = newService; } private BenchmarkProcess createBenchmarkProcess(BenchmarkSetup setup, TextOutputReceiver outputReceiver) { BenchmarkProcess benchmark = new BenchmarkProcess(setup, outputReceiver, commService); return benchmark; } private int parseInt(String input, int defValue) { if (input.length() == 0) { return defValue; } return Integer.parseInt(input); } }