Remove NGROK support

This commit is contained in:
aboyko
2023-02-13 13:20:31 -05:00
parent c580455019
commit 65551c084a
20 changed files with 36 additions and 1506 deletions

View File

@@ -29,7 +29,6 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.ui.editors,
org.eclipse.jface.text,
org.eclipse.ui.workbench,
org.yaml.snakeyaml,
org.eclipse.compare,
com.fasterxml.jackson.core.jackson-databind,
com.fasterxml.jackson.core.jackson-core,
@@ -72,7 +71,6 @@ Export-Package: org.springframework.ide.eclipse.boot.dash,
org.springframework.ide.eclipse.boot.dash.model.local,
org.springframework.ide.eclipse.boot.dash.model.remote,
org.springframework.ide.eclipse.boot.dash.model.runtargettypes,
org.springframework.ide.eclipse.boot.dash.ngrok,
org.springframework.ide.eclipse.boot.dash.util,
org.springframework.ide.eclipse.boot.dash.util.template,
org.springframework.ide.eclipse.boot.dash.views,
@@ -83,7 +81,6 @@ Import-Package: org.eclipse.core.runtime,
org.eclipse.core.runtime.preferences,
org.osgi.framework,
org.osgi.service.prefs,
org.yaml.snakeyaml,
com.google.gson;version="[2.9.1,2.10)",
com.google.gson.annotations;version="[2.9.1,2.10)",
com.google.gson.reflect;version="[2.9.1,2.10)",

View File

@@ -74,7 +74,7 @@ public class SelectRemoteEurekaDialog extends SelectionStatusDialog {
selectRemoteButton.setSelection(true);
tv = new TreeViewer(composite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI);
tv.setSorter(new BootModelViewerSorter(this.model));
tv.setComparator(new BootModelViewerSorter(this.model));
tv.getTree().setLinesVisible(true);
stylers = new Stylers(tv.getTree().getFont());
tv.setLabelProvider(new BootDashTreeLabelProvider(stylers, tv));

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015, 2020 Pivotal, Inc.
* Copyright (c) 2015, 2023 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
@@ -10,13 +10,19 @@
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.labels;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.*;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.DEFAULT_PATH;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.DEVTOOLS;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.HOST;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.INSTANCES;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.LIVE_PORT;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.NAME;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.PROGRESS;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.PROJECT;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.RUN_STATE_ICN;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.TAGS;
import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.TREE_VIEWER_MAIN;
import org.eclipse.core.resources.IProject;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
import org.eclipse.jface.resource.ImageDescriptor;
@@ -27,12 +33,9 @@ import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.PlatformUI;
import org.springframework.ide.eclipse.boot.core.BootPropertyTester;
import org.springframework.ide.eclipse.boot.dash.BootDashActivator;
import org.springframework.ide.eclipse.boot.dash.api.App;
import org.springframework.ide.eclipse.boot.dash.api.DevtoolsConnectable;
import org.springframework.ide.eclipse.boot.dash.api.Styleable;
//import org.springframework.ide.eclipse.boot.dash.cloudfoundry.CloudServiceInstanceDashElement;
import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext;
import org.springframework.ide.eclipse.boot.dash.model.AbstractLaunchConfigurationsDashElement;
import org.springframework.ide.eclipse.boot.dash.model.BootDashElement;
import org.springframework.ide.eclipse.boot.dash.model.BootDashModel;
import org.springframework.ide.eclipse.boot.dash.model.ButtonModel;
@@ -40,9 +43,6 @@ import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester;
import org.springframework.ide.eclipse.boot.dash.model.RefreshState;
import org.springframework.ide.eclipse.boot.dash.model.RunState;
import org.springframework.ide.eclipse.boot.dash.model.TagUtils;
import org.springframework.ide.eclipse.boot.dash.model.remote.GenericRemoteAppElement;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKClient;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKLaunchTracker;
import org.springframework.ide.eclipse.boot.dash.views.ImageDecorator;
import org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn;
import org.springsource.ide.eclipse.commons.frameworks.core.util.StringUtils;
@@ -463,31 +463,6 @@ public class BootDashLabels implements Disposable {
styledLabel = new StyledString(label, stylers.color(instancesColor));
}
}
} else if (column==EXPOSED_URL) {
RunState runState = element.getRunState();
if (runState == RunState.RUNNING || runState == RunState.DEBUGGING) {
List<String> tunnelNames = new ArrayList<>();
if (element instanceof AbstractLaunchConfigurationsDashElement<?>) {
ImmutableSet<ILaunchConfiguration> launches = ((AbstractLaunchConfigurationsDashElement<?>) element).getLaunchConfigs();
for (ILaunchConfiguration launchConfig : launches) {
tunnelNames.add(launchConfig.getName());
}
}
for (String tunnelName : tunnelNames) {
NGROKClient ngrokClient = NGROKLaunchTracker.get(tunnelName);
if (ngrokClient != null) {
Color color = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().get(ALT_TEXT_DECORATION_COLOR_THEME);
if (styledLabel == null) {
styledLabel = new StyledString("\u27A4 " + ngrokClient.getTunnel().getPublic_url(),stylers.color(color));
}
else {
styledLabel.append(new StyledString(" / \u27A4 " + ngrokClient.getTunnel().getPublic_url(),stylers.color(color)));
}
}
}
}
} else {
label = UNKNOWN_LABEL;
}

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015, 2020 Pivotal, Inc.
* Copyright (c) 2015, 2023 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
@@ -13,11 +13,7 @@ package org.springframework.ide.eclipse.boot.dash.model;
import java.time.Duration;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -27,12 +23,10 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.launching.SocketUtil;
import org.eclipse.swt.widgets.Display;
import org.springframework.ide.eclipse.beans.ui.live.model.LiveBeansModel;
import org.springframework.ide.eclipse.boot.dash.livexp.PollingLiveExp;
@@ -40,9 +34,6 @@ import org.springframework.ide.eclipse.boot.dash.model.actuator.ActuatorClient;
import org.springframework.ide.eclipse.boot.dash.model.actuator.JMXActuatorClient;
import org.springframework.ide.eclipse.boot.dash.model.actuator.RequestMapping;
import org.springframework.ide.eclipse.boot.dash.model.actuator.env.LiveEnvModel;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKClient;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKLaunchTracker;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKTunnel;
import org.springframework.ide.eclipse.boot.dash.util.CollectionUtils;
import org.springframework.ide.eclipse.boot.dash.util.LaunchConfRunStateTracker;
import org.springframework.ide.eclipse.boot.dash.util.RunStateTracker.RunStateListener;
@@ -175,7 +166,6 @@ public abstract class AbstractLaunchConfigurationsDashElement<T> extends Wrappin
}
try {
BootLaunchUtils.terminate(launches);
shutdownExpose();
} catch (Exception e) {
//why does terminating process with Eclipse debug UI fail so #$%# often?
Log.log(new Error("Termination of "+this+" failed", e));
@@ -417,7 +407,7 @@ public abstract class AbstractLaunchConfigurationsDashElement<T> extends Wrappin
protected LiveExpression<RunState> createRunStateExp() {
final LaunchConfRunStateTracker tracker = runStateTracker();
final LiveExpression<RunState> exp = new LiveExpression<RunState>() {
final LiveExpression<RunState> exp = new LiveExpression<>() {
protected RunState compute() {
AbstractLaunchConfigurationsDashElement<T> it = AbstractLaunchConfigurationsDashElement.this;
debug("Computing runstate for "+it);
@@ -440,7 +430,7 @@ public abstract class AbstractLaunchConfigurationsDashElement<T> extends Wrappin
super.dispose();
}
};
final RunStateListener<ILaunchConfiguration> runStateListener = new RunStateListener<ILaunchConfiguration>() {
final RunStateListener<ILaunchConfiguration> runStateListener = new RunStateListener<>() {
@Override
public void stateChanged(ILaunchConfiguration changedConf) {
if (getLaunchConfigs().contains(changedConf)) {
@@ -461,7 +451,7 @@ public abstract class AbstractLaunchConfigurationsDashElement<T> extends Wrappin
protected LiveExpression<Integer> createActualInstancesExp() {
final LaunchConfRunStateTracker tracker = runStateTracker();
final LiveExpression<Integer> exp = new LiveExpression<Integer>(0) {
final LiveExpression<Integer> exp = new LiveExpression<>(0) {
@Override
public String toString() {
return "LiveExp(actualInstances)";
@@ -476,7 +466,7 @@ public abstract class AbstractLaunchConfigurationsDashElement<T> extends Wrappin
return activeCount;
}
};
final RunStateListener<ILaunchConfiguration> runStateListener = new RunStateListener<ILaunchConfiguration>() {
final RunStateListener<ILaunchConfiguration> runStateListener = new RunStateListener<>() {
@Override
public void stateChanged(ILaunchConfiguration changedConf) {
if (getLaunchConfigs().contains(changedConf)) {
@@ -504,7 +494,7 @@ public abstract class AbstractLaunchConfigurationsDashElement<T> extends Wrappin
}
private LiveExpression<Integer> createLivePortExp(final LiveExpression<RunState> runState, final String propName) {
AsyncLiveExpression<Integer> exp = new AsyncLiveExpression<Integer>(-1, "Refreshing port info ("+propName+") for "+getName()) {
AsyncLiveExpression<Integer> exp = new AsyncLiveExpression<>(-1, "Refreshing port info ("+propName+") for "+getName()) {
{
//Doesn't really depend on runState, but should be recomputed when runState changes.
dependsOn(runState);
@@ -667,122 +657,6 @@ public abstract class AbstractLaunchConfigurationsDashElement<T> extends Wrappin
return -1;
}
public void restartAndExpose(RunState runMode, NGROKClient ngrokClient, String eurekaInstance, UserInteractions ui) throws Exception {
String launchMode = null;
if (RunState.RUNNING.equals(runMode)) {
launchMode = ILaunchManager.RUN_MODE;
}
else if (RunState.DEBUGGING.equals(runMode)) {
launchMode = ILaunchManager.DEBUG_MODE;
}
else {
throw new IllegalArgumentException("Restart and expose expects RUNNING or DEBUGGING as 'goal' state");
}
int port = getLivePort();
stopSync();
if (port <= 0) {
port = SocketUtil.findFreePort();
}
ILaunchConfiguration launchConfig = getOrCreateLaunchConfig(ui);
if (launchConfig != null) {
String tunnelName = launchConfig.getName();
NGROKTunnel tunnel = ngrokClient.startTunnel("http", Integer.toString(port));
NGROKLaunchTracker.add(tunnelName, ngrokClient, tunnel);
if (tunnel == null) {
ui.errorPopup("ngrok tunnel not started", "there was a problem starting the ngrok tunnel, try again or start a tunnel manually.");
return;
}
String tunnelURL = tunnel.getPublic_url();
if (tunnelURL.startsWith("http://")) {
tunnelURL = tunnelURL.substring(7);
}
Map<String, String> extraAttributes = new HashMap<>();
extraAttributes.put("spring.boot.prop.server.port", "1" + Integer.toString(port));
extraAttributes.put("spring.boot.prop.eureka.instance.hostname", "1" + tunnelURL);
extraAttributes.put("spring.boot.prop.eureka.instance.nonSecurePort", "1" + "80");
extraAttributes.put("spring.boot.prop.eureka.client.service-url.defaultZone", "1" + eurekaInstance);
start(launchMode, launchConfig, extraAttributes);
}
}
private void start(final String runMode, ILaunchConfiguration launchConfig, Map<String, String> extraAttributes) {
try {
if (launchConfig != null) {
ILaunchConfigurationWorkingCopy workingCopy = launchConfig.getWorkingCopy();
removeOverriddenAttributes(workingCopy, extraAttributes);
addAdditionalAttributes(workingCopy, extraAttributes);
launch(runMode, workingCopy);
}
} catch (Exception e) {
Log.log(e);
}
}
private void addAdditionalAttributes(ILaunchConfigurationWorkingCopy workingCopy, Map<String, String> extraAttributes) {
if (extraAttributes != null && extraAttributes.size() > 0) {
Iterator<String> iterator = extraAttributes.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
String value = extraAttributes.get(key);
workingCopy.setAttribute(key, value);
}
}
}
private void removeOverriddenAttributes(ILaunchConfigurationWorkingCopy workingCopy, Map<String, String> attributesToOverride) {
try {
Map<String, Object> attributes = workingCopy.getAttributes();
Set<String> keys = attributes.keySet();
Iterator<String> iter = keys.iterator();
while (iter.hasNext()) {
String existingKey = iter.next();
if (containsSimilarKey(attributesToOverride, existingKey)) {
workingCopy.removeAttribute(existingKey);
}
}
} catch (CoreException e) {
e.printStackTrace();
}
}
private boolean containsSimilarKey(Map<String, String> attributesToOverride, String existingKey) {
Iterator<String> iter = attributesToOverride.keySet().iterator();
while (iter.hasNext()) {
String overridingKey = iter.next();
if (existingKey.startsWith(overridingKey)) {
return true;
}
}
return false;
}
public void shutdownExpose() {
ImmutableSet<ILaunchConfiguration> launchConfigs = getLaunchConfigs();
for (ILaunchConfiguration launchConfig : launchConfigs) {
String tunnelName = launchConfig.getName();
NGROKClient client = NGROKLaunchTracker.get(tunnelName);
if (client != null) {
client.shutdown();
NGROKLaunchTracker.remove(tunnelName);
}
}
}
public void refreshLivePorts() {
refresh(livePort, actuatorPort);
}

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015, 2017 Pivotal, Inc.
* Copyright (c) 2015, 2023 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
@@ -29,8 +29,7 @@ public class LocalRunTarget extends AbstractRunTarget<Void> {
LIVE_PORT,
INSTANCES,
DEFAULT_PATH,
TAGS,
EXPOSED_URL
TAGS
};
private LocalRunTarget() {

View File

@@ -1,126 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.ngrok;
/**
* @author Martin Lippert
*/
public class NGROKClient {
private static int CREATE_TUNNEL_TIMEOUT_SECONDS = 6;
private String path;
private NGROKProcess process;
private NGROKTunnel tunnel;
public NGROKClient(String path) {
this.path = path;
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
if (process != null) {
process.terminate();
}
}
}));
}
public NGROKTunnel getTunnel() {
return tunnel;
}
public String getURL() {
return process != null ? process.getApiURL() : null;
}
public NGROKTunnel startTunnel(String proto, String addr) throws Exception {
// process = NGROKProcess.startNGROK(path, proto, addr);
// if (process != null) {
//
// boolean success = false;
// int seconds = 0;
//
// while (!success && seconds < CREATE_TUNNEL_TIMEOUT_SECONDS) {
// NGROKTunnel[] tunnels = retrieveTunnels();
// if (tunnels != null && tunnels.length > 0) {
// for (int i = 0; i < tunnels.length; i++) {
// if (tunnels[i].getAddr().endsWith(addr) && tunnels[i].getProto().equals(proto)) {
// tunnel = tunnels[i];
// return tunnel;
// }
// }
// }
// seconds++;
// Thread.sleep(1000);
// }
// }
//
return null;
}
public void shutdown() {
if (tunnel != null) {
shutdownTunnel(tunnel);
tunnel = null;
}
if (process != null) {
process.terminate();
process = null;
}
}
private NGROKTunnel[] retrieveTunnels() {
NGROKTunnel[] result = null;
// try {
// String response = Request.Get(process.getApiURL() + "/api/tunnels").execute().returnContent().asString();
//
// JSONObject jsonResponse = new JSONObject(response);
//
// JSONArray tunnels = jsonResponse.getJSONArray("tunnels");
// if (tunnels != null) {
// result = new NGROKTunnel[tunnels.length()];
// for (int i = 0; i < result.length; i++) {
// JSONObject tunnel = tunnels.getJSONObject(i);
// String name = tunnel.getString("name");
// String proto = tunnel.getString("proto");
// String public_url = tunnel.getString("public_url");
// String addr = tunnel.getJSONObject("config").getString("addr");
//
// result[i] = new NGROKTunnel(name, proto, public_url, addr);
// }
// }
// }
// catch (Exception e) {
// System.out.println(e);
// // do nothing, might be the case that the ngrok process is not yet up
// }
return result;
}
private void shutdownTunnel(NGROKTunnel ngrokTunnel) {
// try {
// String deleteURL = process.getApiURL() + "/api/tunnels/" + URLEncoder.encode(ngrokTunnel.getName(), "UTF-8");
// HttpResponse response = Request.Delete(deleteURL).execute().returnResponse();
// if (response.getStatusLine().getStatusCode() != 204) {
// System.err.println("errro closing tunnel");
// }
// } catch (ClientProtocolException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}

View File

@@ -1,445 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.ngrok;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.springframework.ide.eclipse.boot.core.BootActivator;
import org.springframework.ide.eclipse.boot.util.SWTFactory;
/**
* @author Christian Dupuis
* @author Steffen Pingel
* @author Kris De Volder
*/
public class NGROKInstallBlock implements ISelectionProvider {
private static final int defaultColumnWidth = 350;
class NGROKContentProvider implements IStructuredContentProvider {
public void dispose() {
}
public Object[] getElements(Object input) {
return ngroks.toArray();
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
class NGROKLabelProvider extends LabelProvider implements ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
public String getColumnText(Object element, int columnIndex) {
return element.toString();
}
}
private Composite control;
private final List<String> ngroks = new ArrayList<String>();
private CheckboxTableViewer ngrokList;
private Button addButton;
private Button removeButton;
private Button editButton;
private final ListenerList selectionListeners = new ListenerList();
private ISelection prevSelection = new StructuredSelection();
private Table table;
private NGROKInstallManager installManager;
public NGROKInstallBlock(NGROKInstallManager installManager) {
this.installManager = installManager;
}
public void addSelectionChangedListener(ISelectionChangedListener listener) {
selectionListeners.add(listener);
}
public void createControl(Composite ancestor) {
Font font = ancestor.getFont();
Composite parent = SWTFactory.createComposite(ancestor, font, 2, 1, GridData.FILL_BOTH);
control = parent;
SWTFactory.createLabel(parent, "ngrok Installations:", 2);
table = new Table(parent, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.heightHint = 250;
gd.widthHint = 350;
table.setLayoutData(gd);
table.setFont(font);
table.setHeaderVisible(true);
table.setLinesVisible(true);
TableColumn column = new TableColumn(table, SWT.NULL);
column.setText("Location");
column.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
sortByLocation();
}
});
ngrokList = new CheckboxTableViewer(table);
ngrokList.setLabelProvider(new NGROKLabelProvider());
ngrokList.setContentProvider(new NGROKContentProvider());
// by default, sort by name
sortByLocation();
ngrokList.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent evt) {
enableButtons();
}
});
ngrokList.addCheckStateListener(new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent event) {
if (event.getChecked()) {
setCheckedNGROK((String) event.getElement());
}
else {
setCheckedNGROK(null);
}
}
});
ngrokList.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent e) {
if (!ngrokList.getSelection().isEmpty()) {
editNGROK();
}
}
});
table.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent event) {
if (event.character == SWT.DEL && event.stateMask == 0) {
if (removeButton.isEnabled()) {
removeNGROKs();
}
}
}
});
Composite buttons = SWTFactory.createComposite(parent, font, 1, 1, GridData.VERTICAL_ALIGN_BEGINNING, 0, 0);
addButton = SWTFactory.createPushButton(buttons, "Add...", null);
addButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event evt) {
addNGROK();
}
});
editButton = SWTFactory.createPushButton(buttons, "Edit...", null);
editButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event evt) {
editNGROK();
}
});
removeButton = SWTFactory.createPushButton(buttons, "Remove...", null);
removeButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event evt) {
removeNGROKs();
}
});
SWTFactory.createVerticalSpacer(parent, 1);
fillWithWorkspaceNGROKs();
enableButtons();
addButton.setEnabled(true);
}
public String getCheckedNGROK() {
Object[] objects = ngrokList.getCheckedElements();
if (objects.length == 0) {
return null;
}
return (String) objects[0];
}
public Control getControl() {
return control;
}
public String[] getNGROKs() {
return ngroks.toArray(new String[ngroks.size()]);
}
public ISelection getSelection() {
return new StructuredSelection(ngrokList.getCheckedElements());
}
public boolean isDuplicateName(String name) {
for (int i = 0; i < ngroks.size(); i++) {
String ngrok = ngroks.get(i);
if (ngrok.equals(name)) {
return true;
}
}
return false;
}
public void removeNGROKs(String[] ngroksToBeRemoved) {
IStructuredSelection prev = (IStructuredSelection) getSelection();
for (String ngrok : ngroksToBeRemoved) {
ngroks.remove(ngrok);
}
ngrokList.refresh();
IStructuredSelection curr = (IStructuredSelection) getSelection();
if (!curr.equals(prev)) {
String[] installs = getNGROKs();
if (curr.size() == 0 && installs.length == 1) {
setSelection(new StructuredSelection(installs[0]));
}
else {
fireSelectionChanged();
}
}
}
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
selectionListeners.remove(listener);
}
public void restoreColumnSettings(IDialogSettings settings, String qualifier) {
ngrokList.getTable().layout(true);
restoreColumnWidths(settings, qualifier);
}
public void saveColumnSettings(IDialogSettings settings, String qualifier) {
int columnCount = table.getColumnCount();
for (int i = 0; i < columnCount; i++) {
settings.put(qualifier + ".columnWidth" + i, table.getColumn(i).getWidth()); //$NON-NLS-1$
}
}
public void setCheckedNGROK(String vm) {
if (vm == null) {
setSelection(new StructuredSelection());
}
else {
setSelection(new StructuredSelection(vm));
}
}
public void setSelection(ISelection selection) {
if (selection instanceof IStructuredSelection) {
if (!selection.equals(prevSelection)) {
prevSelection = selection;
Object ngrok = ((IStructuredSelection) selection).getFirstElement();
if (ngrok == null) {
ngrokList.setCheckedElements(new Object[0]);
}
else {
ngrokList.setCheckedElements(new Object[] { ngrok });
ngrokList.reveal(ngrok);
}
fireSelectionChanged();
}
}
}
public void ngrokAdded(String ngrok) {
ngroks.add(ngrok);
ngrokList.refresh();
}
private void addNGROK() {
try {
FileDialog fileDialog = new FileDialog(control.getShell());
fileDialog.setText("select ngrok executable");
String result = fileDialog.open();
if (result != null) {
ngroks.add(result);
ngrokList.refresh();
ngrokList.setSelection(new StructuredSelection(result));
setSelection(new StructuredSelection(result));
}
} catch (Exception e) {
BootActivator.log(e);
}
}
private void editNGROK() {
IStructuredSelection selection = (IStructuredSelection) ngrokList.getSelection();
String ngrok = (String) selection.getFirstElement();
if (ngrok == null) {
return;
}
FileDialog fileDialog = new FileDialog(control.getShell());
fileDialog.setText("select ngrok executable");
fileDialog.setFileName(ngrok);
String result = fileDialog.open();
if (result != null) {
// replace with the edited VM
int index = ngroks.indexOf(ngrok);
ngroks.remove(index);
ngroks.add(index, result);
ngrokList.refresh();
ngrokList.setSelection(new StructuredSelection(result));
}
}
private void enableButtons() {
IStructuredSelection selection = (IStructuredSelection) ngrokList.getSelection();
int selectionCount = selection.size();
editButton.setEnabled(selectionCount == 1);
if (selectionCount > 0 && selectionCount < ngrokList.getTable().getItemCount()) {
removeButton.setEnabled(true);
}
else {
removeButton.setEnabled(false);
}
}
private void fireSelectionChanged() {
SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());
Object[] listeners = selectionListeners.getListeners();
for (Object listener2 : listeners) {
ISelectionChangedListener listener = (ISelectionChangedListener) listener2;
listener.selectionChanged(event);
}
}
private void removeNGROKs() {
IStructuredSelection selection = (IStructuredSelection) ngrokList.getSelection();
String[] ngroks = new String[selection.size()];
Iterator<String> iter = selection.iterator();
int i = 0;
while (iter.hasNext()) {
ngroks[i] = iter.next();
i++;
}
removeNGROKs(ngroks);
}
private void restoreColumnWidths(IDialogSettings settings, String qualifier) {
int columnCount = table.getColumnCount();
for (int i = 0; i < columnCount; i++) {
int width = -1;
try {
width = settings.getInt(qualifier + ".columnWidth" + i); //$NON-NLS-1$
}
catch (NumberFormatException e) {
}
if (width <= 0) {
table.getColumn(i).setWidth(defaultColumnWidth);
}
else {
table.getColumn(i).setWidth(width);
}
}
}
private void sortByLocation() {
ngrokList.setComparator(new ViewerComparator() {
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
if ((e1 instanceof String) && (e2 instanceof String)) {
String left = (String) e1;
String right = (String) e2;
return left.compareToIgnoreCase(right);
}
return super.compare(viewer, e1, e2);
}
@Override
public boolean isSorterProperty(Object element, String property) {
return true;
}
});
}
protected void fillWithWorkspaceNGROKs() {
Collection<String> installs = installManager.getInstalls();
String deflt = null;
try {
deflt = installManager.getDefaultInstall();
} catch (Exception e) {
BootActivator.log(e);
}
setNGROKs(installs.toArray(new String[installs.size()]), deflt);
}
protected Shell getShell() {
return getControl().getShell();
}
protected void setNGROKs(String[] newNgroks, String dflt) {
ngroks.clear();
for (String ngrok : newNgroks) {
ngroks.add(ngrok);
}
ngrokList.setInput(ngroks);
ngrokList.refresh();
for (String ngrok : newNgroks) {
if (ngrok.equals(dflt)) {
setCheckedNGROK(ngrok);
}
}
}
}

View File

@@ -1,136 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.ngrok;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.BackingStoreException;
import org.springframework.ide.eclipse.boot.core.BootActivator;
import org.springframework.ide.eclipse.boot.dash.BootDashActivator;
import org.springsource.ide.eclipse.commons.frameworks.core.util.ArrayEncoder;
/**
* Manages the ngrok installations that are configured in this workspace.
*
* @author Martin Lippert
* @author Kris De Volder
*/
public class NGROKInstallManager {
private static final String NGROK_INSTALLS = "ngroks"; //Key used to store info in the prefs.
private static final String DEFAULT_NGROK_INSTALL = "default.ngrok";
private static NGROKInstallManager instance;
public static NGROKInstallManager getInstance() {
if (instance==null) {
instance = new NGROKInstallManager();
}
return instance;
}
private List<String> installs = null;
private String defaultInstall;
private NGROKInstallManager() {
installs = new CopyOnWriteArrayList<String>();
read();
}
private void read() {
IEclipsePreferences prefs = getPrefs();
String defaultName = prefs.get(DEFAULT_NGROK_INSTALL, "");
String encoded = prefs.get(NGROK_INSTALLS, null);
if (encoded!=null) {
String[] encodedInstalls = ArrayEncoder.decode(encoded);
for (String encodedInstall : encodedInstalls) {
try {
String[] parts = ArrayEncoder.decode(encodedInstall);
String install = parts[0];
installs.add(install);
if (defaultName.equals(install)) {
setDefaultInstall(install);
}
} catch (Exception e) {
BootActivator.log(e);
}
}
}
}
protected IEclipsePreferences getPrefs() {
return InstanceScope.INSTANCE.getNode(BootDashActivator.PLUGIN_ID);
}
public void save() {
List<String> local = installs;
String[] encodedInstalls = new String[local.size()];
for (int i = 0; i < encodedInstalls.length; i++) {
encodedInstalls[i] = encodeInstall(local.get(i));
}
String encoded = ArrayEncoder.encode(encodedInstalls);
IEclipsePreferences prefs = getPrefs();
prefs.put(NGROK_INSTALLS, encoded);
String di = null;
try {
di = getDefaultInstall();
} catch (Exception e) {
BootActivator.log(e);
}
if (di==null) {
prefs.remove(DEFAULT_NGROK_INSTALL);
} else {
prefs.put(DEFAULT_NGROK_INSTALL, di);
}
try {
prefs.flush();
} catch (BackingStoreException e) {
BootActivator.log(e);
}
}
private String encodeInstall(String install) {
return ArrayEncoder.encode(new String[] { install});
}
public synchronized String getDefaultInstall() {
return defaultInstall;
}
public void setDefaultInstall(String defaultInstall) {
if (!installs.contains(defaultInstall)) {
installs.add(defaultInstall);
}
this.defaultInstall = defaultInstall;
}
public void setInstalls(Collection<String> newInstalls) {
this.installs = new CopyOnWriteArrayList<String>(newInstalls);
}
public Collection<String> getInstalls() {
return new ArrayList<String>(installs);
}
public void addInstall(String ngrokInstall) {
this.installs.add(ngrokInstall);
}
}

View File

@@ -1,35 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015, 2016 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.ngrok;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Martin Lippert
*/
public class NGROKLaunchTracker {
private static Map<String, NGROKClient> tunnels = new ConcurrentHashMap<String, NGROKClient>();
public static void add(String tunnelName, NGROKClient ngrokClient, NGROKTunnel tunnel) {
tunnels.put(tunnelName, ngrokClient);
}
public static NGROKClient get(String tunnelName) {
return tunnels.get(tunnelName);
}
public static void remove(String tunnelName) {
tunnels.remove(tunnelName);
}
}

View File

@@ -1,69 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.ngrok;
import java.io.File;
import java.io.FileWriter;
import org.eclipse.jdt.launching.SocketUtil;
/**
* @author Martin Lippert
*/
public class NGROKProcess {
private final Process process;
private final String apiURL;
public static NGROKProcess startNGROK(String path, String proto, String addr) throws Exception {
FileWriter fileWriter = null;
try {
int freePort = SocketUtil.findFreePort();
String webAddr = "localhost:" + freePort;
File ngrokConfigFile = File.createTempFile("ngrok-config", "yml");
ngrokConfigFile.deleteOnExit();
fileWriter = new FileWriter(ngrokConfigFile);
fileWriter.write("web_addr: " + webAddr + "\n");
fileWriter.close();
String configFileArg = "-config=" + ngrokConfigFile.getAbsolutePath();
ProcessBuilder processBuilder = new ProcessBuilder(path, proto, configFileArg, addr);
Process process = processBuilder.start();
return new NGROKProcess(process, "http://" + webAddr);
}
finally {
if (fileWriter != null) {
fileWriter.close();
}
}
}
public NGROKProcess(Process process, String apiURL) {
this.process = process;
this.apiURL = apiURL;
}
public String getApiURL() {
return apiURL;
}
public void terminate() {
if (this.process != null) {
this.process.destroy();
}
}
}

View File

@@ -1,95 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.ngrok;
/**
* @author Martin Lippert
*/
public class NGROKTunnel {
private String name;
private String proto;
private String public_url;
private String addr;
public NGROKTunnel(String name, String proto, String public_url, String addr) {
super();
this.name = name;
this.proto = proto;
this.public_url = public_url;
this.addr = addr;
}
public String getName() {
return name;
}
public String getProto() {
return proto;
}
public String getPublic_url() {
return public_url;
}
public String getAddr() {
return addr;
}
@Override
public String toString() {
return "NGROKTunnel [name=" + name + ", proto=" + proto + ", public_url=" + public_url + ", addr=" + addr + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((addr == null) ? 0 : addr.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((proto == null) ? 0 : proto.hashCode());
result = prime * result + ((public_url == null) ? 0 : public_url.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NGROKTunnel other = (NGROKTunnel) obj;
if (addr == null) {
if (other.addr != null)
return false;
} else if (!addr.equals(other.addr))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (proto == null) {
if (other.proto != null)
return false;
} else if (!proto.equals(other.proto))
return false;
if (public_url == null) {
if (other.public_url != null)
return false;
} else if (!public_url.equals(other.public_url))
return false;
return true;
}
}

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015, 2020 Pivotal, Inc.
* Copyright (c) 2015, 2023 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
@@ -49,7 +49,6 @@ import org.springframework.ide.eclipse.boot.dash.model.remote.GenericRemoteAppEl
import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.LocalRunTargetType;
import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.RemoteRunTarget;
import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.RemoteRunTargetType;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKInstallManager;
import org.springframework.ide.eclipse.boot.dash.prefs.BootDashPrefsPage;
import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashAction.Location;
import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashElementsAction.Params;
@@ -76,14 +75,11 @@ public class BootDashActions {
private LinkWithConsoleAction linkWithConsoleAction;
private OpenLaunchConfigAction openConfigAction;
private OpenInBrowserAction openBrowserAction;
private OpenNgrokAdminUi openNgrokAdminUi;
private OpenInPackageExplorer openInPackageExplorerAction;
private AddRunTargetAction[] addTargetActions;
private RefreshRunTargetAction refreshAction;
private RemoveRunTargetAction removeTargetAction;
private ShowViewAction showPropertiesViewAction;
private ExposeAppAction exposeRunAppAction;
private ExposeAppAction exposeDebugAppAction;
private OpenPreferencesAction openBootDashPreferencesAction;
@@ -278,7 +274,6 @@ public class BootDashActions {
openConsoleAction = new OpenConsoleAction(defaultActionParams());
linkWithConsoleAction = new LinkWithConsoleAction(defaultActionParams().setStyle(IAction.AS_CHECK_BOX));
openBrowserAction = new OpenInBrowserAction(defaultActionParams());
openNgrokAdminUi = new OpenNgrokAdminUi(defaultActionParams());
openInPackageExplorerAction = new OpenInPackageExplorer(defaultActionParams());
addTargetActions = createAddTargetActions();
@@ -300,18 +295,6 @@ public class BootDashActions {
toggleFiltersDialogAction = new OpenToggleFiltersDialogAction(model.getToggleFilters(), elementsSelection, context);
exposeRunAppAction = new ExposeAppAction(defaultActionParams(), RunState.RUNNING, NGROKInstallManager.getInstance());
exposeRunAppAction.setText("(Re)start and Expose via ngrok");
exposeRunAppAction.setToolTipText("Start or restart the process associated with the selected elements and expose it to the outside world via an ngrok tunnel");
exposeRunAppAction.setImageDescriptor(BootDashActivator.getImageDescriptor("icons/restart.png"));
exposeRunAppAction.setDisabledImageDescriptor(BootDashActivator.getImageDescriptor("icons/restart_disabled.png"));
exposeDebugAppAction = new ExposeAppAction(defaultActionParams(), RunState.DEBUGGING, NGROKInstallManager.getInstance());
exposeDebugAppAction.setText("(Re)debug and Expose via ngrok");
exposeDebugAppAction.setToolTipText("Start or restart the process associated with the selected elements in debug mode and expose it to the outside world via an ngrok tunnel");
exposeDebugAppAction.setImageDescriptor(BootDashActivator.getImageDescriptor("icons/rebug.png"));
exposeDebugAppAction.setDisabledImageDescriptor(BootDashActivator.getImageDescriptor("icons/rebug_disabled.png"));
duplicateConfigAction = new DuplicateConfigAction(defaultActionParams());
debugOnTargetActions = createDeployOnTargetActions(RunState.DEBUGGING);
@@ -458,10 +441,6 @@ public class BootDashActions {
return openBrowserAction;
}
public AbstractBootDashElementsAction getOpenNgrokAdminUi() {
return openNgrokAdminUi;
}
public AbstractBootDashElementsAction getOpenConsoleAction() {
return openConsoleAction;
}
@@ -512,14 +491,6 @@ public class BootDashActions {
return showPropertiesViewAction;
}
public IAction getExposeRunAppAction() {
return exposeRunAppAction;
}
public IAction getExposeDebugAppAction() {
return exposeDebugAppAction;
}
public EnableRemoteDevtoolsAction getEnableDevtoolsAction() {
return enableRemoteDevtoolsAction;
}
@@ -558,15 +529,6 @@ public class BootDashActions {
toggleFiltersDialogAction = null;
}
if (exposeRunAppAction != null) {
exposeRunAppAction.dispose();
exposeRunAppAction = null;
}
if (exposeDebugAppAction != null) {
exposeDebugAppAction.dispose();
exposeDebugAppAction = null;
}
if (duplicateConfigAction != null) {
duplicateConfigAction.dispose();
duplicateConfigAction = null;
@@ -618,7 +580,7 @@ public class BootDashActions {
private DisposingFactory<RunTarget, AbstractBootDashAction> createDeployOnTargetActions(final RunState runningOrDebugging) {
ObservableSet<RunTarget> runtargets = model.getRunTargets();
return new DisposingFactory<RunTarget, AbstractBootDashAction>(runtargets) {
return new DisposingFactory<>(runtargets) {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
protected AbstractBootDashAction create(RunTarget target) {

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015, 2021 VMware, Inc.
* Copyright (c) 2015, 2023 VMware, 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
@@ -182,7 +182,6 @@ public class BootDashTreeView extends ViewPartWithSections implements ITabbedPro
// BootDashUnifiedTreeSection.addVisible(manager, a);
}
manager.add(actions.getOpenBrowserAction());
manager.add(actions.getOpenNgrokAdminUi());
manager.add(actions.getOpenConsoleAction());
manager.add(actions.getLinkWithConsoleAction());
manager.add(actions.getOpenInPackageExplorerAction());
@@ -192,10 +191,6 @@ public class BootDashTreeView extends ViewPartWithSections implements ITabbedPro
MenuUtil.addDynamicSubmenu(manager, actions.getLiveDataConnectionManagement());
manager.add(new Separator());
manager.add(actions.getExposeRunAppAction());
manager.add(actions.getExposeDebugAppAction());
manager.add(new Separator());
addAddRunTargetMenuActions(manager);

View File

@@ -1,155 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015, 2020 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.views;
import java.util.Collection;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.springframework.ide.eclipse.boot.core.BootActivator;
import org.springframework.ide.eclipse.boot.dash.model.AbstractLaunchConfigurationsDashElement;
import org.springframework.ide.eclipse.boot.dash.model.BootDashElement;
import org.springframework.ide.eclipse.boot.dash.model.BootDashModel.ElementStateListener;
import org.springframework.ide.eclipse.boot.dash.model.LocalCloudServiceDashElement;
import org.springframework.ide.eclipse.boot.dash.model.RunState;
import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.RunTargetTypes;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKClient;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKInstallManager;
/**
* @author Martin Lippert
*/
public class ExposeAppAction extends RunStateAction {
private NGROKInstallManager ngrokManager;
public ExposeAppAction(Params params, final RunState goalState, final NGROKInstallManager ngrokManager) {
super(params, goalState);
Assert.isLegal(goalState == RunState.RUNNING || goalState == RunState.DEBUGGING);
this.ngrokManager = ngrokManager;
model.addElementStateListener(new ElementStateListener() {
@Override
public void stateChanged(BootDashElement e) {
if (e instanceof AbstractLaunchConfigurationsDashElement<?> && RunState.INACTIVE.equals(e.getRunState())) {
try {
AbstractLaunchConfigurationsDashElement<?> localDashProject = (AbstractLaunchConfigurationsDashElement<?>) e;
localDashProject.shutdownExpose();
} catch (Exception ex) {
ui().errorPopup("error shutting down tunnel", "error shutting down tunnel");
}
}
}
});
}
@Override
protected boolean appliesToElement(BootDashElement bootDashElement) {
return bootDashElement.getTarget().getType().equals(RunTargetTypes.LOCAL) && !(bootDashElement instanceof LocalCloudServiceDashElement);
}
@Override
protected Job createJob() {
final Collection<BootDashElement> selecteds = getSelectedElements();
if (!selecteds.isEmpty()) {
boolean riskAccepted = ui().confirmWithToggle("ngrok.tunnel.warning.state", "Really Expose local service on public internet?",
"The ngrok tunnel uses a third-party server to pass all data between your local app and its clients over a public internet connection.\n\n" +
"Do you really want to do this?",
null);
if (riskAccepted) {
String ngrokInstall = this.ngrokManager.getDefaultInstall();
if (ngrokInstall == null) {
ngrokInstall = ui().chooseFile("ngrok installation", null);
if (ngrokInstall != null) {
this.ngrokManager.addInstall(ngrokInstall);
this.ngrokManager.setDefaultInstall(ngrokInstall);
this.ngrokManager.save();
}
}
if (ngrokInstall != null) {
final NGROKClient ngrokClient = new NGROKClient(ngrokInstall);
final String eurekaInstance = getEurekaInstance();
if (eurekaInstance != null) {
return new Job("Restarting and Exposing " + selecteds.size() + " Dash Elements") {
@Override
public IStatus run(IProgressMonitor monitor) {
monitor.beginTask("Restart and Expose Boot Dash Elements", selecteds.size());
try {
for (BootDashElement el : selecteds) {
if (el instanceof AbstractLaunchConfigurationsDashElement<?>) {
monitor.subTask("Restarting: " + el.getName());
try {
AbstractLaunchConfigurationsDashElement<?> localDashProject = (AbstractLaunchConfigurationsDashElement<?>) el;
localDashProject.restartAndExpose(getGoalState(), ngrokClient, eurekaInstance, ui());
} catch (Exception e) {
return BootActivator.createErrorStatus(e);
}
}
monitor.worked(1);
}
return Status.OK_STATUS;
} finally {
monitor.done();
}
}
};
}
}
}
}
return null;
}
private String getEurekaInstance() {
String eurekaInstance = ui().selectRemoteEureka(model, "Eureka URL", "please enter the full URL of the Eureka instance you would like to use", "", null);
if (eurekaInstance != null) {
if (eurekaInstance.endsWith("/eureka") || eurekaInstance.endsWith("/eureka/")) {
return eurekaInstance;
}
else if (eurekaInstance.endsWith("/")) {
eurekaInstance = eurekaInstance + "eureka/";
}
else {
eurekaInstance = eurekaInstance + "/eureka/";
}
}
return eurekaInstance;
}
@Override
public void updateVisibility() {
boolean visible = !getSelectedElements().isEmpty();
for (BootDashElement e : getSelectedElements()) {
if (!RunTargetTypes.LOCAL.equals(e.getTarget().getType())) {
visible = false;
break;
}
}
setVisible(visible);
}
@Override
public void dispose() {
super.dispose();
}
}

View File

@@ -1,69 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016, 2017 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.views;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.springframework.ide.eclipse.boot.dash.BootDashActivator;
import org.springframework.ide.eclipse.boot.dash.model.BootDashElement;
import org.springframework.ide.eclipse.boot.dash.model.LocalRunTarget;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKClient;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKLaunchTracker;
import com.google.common.collect.ImmutableSet;
public class OpenNgrokAdminUi extends AbstractBootDashElementsAction {
public OpenNgrokAdminUi(Params params) {
super(params);
this.setText("Open Ngrok Admin UI");
this.setToolTipText("Opens Ngrok Admin UI for this app in a Web Browser");
this.setImageDescriptor(BootDashActivator.getImageDescriptor("icons/open_browser.png")); //TODO: different icon?
this.setDisabledImageDescriptor(BootDashActivator.getImageDescriptor("icons/open_browser_disabled.png"));
}
@Override
public void updateVisibility() {
// Visible if at least one local app is selected
this.setVisible(getSelectedElements().stream().anyMatch(this::isLocalApp));
}
@Override
public void updateEnablement() {
BootDashElement selected = getSingleSelectedElement();
this.setEnabled(selected != null && getClient(selected) != null);
}
private NGROKClient getClient(BootDashElement bde) {
if (isLocalApp(bde)) {
ImmutableSet<ILaunchConfiguration> launchConfigs = bde.getLaunchConfigs();
if (launchConfigs.size() == 1) {
return NGROKLaunchTracker.get(launchConfigs.iterator().next().getName());
}
}
return null;
}
boolean isLocalApp(BootDashElement bde) {
return bde != null && bde.getTarget() instanceof LocalRunTarget;
}
@Override
public void run() {
NGROKClient client = getClient(getSingleSelectedElement());
if (client != null) {
String url = client.getURL();
if (url != null) {
ui().openUrl(url);
}
}
}
}

View File

@@ -1,95 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015, 2016 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.views.properties;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.springframework.ide.eclipse.boot.dash.model.AbstractLaunchConfigurationsDashElement;
import org.springframework.ide.eclipse.boot.dash.model.BootDashElement;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKClient;
import org.springframework.ide.eclipse.boot.dash.ngrok.NGROKLaunchTracker;
import org.springsource.ide.eclipse.commons.ui.UiUtil;
import com.google.common.collect.ImmutableSet;
/**
* @author Martin Lippert
*/
public class ExposedPropertyControl extends AbstractBdePropertyControl {
private Link exposedURL;
@Override
public void createControl(Composite composite, TabbedPropertySheetPage page) {
super.createControl(composite, page);
page.getWidgetFactory().createLabel(composite, "Exposed via:").setLayoutData(GridDataFactory.fillDefaults().create()); //$NON-NLS-1$
exposedURL = new Link(composite, SWT.NONE);
exposedURL.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
exposedURL.setBackground(composite.getBackground());
exposedURL.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
AbstractLaunchConfigurationsDashElement<?> bde = getLocalBootDashElement();
if (bde != null) {
ImmutableSet<ILaunchConfiguration> launchConfigs = bde.getLaunchConfigs();
if (launchConfigs.size() == 1) {
String tunnelName = launchConfigs.iterator().next().getName();
NGROKClient ngrokClient = NGROKLaunchTracker.get(tunnelName);
if (ngrokClient != null) {
String addr = ngrokClient.getURL();
UiUtil.openUrl(addr);
}
}
}
}
});
}
@Override
public void refreshControl() {
AbstractLaunchConfigurationsDashElement<?> bde = getLocalBootDashElement();
if (bde != null) {
StringBuilder labelText = new StringBuilder();
ImmutableSet<ILaunchConfiguration> configs = bde.getLaunchConfigs();
if (configs.size() == 1) {
String tunnelName = configs.iterator().next().getName();
NGROKClient ngrokClient = NGROKLaunchTracker.get(tunnelName);
if (ngrokClient != null) {
labelText.append(ngrokClient.getTunnel().getPublic_url() + " --- (local ngrok instance at: <a href=\"\">" + ngrokClient.getURL() + "</a>)");
}
}
exposedURL.setText(labelText.toString());
}
}
private AbstractLaunchConfigurationsDashElement<?> getLocalBootDashElement() {
if (exposedURL != null && !exposedURL.isDisposed()) {
BootDashElement bde = getBootDashElement();
if (bde instanceof AbstractLaunchConfigurationsDashElement<?>) {
return (AbstractLaunchConfigurationsDashElement<?>) bde;
}
}
return null;
}
}

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015, 2016 Pivotal, Inc.
* Copyright (c) 2015, 2023 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
@@ -29,8 +29,7 @@ public class LocalGeneralPropertiesSection extends AbstractBdeGeneralPropertiesS
new AppPropertyControl(),
new UrlPropertyControl<>(BootDashElement.class, "URL:", (e) -> e.getUrl()),
new DefaultPathPropertyControl(),
new TagsPropertyControl(),
new ExposedPropertyControl()
new TagsPropertyControl()
};
}

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015, 2020 Pivotal, Inc.
* Copyright (c) 2015, 2023 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
@@ -31,7 +31,6 @@ public class BootDashColumn {
public static final BootDashColumn LIVE_PORT = new BootDashColumn("LIVE_PORT");
public static final BootDashColumn DEFAULT_PATH = new BootDashColumn("DEFAULT_PATH");
public static final BootDashColumn TAGS = new BootDashColumn("TAGS");
public static final BootDashColumn EXPOSED_URL = new BootDashColumn("EXPOSED_URL");
public static final BootDashColumn DEVTOOLS = new BootDashColumn("DEVTOOLS");
public static final BootDashColumn TREE_VIEWER_MAIN = new BootDashColumn("TREE_VIEWER_MAIN"); //this is a 'fake' column which corresponds to the single column shown in unified tree viewer.
public static final BootDashColumn PROGRESS = new BootDashColumn("PROGRESS");

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015, 2019 Pivotal, Inc.
* Copyright (c) 2015, 2023 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
@@ -42,8 +42,8 @@ import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceAdapter;
@@ -154,7 +154,7 @@ public class BootDashUnifiedTreeSection extends PageSection implements MultiSele
}
};
public static class BootModelViewerSorter extends ViewerSorter {
public static class BootModelViewerSorter extends ViewerComparator {
private final BootDashViewModel viewModel;
@@ -186,7 +186,7 @@ public class BootDashUnifiedTreeSection extends PageSection implements MultiSele
}
}
final private ValueListener<Filter<BootDashElement>> FILTER_LISTENER = new UIValueListener<Filter<BootDashElement>>() {
final private ValueListener<Filter<BootDashElement>> FILTER_LISTENER = new UIValueListener<>() {
public void uiGotValue(LiveExpression<Filter<BootDashElement>> exp, Filter<BootDashElement> value) {
tv.refresh();
final Tree t = tv.getTree();
@@ -234,7 +234,7 @@ public class BootDashUnifiedTreeSection extends PageSection implements MultiSele
}
};
final private ValueListener<ImmutableSet<RunTarget>> RUN_TARGET_LISTENER = new UIValueListener<ImmutableSet<RunTarget>>() {
final private ValueListener<ImmutableSet<RunTarget>> RUN_TARGET_LISTENER = new UIValueListener<>() {
protected void uiGotValue(LiveExpression<ImmutableSet<RunTarget>> exp, ImmutableSet<RunTarget> value) {
if (tv != null && !tv.getControl().isDisposed()) {
tv.refresh();
@@ -264,7 +264,7 @@ public class BootDashUnifiedTreeSection extends PageSection implements MultiSele
* Listener which adds element set listener to each section model.
*/
@SuppressWarnings("unchecked")
final private ValueListener<ImmutableSet<BootDashModel>> ELEMENTS_SET_LISTENER_ADAPTER = new ElementwiseListener<BootDashModel>() {
final private ValueListener<ImmutableSet<BootDashModel>> ELEMENTS_SET_LISTENER_ADAPTER = new ElementwiseListener<>() {
protected void added(LiveExpression<ImmutableSet<BootDashModel>> exp, BootDashModel e) {
e.getElements().addListener((ValueListener<ImmutableSet<BootDashElement>>) ELEMENTS_SET_LISTENER);
e.getButtons().addListener((ValueListener<ImmutableSet<ButtonModel>>) ELEMENTS_SET_LISTENER);
@@ -326,7 +326,7 @@ public class BootDashUnifiedTreeSection extends PageSection implements MultiSele
tv = new CustomTreeViewer(page, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI);
tv.setExpandPreCheckFilters(true);
tv.setContentProvider(new BootDashTreeContentProvider());
tv.setSorter(new BootModelViewerSorter(this.model));
tv.setComparator(new BootModelViewerSorter(this.model));
tv.setInput(model);
tv.getTree().setLinesVisible(false);
@@ -465,7 +465,7 @@ public class BootDashUnifiedTreeSection extends PageSection implements MultiSele
private synchronized MultiSelection<Object> getMixedSelection() {
if (mixedSelection==null) {
mixedSelection = MultiSelection.from(Object.class, new ObservableSet<Object>() {
mixedSelection = MultiSelection.from(Object.class, new ObservableSet<>() {
@Override
protected ImmutableSet<Object> compute() {
if (tv!=null) {
@@ -527,7 +527,6 @@ public class BootDashUnifiedTreeSection extends PageSection implements MultiSele
addVisible(manager, a);
}
addVisible(manager, actions.getOpenBrowserAction());
addVisible(manager, actions.getOpenNgrokAdminUi());
addVisible(manager, actions.getOpenConsoleAction());
addVisible(manager, actions.getOpenInPackageExplorerAction());
addVisible(manager, actions.getShowPropertiesViewAction());
@@ -541,8 +540,6 @@ public class BootDashUnifiedTreeSection extends PageSection implements MultiSele
manager.add(new Separator());
addVisible(manager, actions.getExposeRunAppAction());
addVisible(manager, actions.getExposeDebugAppAction());
addSubmenu(manager, "Deploy and Run On...", BootDashActivator.getImageDescriptor("icons/run-on-cloud.png"), actions.getRunOnTargetActions());
addSubmenu(manager, "Deploy and Debug On...", BootDashActivator.getImageDescriptor("icons/debug-on-cloud.png"), actions.getDebugOnTargetActions());
manager.add(new Separator());