/******************************************************************************* * Copyright (c) 2015, 2016 Pivotal, Inc. * 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: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.boot.dash.cloudfoundry.console; import java.io.StringWriter; import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IConsoleManager; import org.eclipse.ui.console.MessageConsole; import org.springframework.ide.eclipse.boot.dash.cloudfoundry.CloudFoundryRunTarget; import org.springframework.ide.eclipse.boot.dash.cloudfoundry.CloudFoundryTargetProperties; import org.springframework.ide.eclipse.boot.dash.cloudfoundry.client.ClientRequests; import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.TargetProperties; import org.springframework.ide.eclipse.boot.dash.views.BootDashModelConsoleManager; import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; public class CloudAppLogManager extends BootDashModelConsoleManager { static final String CONSOLE_TYPE = "org.springframework.ide.eclipse.boot.dash.cloudfoundry.console"; static final String ATT_TARGET_PROPERTIES = "consoleTargetProperties"; static final String ATT_APP_NAME = "consoleAppName"; static final String APP_CONSOLE_ID = "consoleId"; private IConsoleManager consoleManager; private final CloudFoundryRunTarget runTarget; public CloudAppLogManager(CloudFoundryRunTarget runTarget) { this.runTarget = runTarget; consoleManager = ConsolePlugin.getDefault().getConsoleManager(); } @Override protected void doWriteToConsole(BootDashElement element, String message, LogType type) throws Exception { doWriteToConsole(element.getName(), message, type); } @Override protected void doWriteToConsole(String appName, String message, LogType type) throws Exception { ApplicationLogConsole console = getExisitingConsole(runTarget.getTargetProperties(), appName); if (console != null) { console.writeApplicationLog(message, type); // To avoid console "jumping", only show console // if none are visible showIfNoOtherConsoles(console); } } /** * Only shows the given console if no other console is visible. This avoid * "jumping" between consoles when multiple consoles are streaming in * parallel. */ protected void showIfNoOtherConsoles(IConsole console) { IConsole[] consoles = consoleManager.getConsoles(); if (consoles == null || consoles.length == 0) { consoleManager.showConsoleView(console); } } public synchronized void resetConsole(String appName) { ApplicationLogConsole console = getExisitingConsole(runTarget.getTargetProperties(), appName); if (console != null) { console.clearConsole(); console.setLogStreamingToken(null); } } /** * * @param targetProperties * @param appName * @return existing console, or null if it does not exist. */ protected synchronized ApplicationLogConsole getExisitingConsole(TargetProperties targetProperties, String appName) { IConsole[] consoles = ConsolePlugin.getDefault().getConsoleManager().getConsoles(); if (consoles != null) { for (IConsole console : consoles) { if (console instanceof ApplicationLogConsole) { String id = (String) ((MessageConsole) console).getAttribute(APP_CONSOLE_ID); String idToCheck = getConsoleId(targetProperties, appName); if (idToCheck.equals(id)) { ApplicationLogConsole appConsole = (ApplicationLogConsole) console; connectLoggregator(appConsole, appName); return appConsole; } } } } return null; } public synchronized void terminateConsole(String appName) throws Exception { ApplicationLogConsole console = getExisitingConsole(runTarget.getTargetProperties(), appName); if (console != null) { console.close(); console.destroy(); } } /** * * @param targetProperties * @param appName * @return non-null console for the given appname and target properties * @throws Exception * if console was not created or found */ protected synchronized ApplicationLogConsole getApplicationConsole(TargetProperties targetProperties, String appName) throws Exception { if (appName == null) { throw ExceptionUtil.coreException("INTERNAL ERROR: No application name specified when writing to console."); } if (targetProperties == null) { throw ExceptionUtil.coreException("INTERNAL ERROR: No target properties specified for application : " + appName + ". Unable to open console."); } ApplicationLogConsole appConsole = getExisitingConsole(targetProperties, appName); if (appConsole == null) { appConsole = new ApplicationLogConsole(getConsoleDisplayName(targetProperties, appName), CONSOLE_TYPE); appConsole.setAttribute(ATT_TARGET_PROPERTIES, targetProperties); appConsole.setAttribute(ATT_APP_NAME, appName); appConsole.setAttribute(APP_CONSOLE_ID, getConsoleId(targetProperties, appName)); consoleManager.addConsoles(new IConsole[] { appConsole }); connectLoggregator(appConsole, appName); } return appConsole; } protected void connectLoggregator(ApplicationLogConsole logConsole, String appName) { if (logConsole == null) { return; } if (logConsole.getLogStreamingToken() == null) { try { ClientRequests client = runTarget.getClient(); logConsole.setLogStreamingToken(client.streamLogs(appName, logConsole)); } catch (Exception e) { logConsole.writeApplicationLog("Failed to stream contents from Cloud Foundry due to: " + e.getMessage(), LogType.LOCALSTDERROR); } } } public static String getConsoleId(TargetProperties targetProperties, String appName) { return getConsoleDisplayName(targetProperties, appName) + '-' + targetProperties.getUrl(); } public static String getConsoleDisplayName(TargetProperties targetProperties, String appName) { StringWriter writer = new StringWriter(); writer.append(appName); String orgName = null; String spaceName = null; if (targetProperties instanceof CloudFoundryTargetProperties) { orgName = ((CloudFoundryTargetProperties) targetProperties).getOrganizationName(); spaceName = ((CloudFoundryTargetProperties) targetProperties).getSpaceName(); } if (orgName != null && spaceName != null) { writer.append(' '); writer.append('['); writer.append(orgName); writer.append(','); writer.append(' '); writer.append(spaceName); writer.append(']'); } return writer.toString(); } @Override public void showConsole(BootDashElement element) throws Exception { showConsole(element.getName()); } @Override public void showConsole(String appName) throws Exception { ApplicationLogConsole console = getApplicationConsole(runTarget.getTargetProperties(), appName); consoleManager.showConsoleView(console); } @Override public void reconnect(BootDashElement element) throws Exception { String appName = element.getName(); ApplicationLogConsole console = getApplicationConsole(runTarget.getTargetProperties(), appName); console.setLogStreamingToken(null); connectLoggregator(console, appName); consoleManager.showConsoleView(console); } }