package rocks.inspectit.ui.rcp.ci.handler; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.collections.CollectionUtils; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IHandler; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.HandlerUtil; import rocks.inspectit.shared.all.cmr.model.PlatformIdent; import rocks.inspectit.shared.all.communication.data.cmr.AgentStatusData; import rocks.inspectit.shared.all.communication.data.cmr.AgentStatusData.AgentConnection; import rocks.inspectit.shared.all.communication.data.cmr.AgentStatusData.InstrumentationStatus; import rocks.inspectit.ui.rcp.ci.dialog.InstrumentationUpdateDialog; import rocks.inspectit.ui.rcp.ci.dialog.InstrumentationUpdateDialog.OnSaveBehavior; import rocks.inspectit.ui.rcp.preferences.PreferencesConstants; import rocks.inspectit.ui.rcp.preferences.PreferencesUtils; import rocks.inspectit.ui.rcp.provider.ICmrRepositoryAndAgentProvider; import rocks.inspectit.ui.rcp.provider.ICmrRepositoryProvider; import rocks.inspectit.ui.rcp.repository.CmrRepositoryDefinition; import rocks.inspectit.ui.rcp.util.SafeExecutor; /** * Handles the opening of the {@link InstrumentationUpdateDialog} and its result. * * @author Marius Oehler * */ public class InstrumentationUpdateHandler extends AbstractHandler implements IHandler { /** * {@inheritDoc} */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { // try to get the CMR where recording should start. CmrRepositoryDefinition cmrRepositoryDefinition = null; PlatformIdent platformIdent = null; ISelection selection = HandlerUtil.getCurrentSelection(event); if (selection instanceof StructuredSelection) { Object selectedObject = ((StructuredSelection) selection).getFirstElement(); if (selectedObject instanceof ICmrRepositoryProvider) { cmrRepositoryDefinition = ((ICmrRepositoryProvider) selectedObject).getCmrRepositoryDefinition(); } else if (selectedObject instanceof ICmrRepositoryAndAgentProvider) { ICmrRepositoryAndAgentProvider provider = ((ICmrRepositoryAndAgentProvider) selectedObject); cmrRepositoryDefinition = provider.getCmrRepositoryDefinition(); platformIdent = provider.getPlatformIdent(); } } execute(cmrRepositoryDefinition, platformIdent, true, null); return null; } /** * Opens the {@link InstrumentationUpdateDialog} if its {@link OnSaveBehavior} is * {@link OnSaveBehavior#SHOW_DIALOG}. * * @param cmrRepositoryDefinition * the {@link CmrRepositoryDefinition} to use * @param closeButtonLabel * the text on the closing button */ public static void execute(CmrRepositoryDefinition cmrRepositoryDefinition, String closeButtonLabel) { execute(cmrRepositoryDefinition, null, false, closeButtonLabel); } /** * Opens the {@link InstrumentationUpdateDialog}. * * @param repositoryDefinition * the {@link CmrRepositoryDefinition} to use * @param platformIdent * the agent which has been selected * @param forceDialog * whether the set {@link OnSaveBehavior} should be ignored in order to force the * opening * @param closeButtonLabel * the text on the closing button */ private static void execute(final CmrRepositoryDefinition repositoryDefinition, final PlatformIdent platformIdent, final boolean forceDialog, final String closeButtonLabel) { SafeExecutor.syncExec(new Runnable() { @Override public void run() { OnSaveBehavior saveBehavior = PreferencesUtils.getObject(PreferencesConstants.INSTRUMENTATION_UPDATED_AUTO_ACTION); if (forceDialog || (saveBehavior != OnSaveBehavior.DO_NOTHING)) { Map<PlatformIdent, AgentStatusData> agentMap = getPendingAgents(repositoryDefinition); Collection<PlatformIdent> updateAgents = new ArrayList<>(); if (forceDialog || (saveBehavior == OnSaveBehavior.SHOW_DIALOG)) { if (forceDialog || ((agentMap != null) && !agentMap.isEmpty())) { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window == null) { if (PlatformUI.getWorkbench().getWorkbenchWindowCount() > 0) { window = PlatformUI.getWorkbench().getWorkbenchWindows()[0]; } else { return; } } Shell shell = window.getShell(); InstrumentationUpdateDialog updateDialog = new InstrumentationUpdateDialog(shell, agentMap, platformIdent, closeButtonLabel); int result = updateDialog.open(); if (result == Dialog.OK) { updateAgents.addAll(updateDialog.getUpdateAgents()); } } } else if (saveBehavior == OnSaveBehavior.UPDATE_ALL_AGENTS) { updateAgents.addAll(agentMap.keySet()); } if (CollectionUtils.isNotEmpty(updateAgents)) { List<Long> updateIds = new ArrayList<>(); for (PlatformIdent platformIdent : updateAgents) { updateIds.add(platformIdent.getId()); } repositoryDefinition.getAgentInstrumentationService().updateInstrumentation(updateIds); } } } }); } /** * Fetches the existing agents from the CMR and extracts the ones which instrumentation status * is pending. * * @param repositoryDefinition * the {@link CmrRepositoryDefinition} to use * @return {@link Map} of agents having pending an instrumentation */ private static Map<PlatformIdent, AgentStatusData> getPendingAgents(CmrRepositoryDefinition repositoryDefinition) { Map<PlatformIdent, AgentStatusData> agentsOverview = repositoryDefinition.getGlobalDataAccessService().getAgentsOverview(); Map<PlatformIdent, AgentStatusData> resultMap = new HashMap<>(); for (Entry<PlatformIdent, AgentStatusData> entry : agentsOverview.entrySet()) { AgentStatusData agentStatus = entry.getValue(); if ((agentStatus.getAgentConnection() == AgentConnection.CONNECTED) && (agentStatus.getInstrumentationStatus() == InstrumentationStatus.PENDING)) { resultMap.put(entry.getKey(), entry.getValue()); } } return resultMap; } }