/******************************************************************************* * Copyright (c) 2012 Zend Technologies Ltd. * 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 *******************************************************************************/ package org.zend.php.zendserver.monitor.internal.core; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.php.internal.server.core.Server; import org.eclipse.swt.widgets.Display; import org.zend.php.server.core.utils.ServerUtils; import org.zend.php.zendserver.deployment.core.targets.TargetsManagerService; import org.zend.php.zendserver.monitor.core.Activator; import org.zend.php.zendserver.monitor.core.IEventDetails; import org.zend.php.zendserver.monitor.core.INotificationProvider; import org.zend.php.zendserver.monitor.core.MonitorManager; import org.zend.sdklib.application.ZendCodeTracing; import org.zend.sdklib.manager.TargetsManager; import org.zend.sdklib.monitor.IZendIssue; import org.zend.sdklib.monitor.ZendMonitor; import org.zend.sdklib.monitor.ZendMonitor.Filter; import org.zend.sdklib.target.IZendTarget; import org.zend.webapi.core.WebApiException; import org.zend.webapi.core.connection.data.CodeTracingStatus; import org.zend.webapi.core.connection.data.EventsGroupDetails; import org.zend.webapi.core.connection.data.values.ZendServerVersion; import org.zend.webapi.core.connection.response.ResponseCode; import org.zend.webapi.internal.core.connection.exception.UnexpectedResponseCode; import org.zend.webapi.internal.core.connection.exception.WebApiCommunicationError; /** * Represents abstract monitor job. It contains monitor internal implementation * shared between different monitor types. * * @author Wojciech Galanciak, 2012 * */ @SuppressWarnings("restriction") public abstract class AbstractMonitor extends Job { private static final String PROVIDER_EXTENSION = "org.zend.php.zendserver.monitor.core.notificationProvider"; //$NON-NLS-1$ private static final int JOB_DELAY_MIN = 2000; private static final int JOB_DELAY_MAX = 4 * JOB_DELAY_MIN; private static final int STEP = 30; private static INotificationProvider provider; protected String targetId; protected ZendMonitor monitor; protected long lastTime; private int jobDelay = JOB_DELAY_MIN; private int counter; private int offset; private ZendCodeTracing codeTracing; private boolean codeTracingEnabled; public AbstractMonitor(String targetId, String jobTitle) { super(jobTitle); this.targetId = targetId; this.codeTracingEnabled = true; } /** * Start monitor job. */ public void start() { getProvider().showProgress( getName(), MessageFormat.format(Messages.ZendServerMonitor_TaskTitle, getServerName()), new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { if (!doStart(monitor)) { MonitorManager.removeMonitor(AbstractMonitor.this); } } }); } public void stop() { boolean disableCodeTracing = false; if (getState() != Job.NONE) { disableCodeTracing = true; } cancel(); if (disableCodeTracing) { disableCodeTacing(); } } @Override protected IStatus run(IProgressMonitor monitor) { monitor.beginTask(MessageFormat.format( Messages.ZendServerMonitor_TaskTitle, getServerName()), IProgressMonitor.UNKNOWN); IZendTarget target = getTarget(); if (target != null) { if (isZS6(target)) { doRunZS6(target); } else { doRunOld(target); } if (!monitor.isCanceled()) { monitor.done(); if (counter > STEP && jobDelay < JOB_DELAY_MAX) { jobDelay *= 2; counter = 0; } this.schedule(jobDelay); return Status.OK_STATUS; } } else { getProvider().showErrorMessage( Messages.AbstractMonitor_NotificationTitle, Messages.AbstractMonitor_NoTargetError); } monitor.done(); return Status.CANCEL_STATUS; } protected abstract void handleIssues(List<IZendIssue> issues, IZendTarget target); protected void showNonification(final IZendIssue issue, final String projectName, final String basePath, final int delay, final int actionsAvailable) { Display.getDefault().asyncExec(new Runnable() { public void run() { IEventDetails eventSource = EventDetails.create(issue .getIssue().getGeneralDetails().getUrl(), projectName, basePath, issue.getIssue()); getProvider().showNonification(issue, targetId, eventSource, delay, actionsAvailable); } }); } protected int checkActions(IZendIssue issue) { IZendTarget target = getTarget(); if (TargetsManager.checkMinVersion(target, ZendServerVersion.v5_6_0)) { return codeTracingEnabled ? MonitorManager.REPEAT + MonitorManager.CODE_TRACE : MonitorManager.REPEAT; } int result = 0; try { List<EventsGroupDetails> groups = issue.getGroupDetails(); result += MonitorManager.REPEAT; if (codeTracingEnabled && groups != null && groups.size() == 1) { EventsGroupDetails group = groups.get(0); String traceId = group.getCodeTracing(); if (traceId == null) { traceId = group.getEvent().getCodeTracing(); } if (traceId != null && !traceId.isEmpty()) { result += MonitorManager.CODE_TRACE; } } } catch (Exception e) { Activator.log(e); return 0; } return result; } protected abstract IProject getProject(String urlString); protected static INotificationProvider getProvider() { if (provider == null) { IConfigurationElement[] elements = Platform.getExtensionRegistry() .getConfigurationElementsFor(PROVIDER_EXTENSION); for (IConfigurationElement element : elements) { if ("notificationProvider".equals(element.getName())) { //$NON-NLS-1$ try { Object listener = element .createExecutableExtension("class"); //$NON-NLS-1$ if (listener instanceof INotificationProvider) { provider = (INotificationProvider) listener; break; } } catch (CoreException e) { Activator.log(e); } } } } return provider; } protected void disableCodeTacing() { final String name = getServerName(); getProvider().showProgress( getName(), MessageFormat.format(Messages.AbstractMonitor_DisablingJobName, name), new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask( MessageFormat .format(Messages.AbstractMonitor_DisablingJobName, name), IProgressMonitor.UNKNOWN); ZendCodeTracing codeTracing = new ZendCodeTracing( targetId); try { if (getTarget() != null) { CodeTracingStatus status = codeTracing .disable(true); if (status == null) { String m = MessageFormat .format(Messages.AbstractMonitor_InitializationJobConnectionError, name); handleError(monitor, m); return; } } } catch (WebApiCommunicationError e) { String m = MessageFormat .format(Messages.AbstractMonitor_InitializationJobConnectionError, name); handleError(monitor, m); return; } catch (UnexpectedResponseCode e) { ResponseCode code = e.getResponseCode(); switch (code) { case UNSUPPORTED_API_VERSION: String m = MessageFormat .format(Messages.AbstractMonitor_InitializationJobUnsupportedVersion, name); handleError(monitor, m); return; default: break; } } catch (WebApiException e) { handleError(monitor, e.getMessage()); } } }); } protected boolean isZS6(IZendTarget target) { ZendServerVersion version = ZendServerVersion.byName(target .getProperty(IZendTarget.SERVER_VERSION)); return version.getName().startsWith("6"); //$NON-NLS-1$ } protected String getServerName() { Server server = ServerUtils.getServer(getTarget()); return server != null ? server.getName() : targetId; } protected IZendTarget getTarget() { return TargetsManagerService.INSTANCE.getTargetManager().getTargetById( targetId); } private void doRunZS6(IZendTarget target) { List<IZendIssue> issues = null; if (monitor == null) { monitor = new ZendMonitor(targetId); lastTime = System.currentTimeMillis(); } else { issues = monitor .getIssues(Filter.ALL_OPEN_EVENTS, lastTime, target); if (issues != null && issues.size() > 0) { counter = 0; if (jobDelay > JOB_DELAY_MIN) { jobDelay /= 2; } issues = removeDuplicates(issues); handleIssues(issues, target); lastTime = monitor.getLastEventTime(issues.get(0), target); } else { counter++; } } } private List<IZendIssue> removeDuplicates(List<IZendIssue> issues) { List<IZendIssue> result = new ArrayList<IZendIssue>(); for (IZendIssue issue : issues) { if (!result.contains(issue)) { result.add(issue); } } return result; } private void doRunOld(IZendTarget target) { List<IZendIssue> issues = null; if (monitor == null) { monitor = new ZendMonitor(targetId); issues = monitor.getOpenIssues(); if (issues != null && issues.size() > 0) { offset += issues.size(); lastTime = monitor.getLastEventTime( issues.get(issues.size() - 1), target); } } else { issues = monitor.getIssues(Filter.ALL_OPEN_EVENTS, offset); if (issues != null && issues.size() > 0) { counter = 0; if (jobDelay > JOB_DELAY_MIN) { jobDelay /= 2; } issues = removeDuplicates(issues); handleIssues(issues, target); offset += issues.size(); lastTime = monitor.getLastEventTime( issues.get(issues.size() - 1), target); } else { counter++; } } } private boolean doStart(IProgressMonitor monitor) { String name = getServerName(); monitor.beginTask(MessageFormat.format( Messages.AbstractMonitor_EnablingJobName, name), IProgressMonitor.UNKNOWN); if (codeTracing == null) { codeTracing = new ZendCodeTracing(targetId); try { CodeTracingStatus status = codeTracing.enable(true); if (status == null) { String m = MessageFormat .format(Messages.AbstractMonitor_InitializationJobConnectionError, name); handleError(monitor, m); return false; } } catch (WebApiException e) { Activator.log(e); if (e instanceof WebApiCommunicationError) { String m = MessageFormat .format(Messages.AbstractMonitor_InitializationJobConnectionError, name); handleError(monitor, m); return false; } else { if (e instanceof UnexpectedResponseCode) { UnexpectedResponseCode codeException = (UnexpectedResponseCode) e; ResponseCode code = codeException.getResponseCode(); switch (code) { case NOT_SUPPORTED_BY_EDITION: String m = MessageFormat .format(Messages.AbstractMonitor_NotSupportedMessage, name); handleError(monitor, m); return false; case UNSUPPORTED_API_VERSION: m = MessageFormat .format(Messages.AbstractMonitor_InitializationJobUnsupportedVersion, name); handleError(monitor, m); return false; default: break; } } codeTracingEnabled = false; } } } lastTime = Long.MAX_VALUE; if (getState() == Job.NONE) { setSystem(true); } AbstractMonitor.this.run(monitor); return true; } private void handleError(IProgressMonitor monitor, String m) { getProvider().showErrorMessage(getName(), m); stop(); } }