// ============================================================================ // // Copyright (C) 2006-2016 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.mdm.workbench.serverexplorer.console; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.util.Timer; import java.util.TimerTask; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.HttpHostConnectException; import org.apache.http.impl.client.DefaultHttpClient; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.program.Program; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IConsoleView; import org.eclipse.ui.console.MessageConsole; import org.eclipse.ui.console.MessageConsoleStream; import org.eclipse.ui.internal.console.IOConsolePage; import org.eclipse.ui.part.IPageBookViewPage; import org.talend.mdm.repository.model.mdmmetadata.MDMServerDef; import org.talend.mdm.workbench.serverexplorer.core.ServerDefService; import org.talend.mdm.workbench.serverexplorer.i18n.Messages; import org.talend.mdm.workbench.serverexplorer.plugin.MDMServerExplorerPlugin; import org.talend.mdm.workbench.serverexplorer.ui.dialogs.DownloadLogDialog; import com.amalto.workbench.utils.HttpClientUtil; import com.amalto.workbench.utils.Util; /** * created by Karelun Huang on Mar 19, 2013 Detailled comment * */ public abstract class MDMServerMessageConsole extends MessageConsole implements IPropertyChangeListener { private static final Log log = LogFactory.getLog(MDMServerMessageConsole.class); private static final int START_FROM_TAIL = -1; private static final int HTTP_STATUS_OK = 200; private static final int HTTP_STATUS_NO_ACCESS = 401; private static final int HTTP_STSTUS_FORBIDDEN = 403; private static final int HTTP_STATUS_NOT_FOUND = 404; private static final ImageDescriptor DOWNLOAD_IMG = MDMServerExplorerPlugin.imageDescriptorFromPlugin( MDMServerExplorerPlugin.PLUGIN_ID, "icons/download.png"); //$NON-NLS-1$; private static final ImageDescriptor PAUSED_IMG = MDMServerExplorerPlugin.imageDescriptorFromPlugin( MDMServerExplorerPlugin.PLUGIN_ID, "icons/pause.gif"); //$NON-NLS-1$; private static final ImageDescriptor RESUMED_IMG = MDMServerExplorerPlugin.imageDescriptorFromPlugin( MDMServerExplorerPlugin.PLUGIN_ID, "icons/resume.gif"); //$NON-NLS-1$; private static final ImageDescriptor RELOAD_IMG = MDMServerExplorerPlugin.imageDescriptorFromPlugin( MDMServerExplorerPlugin.PLUGIN_ID, "icons/refresh.gif"); //$NON-NLS-1$; private static final ImageDescriptor CLOSE_IMG = MDMServerExplorerPlugin.imageDescriptorFromPlugin( MDMServerExplorerPlugin.PLUGIN_ID, "icons/rem_co.gif"); //$NON-NLS-1$; public class TerminateConsoleAction extends Action { public TerminateConsoleAction() { super(Messages.MDMServerMessageConsole_closeActionLabel); setImageDescriptor(CLOSE_IMG); } @Override public void run() { ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new IConsole[] { MDMServerMessageConsole.this }); } } public class DownloadAction extends Action { public DownloadAction() { super(Messages.MDMServerMessageConsole_DownloadAction_Text); setImageDescriptor(DOWNLOAD_IMG); } @Override public void run() { DownloadLogDialog d = new DownloadLogDialog(getShell()); int ret = d.open(); if (ret != IDialogConstants.OK_ID) { return; } final String filePath = d.getDirectoryPath(); final boolean needOpen = d.needOpen(); ProgressMonitorDialog pmd = new ProgressMonitorDialog(getShell()); try { pmd.run(false, true, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { download(filePath, needOpen, monitor); monitor.done(); } }); } catch (InvocationTargetException e) { log.error(e.getMessage(), e); } catch (InterruptedException e) { log.error(e.getMessage(), e); } } } public class MonitorAction extends Action { /** * false: Puased. true: Resumed. */ private boolean isPaused = false; public MonitorAction() { update(); } @Override public void run() { isPaused = !isPaused; pauseOrResume(isPaused); update(); } public void initStatus() { isPaused = false; update(); } private void update() { if (isPaused) { setText(Messages.MDMServerMessageConsole_MonitorAction_ResumeText); setImageDescriptor(RESUMED_IMG); } else { setText(Messages.MDMServerMessageConsole_MonitorAction_PauseText); setImageDescriptor(PAUSED_IMG); } } } public class ReloadAction extends Action { public ReloadAction() { super(Messages.MDMServerMessageConsole_ReloadAction_Text); setImageDescriptor(RELOAD_IMG); } @Override public void run() { reload(); if (monitorAction != null) { monitorAction.initStatus(); } } private void reload() { refreshServerDef(); disposeTimer(); display(); } private void refreshServerDef() { MDMServerDef newServerDef = ServerDefService.findServerDefByName(getServerDef().getName()); setServerDef(newServerDef); } } private MonitorAction monitorAction = null; private DownloadAction downloadAction = null; private ReloadAction reloadAction = null; private MDMServerDef serverDef = null; /** * Getter for serverDef. * * @return the serverDef */ public MDMServerDef getServerDef() { return this.serverDef; } private Timer timer = null; private int position = START_FROM_TAIL; private TerminateConsoleAction terminateConsoleAction; /** * Getter for terminateConsoleAction. * * @return the terminateConsoleAction */ public TerminateConsoleAction getTerminateConsoleAction() { return this.terminateConsoleAction; } public MDMServerMessageConsole(MDMServerDef serverDef) { this(Messages.MDMServerMessageConsole_Name, null); this.serverDef = serverDef; initMessageConsole(); initActions(); PlatformUI.getPreferenceStore().addPropertyChangeListener(this); } public MDMServerMessageConsole(String name, ImageDescriptor imageDescriptor) { super(name, imageDescriptor); } public void setServerDef(MDMServerDef serverDef) { this.serverDef = serverDef; initMessageConsole(); } private void initMessageConsole() { String name = getConsoleTitle(); setName(name); initWaterMarks(); } private void initActions() { reloadAction = new ReloadAction(); monitorAction = new MonitorAction(); downloadAction = new DownloadAction(); terminateConsoleAction = new TerminateConsoleAction(); } private void initWaterMarks() { int buffer = MDMServerPreferenceService.getDisplayedBuffer(); setWaterMarks(buffer, buffer + 100); } @Override public IPageBookViewPage createPage(IConsoleView view) { IOConsolePage consolePage = new IOConsolePage(this, view) { @Override protected void contextMenuAboutToShow(IMenuManager menuManager) { super.contextMenuAboutToShow(menuManager); menuManager.add(new Separator()); menuManager.add(reloadAction); menuManager.add(monitorAction); menuManager.add(downloadAction); menuManager.add(terminateConsoleAction); } @Override public void dispose() { disposeTimer(); PlatformUI.getPreferenceStore().removePropertyChangeListener(MDMServerMessageConsole.this); removeFromCache(serverDef.getName()); ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new IConsole[] { MDMServerMessageConsole.this }); super.dispose(); } }; consolePage.setReadOnly(); return consolePage; } public void reload() { if (reloadAction != null) { reloadAction.run(); } } @Override public void activate() { super.activate(); display(); } private void display() { position = START_FROM_TAIL; clearConsole(); monitor(); } private synchronized void monitor() { if (timer == null) { timer = new Timer(true); } timer.schedule(new TimerTask() { @Override public void run() { doMonitor(); } }, 0, getRefrehFrequency()); } private HttpResponse executeByHttpget(String url, String userName, String password) { HttpGet httpGet = new HttpGet(url); HttpClientUtil.addStudioToken(httpGet, serverDef.getUser()); DefaultHttpClient httpClient = createHttpClient(); HttpResponse response = null; try { response = httpClient.execute(httpGet); } catch (ClientProtocolException e) { log.error(e.getMessage(), e); } catch (IOException e) { log.error(e.getMessage(), e); } return response; } private void doMonitor() { String monitorURL = buildMonitorURL(position); MessageConsoleStream errorMsgStream = newErrorMessageStream(); InputStream is = null; BufferedReader br = null; MessageConsoleStream msgStream = null; InputStreamReader isr = null; try { HttpResponse response = executeByHttpget(monitorURL, serverDef.getUser(), serverDef.getPasswd()); int code = response.getStatusLine().getStatusCode(); if (HTTP_STATUS_OK == code) { modifyChunkedPosition(response); if (isEndOfChunk(response)) { return; } is = response.getEntity().getContent(); msgStream = newMessageStream(); isr = new InputStreamReader(is); br = new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) { msgStream.println(line); } } else { if (HTTP_STATUS_NO_ACCESS == code) { errorMsgStream.println(Messages.MDMServerMessageConsole_No_Acess_Message); disposeTimer(); } else if (HTTP_STSTUS_FORBIDDEN == code) { errorMsgStream.println(Messages.MDMServerMessageConsole_Forbidden_Message); disposeTimer(); } else if (HTTP_STATUS_NOT_FOUND == code) { errorMsgStream.println(Messages.MDMServerMessageConsole_NotConnected_Message); disposeTimer(); } } } catch (HttpHostConnectException ex) { errorMsgStream.println(ex.getMessage()); disposeTimer(); } catch (IOException e) { log.error(e.getMessage(), e); errorMsgStream.println(e.getMessage()); disposeTimer(); } catch (SecurityException e) { errorMsgStream.println(e.getMessage()); } finally { if (br != null) { try { br.close(); } catch (IOException e) { log.error(e.getMessage(), e); } } if (isr != null) { try { isr.close(); } catch (IOException e) { log.error(e.getMessage(), e); } } if (is != null) { try { is.close(); } catch (IOException e) { log.error(e.getMessage(), e); } } if (msgStream != null) { try { msgStream.close(); } catch (IOException e) { log.error(e.getMessage(), e); } } if (errorMsgStream != null) { try { errorMsgStream.close(); } catch (IOException e) { log.error(e.getMessage(), e); } } } } private int getRefrehFrequency() { return MDMServerPreferenceService.getRefrehFrequency() * 1000; } private void modifyChunkedPosition(HttpResponse response) { Header[] headers = response.getHeaders("X-Log-Position"); //$NON-NLS-1$ Assert.isTrue(headers.length > 0); String value = headers[0].getValue(); position = Integer.parseInt(value); } private boolean isEndOfChunk(HttpResponse response) { Header[] headers = response.getHeaders("Content-Length"); //$NON-NLS-1$ if (headers == null || headers.length == 0) { return false; } String value = headers[0].getValue(); return "0".equals(value); //$NON-NLS-1$ } private DefaultHttpClient createHttpClient() { DefaultHttpClient httpclient = new DefaultHttpClient(); AuthScope authScope = new AuthScope(serverDef.getHost(), Integer.parseInt(serverDef.getPort())); UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(serverDef.getUser(), serverDef.getPasswd()); if (httpclient != null) { httpclient.getCredentialsProvider().setCredentials(authScope, credentials); } return httpclient; } private String buildMonitorURL(int pos) { String buildURL = buildURL(); buildURL += "?position=" + pos; //$NON-NLS-1$ return buildURL; } private String buildURL() { StringBuilder sb = new StringBuilder(); sb.append(serverDef.getProtocol()); sb.append(serverDef.getHost()); sb.append(":"); //$NON-NLS-1$ sb.append(serverDef.getPort()); sb.append(Util.getContextPath(serverDef.getPath())); sb.append(getLogPath()); return sb.toString(); } private void pauseOrResume(boolean isPaused) { if (isPaused) { disposeTimer(); } else { monitor(); } } private Shell getShell() { return Display.getDefault().getActiveShell(); } private void download(String dirPath, boolean needOpen, IProgressMonitor monitor) { monitor.beginTask(Messages.MDMServerMessageConsole_DownloadTask_Name, 100); InputStream is = null; OutputStream os = null; try { String monitorURL = buildURL(); HttpResponse response = executeByHttpget(monitorURL, serverDef.getUser(), serverDef.getPasswd()); monitor.worked(40); int code = response.getStatusLine().getStatusCode(); if (HTTP_STATUS_OK == code) { String fileName = getFileName(response); is = response.getEntity().getContent(); monitor.worked(60); File file = new File(dirPath + File.separator + fileName); os = new FileOutputStream(file); IOUtils.copy(is, os); monitor.worked(85); if (needOpen) { Program.launch(file.getAbsolutePath()); } monitor.worked(90); } else { newErrorMessageStream().println(Messages.MDMServerMessageConsole_DownloadFailed_Message); if (HTTP_STATUS_NO_ACCESS == code) { newErrorMessageStream().println(Messages.MDMServerMessageConsole_No_Acess_Message); } else if (HTTP_STSTUS_FORBIDDEN == code) { newErrorMessageStream().println(Messages.MDMServerMessageConsole_Forbidden_Message); } else if (HTTP_STATUS_NOT_FOUND == code) { newErrorMessageStream().println(Messages.MDMServerMessageConsole_NotConnected_Message); } monitor.worked(90); } } catch (IOException e) { log.error(e.getMessage(), e); newErrorMessageStream().println(Messages.MDMServerMessageConsole_DownloadFailed_Message); newErrorMessageStream().println(e.getMessage()); monitor.worked(90); } catch (SecurityException e) { MessageDialog.openError(getShell(), Messages.MDMServerMessageConsole_error, e.getMessage()); } finally { if (is != null) { try { is.close(); } catch (IOException e) { log.error(e.getMessage(), e); } } if (os != null) { try { os.close(); } catch (IOException e) { log.error(e.getMessage(), e); } } } } private String getFileName(HttpResponse response) { Header[] headers = response.getHeaders("Content-Disposition"); //$NON-NLS-1$ Assert.isTrue(headers.length > 0); String value = headers[0].getValue(); int begin = value.indexOf("\""); //$NON-NLS-1$ int end = value.lastIndexOf("\""); //$NON-NLS-1$ return value.substring(begin + 1, end); } private void disposeTimer() { if (timer != null) { timer.cancel(); timer = null; } } private MessageConsoleStream newErrorMessageStream() { final MessageConsoleStream msgStream = newMessageStream(); ConsolePlugin.getStandardDisplay().asyncExec(new Runnable() { public void run() { msgStream.setColor(Display.getDefault().getSystemColor(SWT.COLOR_RED)); } }); return msgStream; } public void propertyChange(PropertyChangeEvent event) { if (event.getProperty().equals(MDMServerPreferenceService.REFRESH_FREQ)) { disposeTimer(); monitor(); } else if (event.getProperty().equals(MDMServerPreferenceService.DISPLAY_BUFFER_SIZE)) { initWaterMarks(); } } public ReloadAction getReloadAction() { return this.reloadAction; } public MonitorAction getMonitorAction() { return this.monitorAction; } public DownloadAction getDownloadAction() { return this.downloadAction; } @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof MDMServerMessageConsole)) { return false; } if (this == obj) { return true; } MDMServerMessageConsole otherConsole = (MDMServerMessageConsole) obj; return serverDef == otherConsole.getServerDef(); } protected abstract String getLogPath(); protected abstract String getConsoleTitle(); protected abstract void removeFromCache(String serverName); }