diff --git a/eclipse-distribution/local-build.sh b/eclipse-distribution/local-build.sh index 61f0352d8..b83c97154 100755 --- a/eclipse-distribution/local-build.sh +++ b/eclipse-distribution/local-build.sh @@ -1,2 +1,2 @@ -mvn clean package -Pe426 -Psnapshot -Dsigning.skip=true -Dhttpclient.retry-max=20 -Dmaven.test.skip=true -Declipse.p2.mirrors=false -Dtycho.localArtifacts=ignore -Dorg.eclipse.equinox.p2.transport.ecf.retry=5 -Dskip.osx.signing=true -Dskip.win.signing=true -Dskip.osx.notarizing=true +mvn clean package -Pe427 -Psnapshot -Dsigning.skip=true -Dhttpclient.retry-max=20 -Dmaven.test.skip=true -Declipse.p2.mirrors=false -Dtycho.localArtifacts=ignore -Dorg.eclipse.equinox.p2.transport.ecf.retry=5 -Dskip.osx.signing=true -Dskip.win.signing=true -Dskip.osx.notarizing=true diff --git a/eclipse-distribution/org.springframework.boot.ide.product.e418/.project b/eclipse-distribution/org.springframework.boot.ide.product.e418/.project new file mode 100644 index 000000000..c44e92d12 --- /dev/null +++ b/eclipse-distribution/org.springframework.boot.ide.product.e418/.project @@ -0,0 +1,17 @@ + + + org.springframework.boot.ide.product.e418 + + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + + diff --git a/eclipse-distribution/pom.xml b/eclipse-distribution/pom.xml index 81cee1e11..58d973799 100644 --- a/eclipse-distribution/pom.xml +++ b/eclipse-distribution/pom.xml @@ -55,14 +55,12 @@ ../eclipse-extensions/org.springframework.ide.eclipse.boot.validation ../eclipse-extensions/org.springframework.ide.eclipse.boot.wizard ../eclipse-extensions/org.springframework.ide.eclipse.boot.dash.azure - ../eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf ../eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker ../eclipse-extensions/org.springframework.ide.eclipse.boot.dash.feature ../eclipse-extensions/org.springframework.ide.eclipse.docker.client ../eclipse-extensions/org.springframework.ide.eclipse.maven.pom ../eclipse-extensions/org.springframework.ide.eclipse.xml.namespaces ../eclipse-extensions/org.springframework.ide.eclipse.xml.namespaces.feature - ../eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2 diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.classpath b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.classpath deleted file mode 100644 index fb0c5b007..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.classpath +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.project b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.project deleted file mode 100644 index ebd4c7802..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.springframework.ide.eclipse.boot.dash.cf - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.settings/org.eclipse.jdt.core.prefs b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 9f6ece88b..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,8 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.settings/org.eclipse.jdt.ui.prefs b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index c743e1c07..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,59 +0,0 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_functional_interfaces=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=false -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.insert_inferred_type_arguments=false -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=false -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_redundant_type_arguments=false -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=false -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_anonymous_class_creation=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_lambda=true -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.settings/org.springframework.ide.eclipse.prefs b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.settings/org.springframework.ide.eclipse.prefs deleted file mode 100644 index a12794d68..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/.settings/org.springframework.ide.eclipse.prefs +++ /dev/null @@ -1,2 +0,0 @@ -boot.validation.initialized=true -eclipse.preferences.version=1 diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/META-INF/MANIFEST.MF b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/META-INF/MANIFEST.MF deleted file mode 100755 index 4519eaac9..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/META-INF/MANIFEST.MF +++ /dev/null @@ -1,79 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-SymbolicName: org.springframework.ide.eclipse.boot.dash.cf;singleton:=true -Bundle-Version: 4.18.0.qualifier -Bundle-Vendor: VMware, Inc -Bundle-Name: Spring Boot Dash CF Support -Require-Bundle: org.eclipse.ui, - org.eclipse.ui.ide, - org.springframework.ide.eclipse.boot.launch, - org.springframework.ide.eclipse.boot, - org.springframework.ide.eclipse.boot.dash, - org.springsource.ide.eclipse.commons.livexp, - com.google.guava;bundle-version="15.0.0", - org.springframework.ide.eclipse.boot.wizard, - io.projectreactor.reactor-core, - org.reactivestreams.reactive-streams, - org.eclipse.core.resources, - org.eclipse.debug.core, - org.eclipse.jdt.core, - org.springsource.ide.eclipse.commons.ui, - org.eclipse.ui.views.properties.tabbed, - org.eclipse.jdt.launching, - org.eclipse.debug.ui, - org.eclipse.jdt.debug.ui, - org.springsource.ide.eclipse.commons.core, - org.eclipse.ui.console, - javax.ws.rs;bundle-version="2.0.1", - org.springframework.ide.eclipse.beans.ui.live, - org.eclipse.compare, - org.eclipse.core.filebuffers, - org.eclipse.text, - org.springsource.ide.eclipse.commons.frameworks.core, - org.apache.httpcomponents.httpclient, - org.apache.httpcomponents.httpcore, - org.yaml.snakeyaml, - org.apache.commons.lang3, - org.springframework.ide.eclipse.editor.support, - org.eclipse.jface.text, - org.springsource.ide.eclipse.commons.cloudfoundry.client.v2, - org.eclipse.core.net, - org.eclipse.equinox.security, - org.eclipse.jdt.ui, - org.eclipse.ui.genericeditor, - org.eclipse.ui.editors, - com.hierynomus.sshj;bundle-version="0.24.0", - com.jcraft.jzlib;bundle-version="1.1.3", - org.bouncycastle.bcpkix;bundle-version="1.59.0", - org.bouncycastle.bcprov;bundle-version="1.59.0", - org.springsource.ide.eclipse.commons.boot.ls, - org.springframework.tooling.cloudfoundry.manifest.ls, - org.springframework.tooling.ls.eclipse.commons -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Bundle-Activator: org.springframework.ide.eclipse.boot.dash.cf.BootDashCfPlugin -Bundle-ActivationPolicy: lazy -Export-Package: org.springframework.ide.eclipse.boot.dash.cf, - org.springframework.ide.eclipse.boot.dash.cf.actions, - org.springframework.ide.eclipse.boot.dash.cf.client, - org.springframework.ide.eclipse.boot.dash.cf.client.v2, - org.springframework.ide.eclipse.boot.dash.cf.debug, - org.springframework.ide.eclipse.boot.dash.cf.deployment, - org.springframework.ide.eclipse.boot.dash.cf.dialogs, - org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel, - org.springframework.ide.eclipse.boot.dash.cf.model, - org.springframework.ide.eclipse.boot.dash.cf.packaging, - org.springframework.ide.eclipse.boot.dash.cf.routes, - org.springframework.ide.eclipse.boot.dash.cf.runtarget, - org.springframework.ide.eclipse.boot.dash.cf.ui -Bundle-ClassPath: ., - lib/spring-boot-loader-tools-1.2.3.RELEASE.jar -Automatic-Module-Name: org.springframework.ide.eclipse.boot.dash.cf -Import-Package: org.eclipse.core.runtime, - org.eclipse.core.runtime.jobs, - org.eclipse.core.runtime.preferences, - org.eclipse.osgi.util, - org.osgi.framework, - com.google.gson, - com.google.gson.annotations, - com.google.gson.reflect, - com.google.gson.stream diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/build.properties b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/build.properties deleted file mode 100755 index b59f529db..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/build.properties +++ /dev/null @@ -1,7 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - plugin.xml,\ - icons/,\ - lib/spring-boot-loader-tools-1.2.3.RELEASE.jar diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/icons/cloud_obj.png b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/icons/cloud_obj.png deleted file mode 100644 index 7633c35fb..000000000 Binary files a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/icons/cloud_obj.png and /dev/null differ diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/lib/spring-boot-loader-tools-1.2.3.RELEASE-sources.jar b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/lib/spring-boot-loader-tools-1.2.3.RELEASE-sources.jar deleted file mode 100644 index cbb02c57f..000000000 Binary files a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/lib/spring-boot-loader-tools-1.2.3.RELEASE-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/lib/spring-boot-loader-tools-1.2.3.RELEASE.jar b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/lib/spring-boot-loader-tools-1.2.3.RELEASE.jar deleted file mode 100644 index d1a02b37c..000000000 Binary files a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/lib/spring-boot-loader-tools-1.2.3.RELEASE.jar and /dev/null differ diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/plugin.xml b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/plugin.xml deleted file mode 100755 index 8feaf9cc8..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/plugin.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/pom.xml b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/pom.xml deleted file mode 100755 index 2c03415ed..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/pom.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - 4.0.0 - - - org.springframework.boot.ide - org.springframework.boot.ide - 4.18.0-SNAPSHOT - ../../eclipse-distribution/pom.xml - - - org.springframework.ide.eclipse - org.springframework.ide.eclipse.boot.dash.cf - eclipse-plugin - - - - - - org.eclipse.tycho - tycho-source-plugin - ${tycho-version} - - - plugin-source - generate-sources - - plugin-source - - - - - - - org.eclipse.tycho - tycho-p2-plugin - ${tycho-version} - - - second-generate-p2-metadata - - p2-metadata - - verify - - - - - - - - diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/BootDashCfPlugin.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/BootDashCfPlugin.java deleted file mode 100644 index 434e762b3..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/BootDashCfPlugin.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 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: - * Phil Webb - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf; - -import java.util.concurrent.CompletableFuture; - -import org.eclipse.ui.plugin.AbstractUIPlugin; -import org.osgi.framework.BundleContext; - -public class BootDashCfPlugin extends AbstractUIPlugin { - - private static final String PLUGIN_ID = "org.springframework.ide.eclipse.boot.dash.cf"; - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - CompletableFuture.runAsync(() -> BootDashTargetInfoSynchronizer.start()); - } - - @Override - public void stop(BundleContext context) throws Exception { - BootDashTargetInfoSynchronizer.stop(); - super.stop(context); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/BootDashInjections.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/BootDashInjections.java deleted file mode 100644 index a19f412fa..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/BootDashInjections.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.cf; - -import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; -import org.springframework.ide.eclipse.boot.dash.cf.actions.CfBootDashActions; -import org.springframework.ide.eclipse.boot.dash.cf.client.CloudFoundryClientFactory; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.DefaultCloudFoundryClientFactoryV2; -import org.springframework.ide.eclipse.boot.dash.cf.debug.DebugSupport; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshDebugSupport; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshTunnelFactory; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshTunnelImpl; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.CloudFoundryRemoteBootAppsDataContributor; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.JmxSshTunnelManager; -import org.springframework.ide.eclipse.boot.dash.cf.labels.BootDashCfLabels; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTargetType; -import org.springframework.ide.eclipse.boot.dash.cf.ui.CfUserInteractions; -import org.springframework.ide.eclipse.boot.dash.cf.ui.DefaultCfUserInteractions; -import org.springframework.ide.eclipse.boot.dash.di.EclipseBeanLoader.Contribution; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.labels.BootDashLabels; -import org.springframework.ide.eclipse.boot.dash.model.DefaultBootDashModelContext; -import org.springframework.ide.eclipse.boot.dash.views.BootDashActions; -import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder; - -/** - * Contributes bean definitions to {@link DefaultBootDashModelContext} - */ -public class BootDashInjections implements Contribution { - - @Override - public void applyBeanDefinitions(SimpleDIContext context) throws Exception { - //TargetType - context.def(RunTargetType.class, CloudFoundryRunTargetType::new); - - //Auto sync of cf deployed apps with JMX over SSH tunnel with boot ls (for live hover/data features). - context.def(RemoteBootAppsDataHolder.Contributor.class, CloudFoundryRemoteBootAppsDataContributor::new); - - //UI actions - context.defInstance(BootDashActions.Factory.class, CfBootDashActions.factory); - - //BootDashLabels - context.defInstance(BootDashLabels.Contribution.class, BootDashCfLabels.jmxDecoration); - - //cf internal - context.def(CfUserInteractions.class, DefaultCfUserInteractions::new); - context.defInstance(DebugSupport.class, SshDebugSupport.INSTANCE); - context.defInstance(SshTunnelFactory.class, SshTunnelImpl::new); - context.defInstance(JmxSshTunnelManager.class, new JmxSshTunnelManager()); - context.defInstance(CloudFoundryClientFactory.class, DefaultCloudFoundryClientFactoryV2.INSTANCE); - } - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/BootDashTargetInfoSynchronizer.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/BootDashTargetInfoSynchronizer.java deleted file mode 100644 index d4a5fdb28..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/BootDashTargetInfoSynchronizer.java +++ /dev/null @@ -1,160 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.cf; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.DefaultClientRequestsV2; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CfTargetsInfo; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CfTargetsInfo.Target; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CfTargetsInfo.TargetDiagnosticMessages; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryTargetProperties; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springframework.tooling.cloudfoundry.manifest.ls.CloudFoundryManifestLanguageServer; -import org.springsource.ide.eclipse.commons.livexp.core.ValueListener; - -import com.google.common.collect.ImmutableSet; - -/** - * Helper methods to attach listener to the BootDash model and keep editor in sync with - * all connected cloudfoundry targets. - *

- * Usage: just call the 'start()' method once, at the first time the information is desired. - */ -@SuppressWarnings("rawtypes") -public class BootDashTargetInfoSynchronizer { - - private static AtomicBoolean started = new AtomicBoolean(false); - - public static void start() { - if (started.compareAndSet(false, true)) { - model().getRunTargets().addListener(targetsListener); - } - } - - public static void stop() { - if (started.compareAndSet(true, false)) { - updateCloudTargetsInManifestEditor(ImmutableSet.of()); - } - } - - private static final ValueListener> targetsListener = (e, v) -> { - // On target changes, add the client listener in each target so that when the client changes, a notification is sent - addClientChangeListeners(e.getValue()); - }; - - private static final ValueListener clientsChangedListener = (exp, client) -> { - if (client instanceof DefaultClientRequestsV2) { - addRefreshTokenListener((DefaultClientRequestsV2) client); - } - }; - - /** - * Add a listener to be notified when the refresh token becomes available OR - * changes - */ - static private void addRefreshTokenListener(DefaultClientRequestsV2 client) { - if (client != null && client.getRefreshTokens() != null && model() != null - && model().getRunTargets() != null) { - client.getRefreshTokens().doOnNext((token) -> - // Although the refresh token change is for ONE client (i.e. one target) - // compute cloud target information for ALL currently connected targets - // as the manifest editor is updated with the full up-to-date list of connected - // boot dash targets - updateCloudTargetsInManifestEditor(model().getRunTargets().getValue()) - ).subscribe(); - client.getRefreshTokens().doOnComplete(() -> - updateCloudTargetsInManifestEditor(model().getRunTargets().getValue()) - ).subscribe(); - } - } - - static private void updateCloudTargetsInManifestEditor(ImmutableSet value) { - Set toUpdate = value == null ? ImmutableSet.of() : value; - - CfTargetsInfo targetsInfo = asTargetsInfo(toUpdate); - CloudFoundryManifestLanguageServer.setCfTargetLoginOptions(targetsInfo); - } - - private static BootDashViewModel model() { - return BootDashActivator.getDefault().getModel(); - } - - private static void addClientChangeListeners(ImmutableSet targets) { - if (targets != null) { - for (RunTarget runTarget : targets) { - if (runTarget instanceof CloudFoundryRunTarget) { - ((CloudFoundryRunTarget) runTarget).getClientExp().addListener(clientsChangedListener); - } - } - } - } - - private static CfTargetsInfo asTargetsInfo(Collection targets) { - List collectedTargets = new ArrayList<>(); - for (RunTarget runTarget : targets) { - if (runTarget instanceof CloudFoundryRunTarget) { - - CloudFoundryRunTarget cloudFoundryRunTarget = (CloudFoundryRunTarget) runTarget; - if (cloudFoundryRunTarget.isConnected()) { - String token = cloudFoundryRunTarget.getClient().getRefreshToken(); - if (token != null) { - CloudFoundryTargetProperties properties = cloudFoundryRunTarget.getTargetProperties(); - String target = properties.getUrl(); - String org = properties.getOrganizationName(); - String space = properties.getSpaceName(); - boolean sslDisabled = properties.skipSslValidation(); - - CfTargetsInfo.Target integrationTarget = new Target(); - - integrationTarget.setApi(target); - integrationTarget.setOrg(org); - integrationTarget.setSpace(space); - integrationTarget.setSslDisabled(sslDisabled); - integrationTarget.setRefreshToken(token); - collectedTargets.add(integrationTarget); - } - } - } - } - - CfTargetsInfo targetsInfo = new CfTargetsInfo(); - targetsInfo.setCfTargets(collectedTargets); - targetsInfo.setDiagnosticMessages(getDiagnosticMessages()); - return targetsInfo ; - } - - // NOTE: using ':' to separate the "shorter" part of the message from the longer. The longer part may be shown in the UI by expanding the hover info - private static final String TARGET_SOURCE = "Boot Dashboard"; - private static final String NO_ORG_SPACE = "Boot Dashboard - No org/space selected: Verify Cloud Foundry target connection in Boot Dashboard or login via 'cf' CLI"; - // Make this a "generic" message, instead of using "Boot Dash" prefix as it shows general instructions when there are not targets - private static final String NO_TARGETS = "No Cloud Foundry targets found: Create a target in Boot Dashboard or login via 'cf' CLI"; - private static final String CONNECTION_ERROR = "Boot Dashboard - Error connecting to Cloud Foundry target: Verify network connection or that existing target has valid credentials."; - - private static TargetDiagnosticMessages getDiagnosticMessages() { - TargetDiagnosticMessages messages = new TargetDiagnosticMessages(); - messages.setConnectionError(CONNECTION_ERROR); - messages.setNoOrgSpace(NO_ORG_SPACE); - messages.setNoTargetsFound(NO_TARGETS); - messages.setTargetSource(TARGET_SOURCE); - return messages; - } - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/AbstractCloudAppDashElementsAction.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/AbstractCloudAppDashElementsAction.java deleted file mode 100644 index 02ba712a9..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/AbstractCloudAppDashElementsAction.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.cf.actions; - -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; -import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashElementsAction; -import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashElementsAction.Params; - -/** - * Action for {@link CloudAppDashElement} elements only - * - * @author Alex Boyko - * - */ -public class AbstractCloudAppDashElementsAction extends AbstractBootDashElementsAction { - - public AbstractCloudAppDashElementsAction(Params params) { - super(params); - } - - @Override - public void updateVisibility() { - boolean visible = false; - if (!getSelectedElements().isEmpty()) { - visible = true; - for (BootDashElement e : getSelectedElements()) { - if (!(e instanceof CloudAppDashElement)) { - visible = false; - break; - } - } - } - setVisible(visible); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/AbstractCloudDashModelAction.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/AbstractCloudDashModelAction.java deleted file mode 100644 index 245544ad6..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/AbstractCloudDashModelAction.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.cf.actions; - -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.ui.CfUserInteractions; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; -import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashModelAction; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; - -/** - * Action for Cloud Foundry dash model element - * - * @author Alex Boyko - * - */ -public class AbstractCloudDashModelAction extends AbstractBootDashModelAction { - - protected AbstractCloudDashModelAction(LiveExpression section, SimpleDIContext ui) { - super(section, ui); - } - - protected CfUserInteractions cfUi() { - return context.getBean(CfUserInteractions.class); - } - - @Override - public void updateVisibility() { - this.setVisible(sectionSelection.getValue() instanceof CloudFoundryBootDashModel); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/CfBootDashActions.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/CfBootDashActions.java deleted file mode 100644 index 491850acb..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/CfBootDashActions.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019 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.cf.actions; - -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveProcessCommandsExecutor; -import org.springframework.ide.eclipse.boot.dash.livexp.MultiSelection; -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.BootDashViewModel; -import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashAction; -import org.springframework.ide.eclipse.boot.dash.views.BootDashActions; -import org.springframework.ide.eclipse.boot.dash.views.ToggleBootDashModelConnection; -import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashElementsAction.Params; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; - -import com.google.common.collect.ImmutableList; - -public class CfBootDashActions { - - public static BootDashActions.Factory factory = ( - BootDashActions actions, - BootDashViewModel model, - MultiSelection selection, - LiveExpression section, - SimpleDIContext context, - LiveProcessCommandsExecutor liveProcessCmds - ) -> { - - Params defaultActionParams = new Params(actions) - .setModel(model) - .setSelection(selection) - .setContext(context) - .setLiveProcessCmds(liveProcessCmds); - - ImmutableList.Builder builder = ImmutableList.builder(); - builder.add(new RestartApplicationOnlyAction(defaultActionParams)); - builder.add(new SelectManifestAction(defaultActionParams)); - builder.add(new CloudFoundryRestartWithRemoteDevClientAction(defaultActionParams)); - builder.add(new EnableJmxSshTunnelAction(defaultActionParams)); - builder.add(new ReconnectCloudConsoleAction(defaultActionParams)); - if (section!=null) { - builder.add(new UpdatePasswordAction(section, context)); - builder.add(new OpenCloudAdminConsoleAction(section, context)); - builder.add(new CustmomizeTargetAppManagerURLAction(section, context)); - } - return builder.build(); - }; -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/CloudFoundryRestartWithRemoteDevClientAction.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/CloudFoundryRestartWithRemoteDevClientAction.java deleted file mode 100644 index 8954a87b8..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/CloudFoundryRestartWithRemoteDevClientAction.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2017 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.cf.actions; - -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.PlatformUI; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel.ElementStateListener; - -/** - * Action for starting/restarting Remove DevTools Client application - * - * @author Alex Boyko - * - */ -public class CloudFoundryRestartWithRemoteDevClientAction extends AbstractCloudAppDashElementsAction { - - private ElementStateListener stateListener; - - public CloudFoundryRestartWithRemoteDevClientAction(Params params) { - super(params); - this.setText("(Re)start Remote DevTools Client"); - this.setToolTipText("Restarts application with the Remote DevTools Client attched."); - URL url = FileLocator.find(Platform.getBundle("org.springframework.ide.eclipse.boot"), new Path("resources/icons/boot-devtools-icon.png"), null); - if (url != null) { - this.setImageDescriptor(ImageDescriptor.createFromURL(url)); - } - if (model != null) { - model.addElementStateListener(stateListener = new ElementStateListener() { - public void stateChanged(BootDashElement e) { - if (getSelectedElements().contains(e) && !PlatformUI.getWorkbench().isClosing()) { - PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { - public void run() { - updateEnablement(); - } - }); - } - } - }); - } - } - - @Override - public void updateEnablement() { - boolean enable = false; - if (!getSelectedElements().isEmpty()) { - enable = true; - for (BootDashElement e : getSelectedElements()) { - if (!(e instanceof CloudAppDashElement) || e.getProject() == null) { - enable = false; - } - } - } - this.setEnabled(enable); - } - - @Override - public void run() { - for (BootDashElement _e : getSelectedElements()) { - if (_e instanceof CloudAppDashElement && _e.getBootDashModel() instanceof CloudFoundryBootDashModel && _e.getProject() != null) { - CloudAppDashElement e = (CloudAppDashElement) _e; - e.restartWithRemoteClient(ui(), e.createCancelationToken()); - } - } - } - - @Override - public void dispose() { - if (model != null && stateListener != null) { - model.removeElementStateListener(stateListener); - stateListener = null; - } - super.dispose(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/CustmomizeTargetAppManagerURLAction.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/CustmomizeTargetAppManagerURLAction.java deleted file mode 100644 index 04e053d7c..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/CustmomizeTargetAppManagerURLAction.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.cf.actions; - -import java.util.EnumSet; - -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.CustomizeAppsManagerURLDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; -import org.springsource.ide.eclipse.commons.core.pstore.PropertyStoreApi; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; - -public class CustmomizeTargetAppManagerURLAction extends AbstractCloudDashModelAction{ - - protected CustmomizeTargetAppManagerURLAction(LiveExpression section, SimpleDIContext context) { - super(section, context); - setText("Customize Cloud Admin Console URL..."); - } - - @Override - public void updateEnablement() { - this.setEnabled(isApplicable(sectionSelection.getValue())); - } - - @Override - public void updateVisibility() { - this.setVisible(isApplicable(sectionSelection.getValue())); - } - - private boolean isApplicable(BootDashModel section) { - if (section != null && section instanceof CloudFoundryBootDashModel) { - PropertyStoreApi props = section.getRunTarget().getType().getPersistentProperties(); - return props != null; - } - return false; - } - - @Override - public void run() { - final BootDashModel section = sectionSelection.getValue(); - if (isApplicable(section)) { - CustomizeAppsManagerURLDialogModel model = new CustomizeAppsManagerURLDialogModel((CloudFoundryBootDashModel)section); - cfUi().openEditAppsManagerURLDialog(model); - } - } - - @Override - public EnumSet showIn() { - return EnumSet.of(Location.CUSTOMIZE_MENU); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/EnableJmxSshTunnelAction.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/EnableJmxSshTunnelAction.java deleted file mode 100644 index 424506789..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/EnableJmxSshTunnelAction.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 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.cf.actions; - -import java.net.URL; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.PlatformUI; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -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.RunState; -import org.springsource.ide.eclipse.commons.livexp.util.Log; - -public class EnableJmxSshTunnelAction extends AbstractCloudAppDashElementsAction { - - private ElementStateListener stateListener; - - public EnableJmxSshTunnelAction(Params params) { - super(params); - this.setText("Enable JMX Ssh Tunneling"); - this.setToolTipText("Enables JMX on this app and creates an SSH Tunnel the next time the app is started."); - URL url = FileLocator.find(Platform.getBundle("org.springframework.ide.eclipse.boot.dash"), new Path("icons/link_to_editor.png"), null); - if (url != null) { - this.setImageDescriptor(ImageDescriptor.createFromURL(url)); - } - if (model != null) { - model.addElementStateListener(stateListener = new ElementStateListener() { - @Override - public void stateChanged(BootDashElement e) { - if (getSelectedElements().contains(e) && !PlatformUI.getWorkbench().isClosing()) { - PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - updateEnablement(); - } - }); - } - } - }); - } - } - - @Override - public void updateEnablement() { - boolean enable = false; - boolean enableTunnel = false; - if (getSelectedElements().size()==1) { - BootDashElement e = getSelectedElements().iterator().next(); - if (e instanceof CloudAppDashElement && e.getProject() != null) { - CloudAppDashElement cde = (CloudAppDashElement) e; - enable = true; - enableTunnel = !cde.getEnableJmxSshTunnel(); - } - } - this.setEnabled(enable); - if (enable) { - setText((enableTunnel ? "Enable" : "Disable")+" JMX Ssh Tunnelling"); - } else { - setText("Toggle JMX Ssh Tunnelling"); - } - } - - @Override - public void run() { - try { - for (BootDashElement _e : getSelectedElements()) { - if (_e instanceof CloudAppDashElement && _e.getBootDashModel() instanceof CloudFoundryBootDashModel && _e.getProject() != null) { - CloudAppDashElement e = (CloudAppDashElement) _e; - boolean enable = !e.getEnableJmxSshTunnel(); - e.setEnableJmxSshTunnel(enable); - RunState runstate = e.getRunState(); - if (runstate!=RunState.INACTIVE) { - int answer = ui().confirmOperation((enable ? "Enabling" : "Disabling") +" JMX Requires Restart", - "Enabling JMX is done by setting environment parameters on startup. For this setting to take effect the app needs to be restarted.\n\n" + - "Do you want to restart now?", - new String[] { - "Yes, Restart NOW", - "No, I'll restart MANUALLY later" - }, - 0 - ); - if (answer==0) { - RunState runningOrDebugging = runstate==RunState.DEBUGGING ? RunState.DEBUGGING : RunState.RUNNING; - e.restart(runningOrDebugging, ui()); - } - } - } - } - } catch (Exception e) { - Log.log(e); - } - } - - @Override - public void dispose() { - if (model != null && stateListener != null) { - model.removeElementStateListener(stateListener); - stateListener = null; - } - super.dispose(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/OpenCloudAdminConsoleAction.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/OpenCloudAdminConsoleAction.java deleted file mode 100644 index 9eff60721..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/OpenCloudAdminConsoleAction.java +++ /dev/null @@ -1,55 +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.cf.actions; - -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; - -/** - * @author Martin Lippert - */ -public class OpenCloudAdminConsoleAction extends AbstractCloudDashModelAction { - - public OpenCloudAdminConsoleAction(LiveExpression sectionSelection, SimpleDIContext ui) { - super(sectionSelection, ui); - this.setText("Open Cloud Admin Console"); - this.setToolTipText("Opens the Cloud Administration Console for this Cloud Foundry Space and Organisation"); - this.setImageDescriptor(BootDashActivator.getImageDescriptor("icons/cloud_obj.png")); - } - - @Override - public void run() { - final BootDashModel targetModel = sectionSelection.getValue(); - if (targetModel != null) { - RunTarget target = targetModel.getRunTarget(); - if (target instanceof CloudFoundryRunTarget) { - ((CloudFoundryRunTarget) target).openCloudAdminConsole(ui()); - } - } - } - - @Override - public void updateEnablement() { - final BootDashModel targetModel = sectionSelection.getValue(); - if (targetModel != null) { - RunTarget runTarget = targetModel.getRunTarget(); - this.setEnabled(runTarget instanceof CloudFoundryRunTarget); - } else { - this.setEnabled(false); - } - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/ReconnectCloudConsoleAction.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/ReconnectCloudConsoleAction.java deleted file mode 100644 index c84af7442..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/ReconnectCloudConsoleAction.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.actions; - -import java.util.Collection; -import java.util.Iterator; - -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.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -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.views.AbstractBootDashElementsAction; -import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashElementsAction.Params; - -public class ReconnectCloudConsoleAction extends AbstractCloudAppDashElementsAction { - - public ReconnectCloudConsoleAction(Params params) { - super(params); - this.setText("Reconnect Console"); - this.setToolTipText("Reconnect Console"); - this.setImageDescriptor(BootDashActivator.getImageDescriptor("icons/open_console.png")); - this.setDisabledImageDescriptor(BootDashActivator.getImageDescriptor("icons/open_console_disabled.png")); - } - - @Override - public void run() { - final Collection selecteds = getSelectedElements(); - - Job job = new Job("Reconnecting console") { - - @Override - protected IStatus run(IProgressMonitor monitor) { - doShowConsoles(selecteds); - return Status.OK_STATUS; - } - - }; - job.schedule(); - } - - protected void doShowConsoles(Collection selectedElements) { - - if (selectedElements != null) { - - Iterator it = selectedElements.iterator(); - - // Show first element only for now - if (it.hasNext()) { - BootDashElement element = selectedElements.iterator().next(); - BootDashModel model = element.getBootDashModel(); - try { - if (model.getElementConsoleManager() != null) { - model.getElementConsoleManager().reconnect(element); - } - } catch (Exception e) { - ui().errorPopup("Reconnect Console Failure", e.getMessage()); - } - } - } - } - - @Override - public void updateEnablement() { - boolean enable = false; - if (!getSelectedElements().isEmpty()) { - enable = true; - for (BootDashElement e : getSelectedElements()) { - if (!(e instanceof CloudAppDashElement)) { - enable = false; - break; - } - } - } - - this.setEnabled(enable); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/RestartApplicationOnlyAction.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/RestartApplicationOnlyAction.java deleted file mode 100644 index 184fcca11..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/RestartApplicationOnlyAction.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 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.cf.actions; - -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.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; -import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashElementsAction; -import org.springframework.ide.eclipse.boot.dash.views.AbstractBootDashElementsAction.Params; - -public class RestartApplicationOnlyAction extends AbstractCloudAppDashElementsAction { - - public RestartApplicationOnlyAction(Params params) { - super(params); - this.setText("Restart Only"); - this.setToolTipText("Restarts the application without uploading changes."); - this.setImageDescriptor(BootDashActivator.getImageDescriptor("icons/restart.png")); - this.setDisabledImageDescriptor(BootDashActivator.getImageDescriptor("icons/restart_disabled.png")); - } - - @Override - public void run() { - Job job = new Job("Restarting apps") { - @Override - protected IStatus run(IProgressMonitor monitor) { - for (BootDashElement el : getSelectedElements()) { - - if (el instanceof CloudAppDashElement) { - try { - CloudAppDashElement cloudAppDashElement = (CloudAppDashElement) el; - cloudAppDashElement.restartOnlyAsynch(ui(), cloudAppDashElement.createCancelationToken()); - } catch (Exception e) { - ui().errorPopup("Error restarting application", e.getMessage()); - } - } - } - return Status.OK_STATUS; - } - - }; - job.schedule(); - } - - @Override - public void updateEnablement() { - boolean enable = false; - if (!getSelectedElements().isEmpty()) { - enable = true; - for (BootDashElement e : getSelectedElements()) { - if (!(e instanceof CloudAppDashElement)) { - enable = false; - break; - } - } - } - - this.setEnabled(enable); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/SelectManifestAction.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/SelectManifestAction.java deleted file mode 100644 index fab71e1aa..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/SelectManifestAction.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.actions; - -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.ops.SelectManifestOp; -import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; - -public class SelectManifestAction extends AbstractCloudAppDashElementsAction { - - public SelectManifestAction(Params params) { - super(params); - params.getContext().assertDefinitionFor(UserInteractions.class); - this.setText("Select Manifest"); - this.setToolTipText("Selects a manifest YAML file to use during application restart."); - this.setImageDescriptor(BootDashActivator.getImageDescriptor("icons/selectmanifest.gif")); - } - - @Override - public void run() { - CloudAppDashElement element = getSelectedCloudElementWithProject(); - if (element != null) { - CloudFoundryBootDashModel model = element.getBootDashModel(); - model.runAsynch(new SelectManifestOp(element), ui()); - } - } - - @Override - public void updateEnablement() { - this.setEnabled(getSelectedCloudElementWithProject() != null); - } - - protected CloudAppDashElement getSelectedCloudElementWithProject() { - if (getSelectedElements().size() == 1) { - - for (BootDashElement e : getSelectedElements()) { - if (e instanceof CloudAppDashElement) { - CloudAppDashElement cde = (CloudAppDashElement) e; - if (cde.getProject() != null && cde.getProject().isAccessible()) { - return cde; - } - } - } - } - return null; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/UpdatePasswordAction.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/UpdatePasswordAction.java deleted file mode 100644 index d7d215c9d..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/actions/UpdatePasswordAction.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.actions; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import org.eclipse.core.runtime.Status; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springframework.ide.eclipse.boot.dash.model.RunTargetWithProperties; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.util.Log; - -public class UpdatePasswordAction extends AbstractCloudDashModelAction { - - public UpdatePasswordAction(LiveExpression sectionSelection, SimpleDIContext context) { - super(sectionSelection, context); - this.setText("Update Password"); - this.setToolTipText("Update password locally for the selected target."); - this.setImageDescriptor(BootDashActivator.getImageDescriptor("icons/update_password.png")); - } - - CompletableFuture lastRunCompletion = null; - - /** - * This is meant for test-code only, so that test can we wait for the action (part f which is executed in - * a job) to complete. - */ - public void waitFor() throws InterruptedException, ExecutionException { - if (lastRunCompletion!=null) { - lastRunCompletion.get(); - } - } - - @Override - public void run() { - CompletableFuture lastRunCompletion = this.lastRunCompletion = new CompletableFuture<>(); - try { - final CloudFoundryBootDashModel targetModel = (CloudFoundryBootDashModel) sectionSelection.getValue(); - final CloudFoundryRunTarget runTarget = targetModel.getRunTarget(); - if (runTarget!=null) { - targetModel.refreshTracker.callAsync("Updating password...", () -> { - runTarget.updatePasswordAndConnect(); - lastRunCompletion.complete(null); - return Status.OK_STATUS; - }); - } - } catch (Exception e) { - Log.log(e); - } - } - - @Override - public void updateEnablement() { - this.setEnabled(getCredentialsHolder(sectionSelection.getValue())!=null); - } - - @Override - public void updateVisibility() { - setVisible(getCredentialsHolder(sectionSelection.getValue()) != null); - } - - private RunTargetWithProperties getCredentialsHolder(BootDashModel section) { - if (section!=null) { - RunTarget target = section.getRunTarget(); - if (target instanceof RunTargetWithProperties) { - RunTargetWithProperties targetWithProps = (RunTargetWithProperties) target; - if (targetWithProps.requiresCredentials()) { - return targetWithProps; - } - } - } - return null; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFAppState.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFAppState.java deleted file mode 100644 index 5b8ead367..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFAppState.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -public enum CFAppState { - - STOPPED, - STARTED, - UNKNOWN - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFApplication.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFApplication.java deleted file mode 100644 index 341ea5819..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFApplication.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -public interface CFApplication extends CFEntity { - //TODO: lots of this infos should be moved to application details - - int getInstances(); - int getRunningInstances(); - int getMemory(); - UUID getGuid(); - List getServices(); - String getBuildpackUrl(); - List getUris(); - CFAppState getState(); - int getDiskQuota(); - Integer getTimeout(); - String getCommand(); - String getStack(); - - Map getEnvAsMap(); - String getHealthCheckType(); - String getHealthCheckHttpEndpoint(); -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFApplicationArchive.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFApplicationArchive.java deleted file mode 100644 index e91ecf189..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFApplicationArchive.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -public interface CFApplicationArchive { - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFApplicationDetail.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFApplicationDetail.java deleted file mode 100644 index 591dfb285..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFApplicationDetail.java +++ /dev/null @@ -1,17 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -import java.util.List; - -public interface CFApplicationDetail extends CFApplication { - List getInstanceDetails(); -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFBuildpack.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFBuildpack.java deleted file mode 100644 index 40f2704ef..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFBuildpack.java +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -public interface CFBuildpack { - String getName(); -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFClientParams.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFClientParams.java deleted file mode 100644 index 3632d0bef..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFClientParams.java +++ /dev/null @@ -1,168 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -import java.net.URI; - -import org.eclipse.core.runtime.Assert; -import org.springframework.ide.eclipse.boot.core.BootActivator; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials.CFCredentialType; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryTargetProperties; - -/** - * All the parameters needed to create a CF client. - * - * @author Kris De Volder - */ -public class CFClientParams { - - private final String apiUrl; - private final String username; - private CFCredentials credentials; - private final boolean isSelfSigned; - private final boolean skipSslValidation; - - private String orgName; // optional - private String spaceName; //optional - - public CFClientParams(String apiUrl, - String username, - CFCredentials credentials, - boolean isSelfSigned, - String orgName, - String spaceName, - boolean skipSslValidation - ) { - Assert.isNotNull(apiUrl, "apiUrl is required"); - Assert.isNotNull(credentials, "credentials required"); - if (credentials.getType()==CFCredentialType.PASSWORD) { - Assert.isNotNull(username, "username is required"); - } - this.apiUrl = apiUrl; - this.username = username; - this.credentials = credentials; - this.isSelfSigned = isSelfSigned; - this.skipSslValidation = skipSslValidation; - this.orgName = orgName; - this.spaceName = spaceName; - } - - public CFClientParams(CloudFoundryTargetProperties targetProperties) throws Exception { - this( - targetProperties.getUrl(), - targetProperties.getUsername(), - targetProperties.getCredentials(), - targetProperties.isSelfsigned(), - targetProperties.getOrganizationName(), - targetProperties.getSpaceName(), - targetProperties.skipSslValidation() - ); - } - - public CFCredentials getCredentials() { - return credentials; - } - - public String getUsername() { - return username; - } - - public boolean isSelfsigned() { - return isSelfSigned; - } - - public boolean skipSslValidation() { - return skipSslValidation; - } - - public String getApiUrl() { - return apiUrl; - } - - public String getOrgName() { - return orgName; - } - - public void setOrgName(String orgName) { - this.orgName = orgName; - } - - public String getSpaceName() { - return spaceName; - } - - public void setSpaceName(String spaceName) { - this.spaceName = spaceName; - } - - public String getHost() { - try { - URI uri = new URI(getApiUrl()); - return uri.getHost(); - } catch (Exception e) { - BootActivator.log(e); - } - return null; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((apiUrl == null) ? 0 : apiUrl.hashCode()); - result = prime * result + (isSelfSigned ? 1231 : 1237); - result = prime * result + ((orgName == null) ? 0 : orgName.hashCode()); - result = prime * result + ((credentials == null) ? 0 : credentials.hashCode()); - result = prime * result + ((spaceName == null) ? 0 : spaceName.hashCode()); - result = prime * result + ((username == null) ? 0 : username.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; - CFClientParams other = (CFClientParams) obj; - if (apiUrl == null) { - if (other.apiUrl != null) - return false; - } else if (!apiUrl.equals(other.apiUrl)) - return false; - if (isSelfSigned != other.isSelfSigned) - return false; - if (orgName == null) { - if (other.orgName != null) - return false; - } else if (!orgName.equals(other.orgName)) - return false; - if (credentials == null) { - if (other.credentials != null) - return false; - } else if (!credentials.equals(other.credentials)) - return false; - if (spaceName == null) { - if (other.spaceName != null) - return false; - } else if (!spaceName.equals(other.spaceName)) - return false; - if (username == null) { - if (other.username != null) - return false; - } else if (!username.equals(other.username)) - return false; - return true; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFCloudDomain.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFCloudDomain.java deleted file mode 100644 index 041f81e7b..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFCloudDomain.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFDomainStatus; - -public interface CFCloudDomain { - String getName(); - CFDomainType getType(); - CFDomainStatus getStatus(); - - /** - * If the given hostAndDomain is of the form ${host}.${domain} then - * return the host part. Otherwise return null. - */ - default String splitHost(String hostAndDomain) { - String name = getName(); - if (hostAndDomain.endsWith("."+name)) { - return hostAndDomain.substring(0, hostAndDomain.length()-name.length()-1); - } - return null; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFCredentials.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFCredentials.java deleted file mode 100644 index 26548feee..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFCredentials.java +++ /dev/null @@ -1,151 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -import org.apache.commons.lang3.StringUtils; -import org.eclipse.core.runtime.Assert; -import org.springsource.ide.eclipse.commons.livexp.ui.Ilabelable; - -public class CFCredentials { - - public enum CFCredentialType { - PASSWORD, - TEMPORARY_CODE, - REFRESH_TOKEN; - - public LoginMethod toLoginMethod() { - switch (this) { - case PASSWORD: - return LoginMethod.PASSWORD; - case TEMPORARY_CODE: - return LoginMethod.TEMPORARY_CODE; - default: - return null; - } - } - } - - public enum LoginMethod implements Ilabelable { - PASSWORD, - TEMPORARY_CODE; - - @Override - public String getLabel() { - String[] pieces = name().split("_"); - StringBuilder label = new StringBuilder(); - for (int i = 0; i < pieces.length; i++) { - if (i>0) { - label.append(" "); - } - label.append(StringUtils.capitalize(pieces[i].toLowerCase())); - } - return label.toString(); - } - } - - private final CFCredentialType type; - private final String secret; - - /** - * Deprecated, use fromLogin instead - */ - @Deprecated - public static CFCredentials fromPassword(String password) { - return fromLogin(LoginMethod.PASSWORD, password); - } - - - public static CFCredentials fromLogin(LoginMethod method, String secret) { - CFCredentialType type; - switch (method) { - case PASSWORD: - type = CFCredentialType.PASSWORD; - break; - case TEMPORARY_CODE: - type = CFCredentialType.TEMPORARY_CODE; - break; - default: - throw new IllegalStateException("Bug! Missing switch case?"); - } - return new CFCredentials(type, secret); - } - - public static CFCredentials fromRefreshToken(String refreshToken) { - Assert.isNotNull(refreshToken); - return new CFCredentials(CFCredentialType.REFRESH_TOKEN, refreshToken); - } - - public String getSecret() { - return secret; - } - - ///////////////////////////////////////////////////////////////////////// - - - /** - * Private constuctor, use static `fromXXX` factory methods instead. - */ - private CFCredentials(CFCredentialType type, String secret) { - this.type = type; - this.secret = secret; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((secret == null) ? 0 : secret.hashCode()); - result = prime * result + ((type == null) ? 0 : type.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; - CFCredentials other = (CFCredentials) obj; - if (secret == null) { - if (other.secret != null) - return false; - } else if (!secret.equals(other.secret)) - return false; - if (type != other.type) - return false; - return true; - } - - @Override - public String toString() { - return "CFCredentials [type=" + type + ", secret=" + hidePassword(type, secret) + "]"; - } - - private String hidePassword(CFCredentialType type, String password) { - if (password==null) { - return null; - } - return type==CFCredentialType.PASSWORD - ? "****" - : password; - } - - - public CFCredentialType getType() { - return type; - } - - public static CFCredentials fromSsoToken(String ssoToken) { - return CFCredentials.fromLogin(LoginMethod.TEMPORARY_CODE, ssoToken); - } -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFDomainType.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFDomainType.java deleted file mode 100644 index c3045c34a..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFDomainType.java +++ /dev/null @@ -1,16 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Spring IDE Developers - * 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: - * Spring IDE Developers - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -public enum CFDomainType { - HTTP, TCP -} - diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFEntity.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFEntity.java deleted file mode 100644 index ff7618bff..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFEntity.java +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -public interface CFEntity { - String getName(); -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFExceptions.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFExceptions.java deleted file mode 100644 index 1ababe0a5..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFExceptions.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -import org.cloudfoundry.uaa.UaaException; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -/** - * Static methods to recognize specific types of exceptions CF client - * may throw. - * - * @author Kris De Volder - */ -public class CFExceptions { - - public static boolean isAuthFailure(Exception e) { - String msg = ExceptionUtil.getMessage(e); - return msg.contains("Bad credentials") || ExceptionUtil.getDeepestCause(e) instanceof UaaException; - } - - public static boolean isSSLCertificateFailure(Exception e) { - Throwable cause = ExceptionUtil.getDeepestCause(e); - return cause.getClass().getName().equals("sun.security.provider.certpath.SunCertPathBuilderException"); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFInstanceState.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFInstanceState.java deleted file mode 100644 index cc98f66b6..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFInstanceState.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -public enum CFInstanceState { - RUNNING, CRASHED, FLAPPING, STARTING, DOWN, UNKNOWN -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFInstanceStats.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFInstanceStats.java deleted file mode 100644 index 6d0953f8f..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFInstanceStats.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -public interface CFInstanceStats { - - CFInstanceState getState(); - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFOrganization.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFOrganization.java deleted file mode 100644 index a6504fa02..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFOrganization.java +++ /dev/null @@ -1,17 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -import java.util.UUID; - -public interface CFOrganization extends CFEntity { - UUID getGuid(); -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFServiceInstance.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFServiceInstance.java deleted file mode 100644 index fa9f57d8f..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFServiceInstance.java +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -public interface CFServiceInstance extends CFEntity { - - String getName(); - String getService(); - String getPlan(); - String getDescription(); - String getDocumentationUrl(); - String getDashboardUrl(); - - //TODO: last operation info? - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFSpace.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFSpace.java deleted file mode 100644 index bb5e0b553..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFSpace.java +++ /dev/null @@ -1,18 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -import java.util.UUID; - -public interface CFSpace extends CFEntity { - CFOrganization getOrganization(); - UUID getGuid(); -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFStack.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFStack.java deleted file mode 100644 index 29be393fa..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CFStack.java +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -public interface CFStack extends CFEntity { - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/ClientRequests.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/ClientRequests.java deleted file mode 100644 index 6389e341c..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/ClientRequests.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.osgi.framework.Version; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFPushArguments; -import org.springframework.ide.eclipse.boot.dash.console.IApplicationLogConsole; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; -import org.springsource.ide.eclipse.commons.livexp.ui.Disposable; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -public interface ClientRequests extends Disposable { - - /** - * The actual Rest API version that cloud controller claims to be. - */ - Version getApiVersion() throws Exception; - - /** - * The minimum version that the CF V2 java client claims to support. - */ - Version getSupportedApiVersion(); - - /** - * Returns null if the application does not exist. Throws some kind of Exception if there's any other kind of problem. - */ - CFApplicationDetail getApplication(String appName) throws Exception; - - //TODO: consider removing the getXXXSupport method and directly adding the apis that these support - // objects provide. - SshClientSupport getSshClientSupport() throws Exception; - - - void deleteApplication(String name) throws Exception; - - List getApplicationsWithBasicInfo() throws Exception; - List getBuildpacks() throws Exception; - List getDomains() throws Exception; - List getServices() throws Exception; - List getSpaces() throws Exception; - List getStacks() throws Exception; - void restartApplication(String appName, CancelationToken token) throws Exception; - void stopApplication(String appName) throws Exception; - reactor.core.Disposable streamLogs(String appName, IApplicationLogConsole logConsole) throws Exception; - Flux getApplicationDetails(List appsToLookUp) throws Exception; - String getHealthCheck(UUID appGuid) throws Exception; - void setHealthCheck(UUID guid, String hcType) throws Exception; - boolean applicationExists(String appName) throws Exception; - - //Added since v2: - void push(CFPushArguments args, CancelationToken cancelationToken) throws Exception; - Map getApplicationEnvironment(String appName) throws Exception; - Mono deleteServiceAsync(String serviceName); - - /** - * Gets current value of the client's refresh token. Note that the token is only set once it is known. - * Initially, if a client is created via password auth, then the refreshToken won't be known until - * some operation has been executed. - * - * @return Refresh token if it is already known, null otherwise. - */ - String getRefreshToken(); - Mono getUserName(); - - /** - * The returned flux will provide the current token in its onNext immediately, if there is a current - * token already. Subsequent onNext will be fired whenever the token changes. - */ - Flux getRefreshTokens(); -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CloudAppInstances.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CloudAppInstances.java deleted file mode 100644 index 354b7167b..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CloudAppInstances.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.client; - -import java.util.List; - -import org.eclipse.core.runtime.Assert; - -/** - * A Cloud application with additional stats and instances information - * - * This should be removed. Use {@link CFApplicationDetail} instead. It contains - * all the same infos. - */ -@Deprecated -public class CloudAppInstances { - - private final CFApplication app; - private final List stats; - - public CloudAppInstances(CFApplication app, List stats) { - Assert.isNotNull(app); - this.app = app; - this.stats = stats; - } - - public CFApplication getApplication() { - return app; - } - - public List getStats() { - return stats; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CloudFoundryClientFactory.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CloudFoundryClientFactory.java deleted file mode 100644 index 0df2c19fc..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/CloudFoundryClientFactory.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryTargetProperties; - -public abstract class CloudFoundryClientFactory { - - public abstract ClientRequests getClient(CFClientParams params); - - /** - * Get the client for an existing {@link CloudFoundryRunTarget}. Note that - * this may require the password to be set for that runtarget. - * - * @param runTarget - * @return client if connection was successful. - * @throws Exception - * if there was an error connecting, including if password is - * not set or invalid. - */ - public final ClientRequests getClient(CloudFoundryTargetProperties targetProperties) throws Exception { - return getClient(new CFClientParams(targetProperties)); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/HealthChecks.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/HealthChecks.java deleted file mode 100644 index b531e8b10..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/HealthChecks.java +++ /dev/null @@ -1,19 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019 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.cf.client; - -public class HealthChecks { - - public static final String HC_PORT = "port"; - public static final String HC_PROCESS = "process"; - public static final String HC_HTTP = "http"; - public static final String[] HC_ALL = {HC_PORT, HC_PROCESS, HC_HTTP}; -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/InstanceState.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/InstanceState.java deleted file mode 100644 index de67ab7c3..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/InstanceState.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009-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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -/** - * Enum used for the state of an instance - * - * Note: copied over from CF V1 client code. - * - * @author Thomas Risberg - */ -public enum InstanceState { - DOWN, STARTING, RUNNING, CRASHED, FLAPPING, UNKNOWN; - - public static InstanceState valueOfWithDefault(String s) { - try { - return InstanceState.valueOf(s); - } catch (IllegalArgumentException e) { - return InstanceState.UNKNOWN; - } - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/RequestErrorHandler.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/RequestErrorHandler.java deleted file mode 100644 index 63c1f2c99..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/RequestErrorHandler.java +++ /dev/null @@ -1,25 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client; - -public class RequestErrorHandler { - - /** - * - * @param e - * @return true if request error should be treated as an error and thrown. False error - * should be ignored. - */ - public boolean throwError(Throwable e) { - return true; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/SshClientSupport.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/SshClientSupport.java deleted file mode 100644 index 35cbef140..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/SshClientSupport.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.cf.client; - -import java.util.UUID; - -public interface SshClientSupport { - - SshHost getSshHost() throws Exception; - String getSshUser(String appName, int instance) throws Exception; - String getSshCode() throws Exception; - - /** - * Deprecated because it is not supported with V2. Use the method based on appName instead. - */ - @Deprecated - String getSshUser(UUID appGuid, int instance) throws Exception; - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/SshHost.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/SshHost.java deleted file mode 100644 index f9fcf1975..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/SshHost.java +++ /dev/null @@ -1,53 +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.cf.client; - -/** - * Info object containing various bits of info about the host to which an ssh - * client may wish to connect. - * - * @author Kris De Volder - */ -public class SshHost { - - final private String host; - - final private int port; - - final private String fingerPrint; - - public SshHost(String host, int port, String fingerPrint) { - super(); - this.host = host; - this.port = port; - this.fingerPrint = fingerPrint; - } - - public String getFingerPrint() { - return fingerPrint; - } - - public int getPort() { - return port; - } - - public String getHost() { - return host; - } - - @Override - public String toString() { - return "SshHost [host=" //$NON-NLS-1$ - + host + ", port=" //$NON-NLS-1$ - + port + ", fingerPrint=" //$NON-NLS-1$ - + fingerPrint + "]";//$NON-NLS-1$ - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/ApplicationExtras.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/ApplicationExtras.java deleted file mode 100644 index aaf953e1a..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/ApplicationExtras.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client.v2; - -import java.util.List; -import java.util.Map; - -import reactor.core.publisher.Mono; - -/** - * Extrat bits of info that are 'prefetched' asynchronously to fill - * out the CFApplication with info that C2 client doesn't initially return. - * - * @author Kris De Volder - */ -public interface ApplicationExtras { - Mono> getEnv(); - Mono> getServices(); - Mono getBuildpack(); - Mono getStack(); - Mono getTimeout(); - Mono getCommand(); - Mono getHealthCheckType(); - Mono getHealthCheckHttpEndpoint(); -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFApplicationDetailData.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFApplicationDetailData.java deleted file mode 100644 index 66800b1e4..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFApplicationDetailData.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client.v2; - -import java.util.List; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFInstanceStats; - -public class CFApplicationDetailData extends CFApplicationSummaryData implements CFApplicationDetail { - - private List instanceDetails; - - public CFApplicationDetailData( - CFApplicationSummaryData app, - List instanceDetails - ) { - super( - app.getName(), - app.getInstances(), - app.getRunningInstances(), - app.getMemory(), - app.getGuid(), - app.getUris(), - app.getState(), - app.getDiskQuota(), - app.extras - ); - this.instanceDetails = instanceDetails; - } - - @Override - public List getInstanceDetails() { - return instanceDetails; - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("CFApplicationDetail(\n"); - buf.append(" name = "+getName()+"\n"); - buf.append(" instance = "+getInstances()+"\n"); - buf.append(" runningInstances = "+getRunningInstances()+"\n"); - buf.append(" memory = "+getMemory()+"\n"); - buf.append(" guid = "+getGuid()+"\n"); - buf.append(" uris = "+getUris()+"\n"); - buf.append(" state = "+getState()+"\n"); - buf.append(" diskQuota = "+getDiskQuota()+"\n"); - buf.append(" instanceDetails = "+getInstanceDetails()+"\n"); - buf.append(")\n"); - return buf.toString(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFApplicationSummaryData.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFApplicationSummaryData.java deleted file mode 100644 index 4f7cd8dd2..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFApplicationSummaryData.java +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client.v2; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFAppState; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; - -public class CFApplicationSummaryData implements CFApplication { - - private String name; - private int instances; - private int runningInstances; - private int memory; - private UUID guid; - private List uris; - private CFAppState state; - private int diskQuota; - protected ApplicationExtras extras; - - public CFApplicationSummaryData( - String name, - int instances, - int runningInstances, - int memory, - UUID guid, - List uris, - CFAppState state, - int diskQuota, - ApplicationExtras extras - ) { - super(); - this.name = name; - this.instances = instances; - this.runningInstances = runningInstances; - this.memory = memory; - this.guid = guid; - this.uris = uris; - this.state = state; - this.diskQuota = diskQuota; - this.extras = extras; - } - - @Override - public String getName() { - return name; - } - - @Override - public int getInstances() { - return instances; - } - - @Override - public int getRunningInstances() { - return runningInstances; - } - - @Override - public int getMemory() { - return memory; - } - - @Override - public UUID getGuid() { - return guid; - } - - @Override - public List getServices() { - return extras.getServices().block(DefaultClientRequestsV2.GET_SERVICES_TIMEOUT); - } - - @Override - public String getBuildpackUrl() { - return extras.getBuildpack().block(DefaultClientRequestsV2.GET_SMALL_INFO_TIMEOUT); - } - - @Override - public List getUris() { - return uris; - } - - @Override - public CFAppState getState() { - return state; - } - - @Override - public int getDiskQuota() { - return diskQuota; - } - - @Override - public Integer getTimeout() { - return extras.getTimeout().block(DefaultClientRequestsV2.GET_SMALL_INFO_TIMEOUT); - } - - @Override - public String getHealthCheckType() { - return extras.getHealthCheckType().block(DefaultClientRequestsV2.GET_SMALL_INFO_TIMEOUT); - } - - @Override - public String getCommand() { - return extras.getCommand().block(DefaultClientRequestsV2.GET_SMALL_INFO_TIMEOUT); - } - - @Override - public String getStack() { - return extras.getStack().block(DefaultClientRequestsV2.GET_SMALL_INFO_TIMEOUT); - } - - @Override - public Map getEnvAsMap() { - return extras.getEnv().block(DefaultClientRequestsV2.GET_SMALL_INFO_TIMEOUT); - } - - @Override - public String getHealthCheckHttpEndpoint() { - return extras.getHealthCheckHttpEndpoint().block(DefaultClientRequestsV2.GET_SMALL_INFO_TIMEOUT); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFCloudDomainData.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFCloudDomainData.java deleted file mode 100644 index c8b4445b1..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFCloudDomainData.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Spring IDE Developers - * 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: - * Spring IDE Developers - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client.v2; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; - -public final class CFCloudDomainData implements CFCloudDomain { - private final String name; - private final CFDomainType type; - private final CFDomainStatus status; - - public CFCloudDomainData(String name, CFDomainType type, CFDomainStatus status) { - super(); - this.name = name; - this.type = type; - this.status = status; - } - - public CFCloudDomainData(String name) { - this(name, CFDomainType.HTTP, CFDomainStatus.SHARED); - } - - @Override - public CFDomainType getType() { - return type; - } - - @Override - public CFDomainStatus getStatus() { - return status; - } - - @Override - public String getName() { - return name; - } - - @Override - public String toString() { - return "CFCloudDomainData [name=" + name + ", type=" + type + ", status=" + status + "]"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((status == null) ? 0 : status.hashCode()); - result = prime * result + ((type == null) ? 0 : type.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; - CFCloudDomainData other = (CFCloudDomainData) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (status != other.status) - return false; - if (type != other.type) - return false; - return true; - } - -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFDomainStatus.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFDomainStatus.java deleted file mode 100644 index 87cd867f0..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFDomainStatus.java +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Spring IDE Developers - * 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: - * Spring IDE Developers - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client.v2; - -public enum CFDomainStatus { - OWNED, SHARED -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFPushArguments.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFPushArguments.java deleted file mode 100644 index 9e53e63e6..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFPushArguments.java +++ /dev/null @@ -1,171 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client.v2; - -import java.io.File; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.zip.ZipFile; - -import org.eclipse.core.runtime.Assert; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentProperties; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -/** - * Arguments passed to push operation. - * - * @author Kris De Volder - * @author Nieraj Singh - */ -public class CFPushArguments implements AutoCloseable { - private List routes = ImmutableList.of(); - private String appName; - private Integer memory; - private Integer diskQuota; - private Integer timeout; - private String buildpack; - private String command; - private String stack; - private String healthCheckType; - private Map env = ImmutableMap.of(); - private Integer instances; - private List services = ImmutableList.of(); - private File applicationDataAsFile; - private boolean noStart = false; - private boolean randomRoute = false; - private String healthCheckHttpEndpoint; - - public CFPushArguments() { - } - - public String getAppName() { - return appName; - } - public void setAppName(String appName) { - this.appName = appName; - } - public Integer getMemory() { - return memory; - } - public void setMemory(Integer memory) { - this.memory = memory; - } - public Integer getDiskQuota() { - return diskQuota; - } - public void setDiskQuota(Integer diskQuota) { - this.diskQuota = diskQuota; - } - public Integer getTimeout() { - return timeout; - } - public void setTimeout(Integer timeout) { - this.timeout = timeout; - } - public String getBuildpack() { - return buildpack; - } - public void setBuildpack(String buildpack) { - this.buildpack = buildpack; - } - public String getCommand() { - return command; - } - public void setCommand(String command) { - this.command = command; - } - public String getStack() { - return stack; - } - public void setStack(String stack) { - this.stack = stack; - } - public Map getEnv() { - return env; - } - public void setEnv(Map env) { - this.env = env; - } - public Integer getInstances() { - return instances; - } - public void setInstances(Integer instances) { - this.instances = instances; - } - public List getServices() { - return services; - } - public void setServices(List services) { - this.services = services; - } - public boolean getRandomRoute() { - return this.randomRoute; - } - public void setRandomRoute(boolean randomRoute) { - this.randomRoute = randomRoute; - } - public File getApplicationDataAsFile() { - return applicationDataAsFile; - } - public void setApplicationData(File archive) throws Exception { - Assert.isLegal(this.applicationDataAsFile==null, "Can only set this once"); - this.applicationDataAsFile=archive; - } - public boolean isNoStart() { - return noStart; - } - public void setNoStart(boolean noStart) { - this.noStart = noStart; - } - public String getHealthCheckType() { - if (healthCheckType==null) { - return DeploymentProperties.DEFAULT_HEALTH_CHECK_TYPE; - } - return healthCheckType; - } - public void setHealthCheckType(String healthCheckType) { - this.healthCheckType = healthCheckType; - } - public List getRoutes() { - return routes; - } - public void setRoutes(Collection routes) { - this.routes = routes == null ? ImmutableList.of() : ImmutableList.copyOf(routes); - } - public void setRoutes(String... routes) { - setRoutes(ImmutableList.copyOf(routes)); - } - @Override - public String toString() { - return "CFPushArguments [appName=" + appName + ", routes=" + routes + ", memory=" + memory + ", diskQuota=" - + diskQuota + ", timeout=" + timeout + ", buildpack=" + buildpack + ", command=" + command + ", stack=" - + stack + ", env=" + env + ", instances=" + instances + ", services=" + services + ", noStart=" - + noStart + ", healthCheckType="+ healthCheckType+ ", randomRoute="+ randomRoute+" ]"; - } - - public void setHealthCheckHttpEndpoint(String healthCheckHttpEndpoint) { - this.healthCheckHttpEndpoint = healthCheckHttpEndpoint; - } - - public String getHealthCheckHttpEndpoint() { - return this.healthCheckHttpEndpoint; - } - - @Override - public void close() throws Exception { - //This used to do something more useful, we kept it for now to avoid having to - // change a lot of code. But calling `close` is no longer needed and does nothing. - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFRoute.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFRoute.java deleted file mode 100644 index 5a1a6e686..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFRoute.java +++ /dev/null @@ -1,117 +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.cf.client.v2; - -import org.springsource.ide.eclipse.commons.core.util.StringUtil; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -public class CFRoute { - - public static final int NO_PORT = -1; - public static final String EMPTY_ROUTE = ""; - - final private String domain; - final private String host; - final private String path; - final private int port; - final private String fullRoute; - - CFRoute(String domain, String host, String path, int port, String fullRoute) { - super(); - this.domain = domain; - this.host = host; - this.path = path; - this.port = port; - this.fullRoute = fullRoute; - } - - public String getDomain() { - return domain; - } - - public String getHost() { - return host; - } - - public String getPath() { - return path; - } - - public int getPort() { - return port; - } - - public String getRoute() { - return fullRoute; - } - - public void validate() throws Exception { - if (!StringUtil.hasText(getDomain())) { - throw ExceptionUtil.coreException("Invalid route: No domain set."); - } - } - - @Override - public String toString() { - return "CFRoute [domain=" + domain + ", host=" + host + ", path=" + path + ", port=" + port +"]"; - } - - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((domain == null) ? 0 : domain.hashCode()); - result = prime * result + ((fullRoute == null) ? 0 : fullRoute.hashCode()); - result = prime * result + ((host == null) ? 0 : host.hashCode()); - result = prime * result + ((path == null) ? 0 : path.hashCode()); - result = prime * result + port; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CFRoute other = (CFRoute) obj; - if (domain == null) { - if (other.domain != null) - return false; - } else if (!domain.equals(other.domain)) - return false; - if (fullRoute == null) { - if (other.fullRoute != null) - return false; - } else if (!fullRoute.equals(other.fullRoute)) - return false; - if (host == null) { - if (other.host != null) - return false; - } else if (!host.equals(other.host)) - return false; - if (path == null) { - if (other.path != null) - return false; - } else if (!path.equals(other.path)) - return false; - if (port != other.port) - return false; - return true; - } - - public static CFRouteBuilder builder() { - return new CFRouteBuilder(); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFRouteBuilder.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFRouteBuilder.java deleted file mode 100644 index 1c081d19d..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFRouteBuilder.java +++ /dev/null @@ -1,248 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.cf.client.v2; - -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -import org.cloudfoundry.operations.routes.Route; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.util.Log; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; - -public class CFRouteBuilder { - private String domain; - private String host; - private String path; - private int port = CFRoute.NO_PORT; - private String fullRoute; - - public CFRoute build() { - return new CFRoute(this.domain, this.host, this.path, this.port, this.fullRoute); - } - - public CFRouteBuilder domain(String domain) { - this.domain = domain; - // may seem like the more ideal place is to build the full route when - // building the route, rather than repeating - // the process each time a domain, host, path or port value is set - // but the "from" option should be allowed to overwrite the full route - // as well since it already - // has the full value. Therefore re-construct the full value if the - // route is being built piece by piece, but not in from - this.fullRoute = buildRouteVal(this.host, this.domain, this.path, this.port); - return this; - } - - public CFRouteBuilder host(String host) { - this.host = host; - this.fullRoute = buildRouteVal(this.host, this.domain, this.path, this.port); - return this; - } - - public CFRouteBuilder path(String path) { - this.path = path; - this.fullRoute = buildRouteVal(this.host, this.domain, this.path, this.port); - return this; - } - - public CFRouteBuilder port(int port) { - this.port = port; - this.fullRoute = buildRouteVal(this.host, this.domain, this.path, this.port); - return this; - } - - public CFRouteBuilder from(Route route) { - // Route doesn't seem to have API to get a port - this.port = CFRoute.NO_PORT; - this.domain = route.getDomain(); - this.host = route.getHost(); - this.path = route.getPath(); - this.fullRoute = buildRouteVal(this.host, this.domain, this.path, this.port); - return this; - } - - /** - * Builds a {@link CFRoute} given a desiredUrl. This does NOT validate, and - * will attempt to build a route the best way it can given the desiredUrl. - * External components, like the CF Java client, can then validate the - * CFRoute. - * - * @param desiredUrl - * @param domains - * @return this builder - */ - public CFRouteBuilder from(String desiredUrl, Collection domains) { - - - //If it is empty or null, there is nothing to build. However, be sure that the - // full route value is non-null, even if the "components" may be null - if (!StringUtil.hasText(desiredUrl)) { - this.fullRoute = CFRoute.EMPTY_ROUTE; - return this; - } else { - // Be sure to set the full route. - this.fullRoute = desiredUrl; - } - - // Based on CLI cf/actors/routes.go and testing CLI directly with - // different "routes" values: - // 1. Paths is not allowed in TCP route (valid TCP route: - // "tcp.spring.io:8888") - // 2. Ports are not allowed in HTTP route (valid HTTP route: - // "myapps.cfapps.io/pathToApp/home") - // 3. Schemes (e.g. "http://") are not allowed in routes values. - // Anything that has a ":" is assumed to be TCP route followed by a port - // 4. Route can just be domain, or host and domain - // - // Therefore, routes values cannot be treated as URIs or URLs, but a - // combination of domain, host, path and port - // NOTE: The validation above doesn't need to take place here. The - // client or CF will validate correct combinations of routes. - // However, We may want to implement similar - // validation to the CF manifest editor though. - - String matchedHost = null; - String hostAndDomain = null; - - // Split into hostDomain segment, port and path - int slashIndex = desiredUrl.indexOf('/'); - if (slashIndex >= 0) { - hostAndDomain = desiredUrl.substring(0, slashIndex); - String tempPath = desiredUrl.substring(slashIndex); - // Do not set empty strings. If there is no path, then it should be - // null - if (StringUtil.hasText(tempPath)) { - this.path = tempPath; - } - } else { - hostAndDomain = desiredUrl; - } - - // CF Route builder does not validate, so don't allow exceptions to - // prevent parsing of the route. The builder should attempt to build - // a route the best way it can, even if it may have invalid information. - // This allows external participants, like the CF Java client, to - // perform validation - try { - String[] portSegments = hostAndDomain.split(":"); - if (portSegments.length == 2) { - hostAndDomain = portSegments[0]; - this.port = Integer.parseInt(portSegments[1]); - } - } catch (NumberFormatException e) { - Log.log(e); - } - - this.domain = findDomain(hostAndDomain, domains); - - if (this.domain != null) { - matchedHost = hostAndDomain.substring(0, hostAndDomain.length() - this.domain.length()); - if (matchedHost.endsWith(".")) { - matchedHost = matchedHost.substring(0, matchedHost.length() - 1); - } - - // Don't set empty strings - if (StringUtil.hasText(matchedHost)) { - this.host = matchedHost; - } - } else { - // Do a basic split on '.', where first segment is the host, and the - // rest domain - int firstDotIndex = hostAndDomain.indexOf('.'); - if (firstDotIndex >= 0) { - String tempDomain = hostAndDomain.substring(firstDotIndex + 1); - // Don't set empty strings - if (StringUtil.hasText(tempDomain)) { - this.domain = tempDomain; - } - - String tempHost = hostAndDomain.substring(0, firstDotIndex); - if (StringUtil.hasText(tempHost)) { - this.host = tempHost; - } - } else { - if (StringUtil.hasText(hostAndDomain)) { - this.host = hostAndDomain; - } - } - } - - return this; - } - - public static String findDomain(String hostDomain, Collection domains) { - if (hostDomain == null) { - return null; - } - // find exact match - for (String name : domains) { - if (hostDomain.equals(name)) { - return hostDomain; - } - } - // Otherwise split on the first "." and try again - if (hostDomain.indexOf(".") >= 0 && hostDomain.indexOf(".") + 1 < hostDomain.length()) { - String remaining = hostDomain.substring(hostDomain.indexOf(".") + 1, hostDomain.length()); - return findDomain(remaining, domains); - } else { - return null; - } - } - - /** - * A basic building of a full route value. It performs no validation, just - * builds based on whether the parameter are set - * - * @param host - * @param domain - * @param path - * @param port - * @return Route value build with the given components. Always returns a non-null route. Empty route if no arguments are passed. - */ - public static String buildRouteVal(String host, String domain, String path, int port) { - - StringBuilder builder = new StringBuilder(); - if (StringUtil.hasText(host)) { - builder.append(host); - } - - if (StringUtil.hasText(domain)) { - if (StringUtil.hasText(host)) { - builder.append('.'); - } - builder.append(domain); - } - - if (port != CFRoute.NO_PORT) { - builder.append(':'); - builder.append(Integer.toString(port)); - } - - if (StringUtil.hasText(path)) { - if (!path.startsWith("/")) { - builder.append('/'); - } - builder.append(path); - } - - return builder.toString(); - } - - public CFRouteBuilder from(String desiredUrl, List cloudDomains) { - List domains = cloudDomains - .stream() - .map(CFCloudDomain::getName) - .collect(Collectors.toList()); - return from(desiredUrl, domains); - } -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFWrappingV2.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFWrappingV2.java deleted file mode 100644 index 0e0c7a00c..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CFWrappingV2.java +++ /dev/null @@ -1,293 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client.v2; - -import java.util.List; -import java.util.UUID; -import java.util.stream.Collectors; - -import org.cloudfoundry.client.v2.buildpacks.BuildpackResource; -import org.cloudfoundry.operations.applications.ApplicationDetail; -import org.cloudfoundry.operations.applications.ApplicationSummary; -import org.cloudfoundry.operations.applications.InstanceDetail; -import org.cloudfoundry.operations.domains.Domain; -import org.cloudfoundry.operations.domains.Status; -import org.cloudfoundry.operations.organizations.OrganizationSummary; -import org.cloudfoundry.operations.services.ServiceInstance; -import org.cloudfoundry.operations.services.ServiceInstanceType; -import org.cloudfoundry.operations.spaces.SpaceSummary; -import org.cloudfoundry.operations.stacks.Stack; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFAppState; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFBuildpack; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFInstanceState; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFInstanceStats; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFOrganization; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFServiceInstance; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFStack; -import org.springframework.ide.eclipse.boot.util.Log; - -import com.google.common.collect.ImmutableList; - -/** - * Various helper methods to 'wrap' objects returned by CF client into - * our own types, so that we do not directly expose library types to our - * code. - * - * @author Kris De Volder - */ -public class CFWrappingV2 { - - public static CFBuildpack wrap(BuildpackResource rsrc) { - String name = rsrc.getEntity().getName(); - return new CFBuildpack() { - @Override - public String getName() { - return name; - } - }; - } - - public static CFApplicationDetail wrap(ApplicationDetail details, ApplicationExtras extras) { - if (details!=null) { - List instances = ImmutableList.copyOf( - details.getInstanceDetails() - .stream() - .map(CFWrappingV2::wrap) - .collect(Collectors.toList()) - ); - CFApplicationSummaryData summary = wrapSummary(details, extras); - return new CFApplicationDetailData( - summary, - instances - ); - } - return null; - } - - public static CFStack wrap(Stack stack) { - if (stack!=null) { - String name = stack.getName(); - return new CFStack() { - @Override - public String getName() { - return name; - } - - @Override - public String toString() { - return "CFStack("+name+")"; - } - }; - } - return null; - } - - public static CFApplicationDetail wrap( - CFApplicationSummaryData summary, - ApplicationDetail details - ) { - List instanceDetails = ImmutableList.copyOf( - details - .getInstanceDetails() - .stream() - .map(CFWrappingV2::wrap) - .collect(Collectors.toList()) - ); - return new CFApplicationDetailData(summary, instanceDetails); - } - - public static CFCloudDomain wrap(Domain domain) { - if (domain!=null) { - return new CFCloudDomainData( - domain.getName(), - CFWrappingV2.wrapDomainType(domain.getType()), - CFWrappingV2.wrap(domain.getStatus()) - ); - } - return null; - } - - public static CFDomainStatus wrap(Status status) { - if (status!=null) { - return CFDomainStatus.valueOf(status.name()); - } - return null; - } - - public static CFDomainType wrapDomainType(String type) { - if (type!=null) { - return CFDomainType.valueOf(type.toUpperCase()); - } - return CFDomainType.HTTP; - } - - public static CFInstanceStats wrap(InstanceDetail instanceDetail) { - return new CFInstanceStats() { - @Override - public CFInstanceState getState() { - try { - return CFInstanceState.valueOf(instanceDetail.getState()); - } catch (Exception e) { - Log.log(e); - return CFInstanceState.UNKNOWN; - } - } - - @Override - public String toString() { - return ""+getState(); - } - }; - } - - private static CFApplicationSummaryData wrapSummary(ApplicationDetail app, ApplicationExtras extras) { - CFAppState state; - try { - state = CFAppState.valueOf(app.getRequestedState()); - } catch (Exception e) { - Log.log(e); - state = CFAppState.UNKNOWN; - } - - return new CFApplicationSummaryData( - app.getName(), - app.getInstances(), - app.getRunningInstances(), - app.getMemoryLimit(), - UUID.fromString(app.getId()), - app.getUrls(), - state, - app.getDiskQuota(), - extras - ); - } - - public static CFApplication wrap(ApplicationSummary app, ApplicationExtras extras) { - CFAppState state; - try { - state = CFAppState.valueOf(app.getRequestedState()); - } catch (Exception e) { - Log.log(e); - state = CFAppState.UNKNOWN; - } - - return new CFApplicationSummaryData( - app.getName(), - app.getInstances(), - app.getRunningInstances(), - app.getMemoryLimit(), - UUID.fromString(app.getId()), - app.getUrls(), - state, - app.getDiskQuota(), - extras - ); - } - - public static CFServiceInstance wrap(final ServiceInstance service) { - return new CFServiceInstance() { - - @Override - public String getName() { - return service.getName(); - } - - @Override - public String getPlan() { - return service.getPlan(); - } - - @Override - public String getDashboardUrl() { - return service.getDashboardUrl(); - } - - @Override - public String getService() { - if (service.getType()==ServiceInstanceType.USER_PROVIDED) { - return "user-provided"; - } else { - return service.getService(); - } - } - - @Override - public String getDescription() { - return service.getDescription(); - } - - @Override - public String getDocumentationUrl() { - return service.getDocumentationUrl(); - } - }; - } - - public static CFAppState wrapAppState(String s) { - try { - return CFAppState.valueOf(s); - } catch (Exception e) { - Log.log(e); - return CFAppState.UNKNOWN; - } - } - - public static CFSpace wrap(OrganizationSummary org, SpaceSummary space) { - return new CFSpace() { - @Override - public String getName() { - return space.getName(); - } - @Override - public CFOrganization getOrganization() { - return wrap(org); - } - @Override - public UUID getGuid() { - return UUID.fromString(space.getId()); - } - - @Override - public String toString() { - return "CFSpace("+org.getName()+" / "+getName()+")"; - } - }; - } - - public static CFOrganization wrap(OrganizationSummary org) { - return new CFOrganization() { - @Override - public String getName() { - return org.getName(); - } - - @Override - public UUID getGuid() { - return UUID.fromString(org.getId()); - } - }; - } - - public static CFBuildpack buildpack(String name) { - return new CFBuildpack() { - @Override - public String getName() { - return name; - } - }; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CloudFoundryClientCache.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CloudFoundryClientCache.java deleted file mode 100644 index f7709bb4e..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/CloudFoundryClientCache.java +++ /dev/null @@ -1,261 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 2018 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.cf.client.v2; - -import java.net.URL; -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import org.cloudfoundry.client.CloudFoundryClient; -import org.cloudfoundry.client.v2.info.GetInfoRequest; -import org.cloudfoundry.client.v2.info.GetInfoResponse; -import org.cloudfoundry.reactor.DefaultConnectionContext; -import org.cloudfoundry.reactor.ProxyConfiguration; -import org.cloudfoundry.reactor.TokenProvider; -import org.cloudfoundry.reactor.client.ReactorCloudFoundryClient; -import org.cloudfoundry.reactor.doppler.ReactorDopplerClient; -import org.cloudfoundry.reactor.tokenprovider.OneTimePasscodeTokenProvider; -import org.cloudfoundry.reactor.tokenprovider.PasswordGrantTokenProvider; -import org.cloudfoundry.reactor.tokenprovider.RefreshTokenGrantTokenProvider; -import org.cloudfoundry.reactor.uaa.ReactorUaaClient; -import org.eclipse.core.net.proxy.IProxyData; -import org.eclipse.core.net.proxy.IProxyService; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.util.Log; -import org.springsource.ide.eclipse.commons.frameworks.core.util.StringUtils; - -import reactor.core.publisher.Mono; - -/** - * TODO: Remove this class when the 'thread leak bug' in V2 client is fixed. - * - * At the moment each time {@link SpringCloudFoundryClient} is create a threadpool - * is created by the client and it is never cleaned up. The only way we have - * to mitigate this leak is to try and create as few clients as possible. - *

- * So we have a permanent cache of clients here that is reused. - *

- * When the bug is fixed then this should no longer be necessary and we can removed this cache - * and just create the client as needed. - * - * @author Kris De Volder - */ -public class CloudFoundryClientCache { - - public class CFClientProvider { - - final DefaultConnectionContext connection; - final TokenProvider tokenProvider; - - //Note: the three client objects below are 'stateless' wrappers and it would be - // fine to recreate as needed instead of store them - - final CloudFoundryClient client; - final ReactorUaaClient uaaClient; - final ReactorDopplerClient doppler; - final Mono info; - - private ProxyConfiguration getProxy(String host) { - try { - if (StringUtils.hasText(host)) { - URL url = new URL("https://"+host); - // In certain cases, the activator would have stopped and the plugin may - // no longer be available. Usually onl happens on shutdown. - BootDashActivator plugin = BootDashActivator.getDefault(); - if (plugin != null) { - IProxyService proxyService = plugin.getProxyService(); - if (proxyService != null) { - IProxyData[] selectedProxies = proxyService.select(url.toURI()); - - // No proxy configured or not found - if (selectedProxies == null || selectedProxies.length == 0) { - return null; - } - - IProxyData data = selectedProxies[0]; - int proxyPort = data.getPort(); - String proxyHost = data.getHost(); - String user = data.getUserId(); - String password = data.getPassword(); - if (proxyHost!=null) { - return ProxyConfiguration.builder() - .host(proxyHost) - .port(proxyPort==-1?Optional.empty():Optional.of(proxyPort)) - .username(Optional.ofNullable(user)) - .password(Optional.ofNullable(password)) - .build(); -// return proxyHost != null ? new HttpProxyConfiguration(proxyHost, proxyPort, -// data.isRequiresAuthentication(), user, password) : null; - } - } - } - } - } catch (Exception e) { - Log.log(e); - } - return null; - } - - public CFClientProvider(Params params) { - long sslTimeout = Long.getLong("sts.bootdash.cf.client.ssl.handshake.timeout", 60); //TODO: make a preference for this? - Optional keepAlive = getBooleanSystemProp("http.keepAlive"); - debug("cf client keepAlive = "+keepAlive); - connection = DefaultConnectionContext.builder() - .proxyConfiguration(Optional.ofNullable(getProxy(params.host))) - .apiHost(params.host) - .sslHandshakeTimeout(Duration.ofSeconds(sslTimeout)) - .keepAlive(keepAlive) - .skipSslValidation(params.skipSsl) - .build(); - - tokenProvider = createTokenProvider(params); - - client = ReactorCloudFoundryClient.builder() - .connectionContext(connection) - .tokenProvider(tokenProvider) - .build(); - - uaaClient = ReactorUaaClient.builder() - .connectionContext(connection) - .tokenProvider(tokenProvider) - .build(); - - doppler = ReactorDopplerClient.builder() - .connectionContext(connection) - .tokenProvider(tokenProvider) - .build(); - - // Cache CF client info - workaround for https://www.pivotaltracker.com/story/show/158741609 - info = client.info().get(GetInfoRequest.builder().build()).cache(); - } - - private TokenProvider createTokenProvider(Params params) { - CFCredentials creds = params.credentials; - switch (creds.getType()) { - case PASSWORD: - return PasswordGrantTokenProvider.builder() - .username(params.username) - .password(creds.getSecret()) - .build(); - case REFRESH_TOKEN: - return RefreshTokenGrantTokenProvider.builder() - .token(creds.getSecret()) - .build(); - case TEMPORARY_CODE: - return OneTimePasscodeTokenProvider.builder() - .passcode(creds.getSecret()) - .build(); - default: - throw new IllegalStateException("BUG! Missing switch case?"); - } - } - - private Optional getBooleanSystemProp(String name) { - String str = System.getProperty(name); - if (str!=null) { - return Optional.of(Boolean.valueOf(str)); - } - return Optional.empty(); - } - } - - private static final boolean DEBUG = true; - - private static void debug(String string) { - if (DEBUG) { - System.out.println(string); - } - } - - public static class Params { - public final String username; - public final CFCredentials credentials; - public final String host; - public final boolean skipSsl; - public Params(String username, CFCredentials credentials, String host, boolean skipSsl) { - super(); - this.username = username; - this.credentials = credentials; - this.host = host; - this.skipSsl = skipSsl; - } - - @Override - public String toString() { - return "Params [username=" + username + ", host=" + host + ", skipSsl=" + skipSsl - + "]"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((host == null) ? 0 : host.hashCode()); - result = prime * result + ((credentials == null) ? 0 : credentials.hashCode()); - result = prime * result + (skipSsl ? 1231 : 1237); - result = prime * result + ((username == null) ? 0 : username.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; - Params other = (Params) obj; - if (host == null) { - if (other.host != null) - return false; - } else if (!host.equals(other.host)) - return false; - if (credentials == null) { - if (other.credentials != null) - return false; - } else if (!credentials.equals(other.credentials)) - return false; - if (skipSsl != other.skipSsl) - return false; - if (username == null) { - if (other.username != null) - return false; - } else if (!username.equals(other.username)) - return false; - return true; - } - } - - private Map cache = new HashMap<>(); - - private int clientCount = 0; - - public synchronized CFClientProvider getOrCreate(String username, CFCredentials credentials, String host, boolean skipSsl) { - Params params = new Params(username, credentials, host, skipSsl); - CFClientProvider client = cache.get(params); - if (client==null) { - clientCount++; - debug("Creating client ["+clientCount+"]: "+params); - cache.put(params, client = create(params)); - } else { - debug("Reusing client ["+clientCount+"]: "+params); - } - return client; - } - - protected CFClientProvider create(Params params) { - return new CFClientProvider(params); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/DefaultClientRequestsV2.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/DefaultClientRequestsV2.java deleted file mode 100644 index edae43a2d..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/DefaultClientRequestsV2.java +++ /dev/null @@ -1,1376 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 2018 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.cf.client.v2; - -import java.io.IOException; -import java.time.Duration; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Function; -import java.util.function.Predicate; - -import org.apache.commons.lang3.RandomStringUtils; -import org.cloudfoundry.client.CloudFoundryClient; -import org.cloudfoundry.client.v2.applications.ApplicationEntity; -import org.cloudfoundry.client.v2.applications.GetApplicationResponse; -import org.cloudfoundry.client.v2.applications.UpdateApplicationRequest; -import org.cloudfoundry.client.v2.applications.UpdateApplicationResponse; -import org.cloudfoundry.client.v2.buildpacks.ListBuildpacksRequest; -import org.cloudfoundry.client.v2.buildpacks.ListBuildpacksResponse; -import org.cloudfoundry.client.v2.info.GetInfoRequest; -import org.cloudfoundry.client.v2.info.GetInfoResponse; -import org.cloudfoundry.client.v2.serviceinstances.DeleteServiceInstanceRequest; -import org.cloudfoundry.client.v2.stacks.GetStackRequest; -import org.cloudfoundry.client.v2.stacks.GetStackResponse; -import org.cloudfoundry.client.v2.userprovidedserviceinstances.DeleteUserProvidedServiceInstanceRequest; -import org.cloudfoundry.client.v2.users.GetUserRequest; -import org.cloudfoundry.doppler.LogMessage; -import org.cloudfoundry.doppler.MessageType; -import org.cloudfoundry.operations.CloudFoundryOperations; -import org.cloudfoundry.operations.DefaultCloudFoundryOperations; -import org.cloudfoundry.operations.applications.ApplicationDetail; -import org.cloudfoundry.operations.applications.ApplicationHealthCheck; -import org.cloudfoundry.operations.applications.ApplicationManifest; -import org.cloudfoundry.operations.applications.DeleteApplicationRequest; -import org.cloudfoundry.operations.applications.GetApplicationEnvironmentsRequest; -import org.cloudfoundry.operations.applications.GetApplicationRequest; -import org.cloudfoundry.operations.applications.LogsRequest; -import org.cloudfoundry.operations.applications.PushApplicationManifestRequest; -import org.cloudfoundry.operations.applications.RestartApplicationRequest; -import org.cloudfoundry.operations.applications.StartApplicationRequest; -import org.cloudfoundry.operations.applications.StopApplicationRequest; -import org.cloudfoundry.operations.domains.Domain; -import org.cloudfoundry.operations.organizations.OrganizationDetail; -import org.cloudfoundry.operations.organizations.OrganizationInfoRequest; -import org.cloudfoundry.operations.organizations.OrganizationSummary; -import org.cloudfoundry.operations.routes.Level; -import org.cloudfoundry.operations.routes.ListRoutesRequest; -import org.cloudfoundry.operations.routes.MapRouteRequest; -import org.cloudfoundry.operations.routes.UnmapRouteRequest; -import org.cloudfoundry.operations.services.BindServiceInstanceRequest; -import org.cloudfoundry.operations.services.CreateServiceInstanceRequest; -import org.cloudfoundry.operations.services.CreateUserProvidedServiceInstanceRequest; -import org.cloudfoundry.operations.services.GetServiceInstanceRequest; -import org.cloudfoundry.operations.services.ServiceInstance; -import org.cloudfoundry.operations.services.ServiceInstanceSummary; -import org.cloudfoundry.operations.services.UnbindServiceInstanceRequest; -import org.cloudfoundry.reactor.DefaultConnectionContext; -import org.cloudfoundry.reactor.tokenprovider.AbstractUaaTokenProvider; -import org.cloudfoundry.uaa.UaaClient; -import org.cloudfoundry.util.PaginationUtils; -import org.eclipse.core.runtime.Platform; -import org.osgi.framework.Version; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFBuildpack; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFServiceInstance; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFStack; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.SshClientSupport; -import org.springframework.ide.eclipse.boot.dash.cf.client.SshHost; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CloudFoundryClientCache.CFClientProvider; -import org.springframework.ide.eclipse.boot.dash.console.IApplicationLogConsole; -import org.springframework.ide.eclipse.boot.dash.console.LogType; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; -import org.springframework.ide.eclipse.boot.util.Log; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMap.Builder; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; - -import reactor.core.Disposable; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * @author Kris De Volder - * @author Nieraj Singh - */ -public class DefaultClientRequestsV2 implements ClientRequests { - - private static AtomicLong instances = new AtomicLong(0); - - public static final Duration APP_START_TIMEOUT = Duration.ofMinutes(10); - public static final Duration GET_SERVICES_TIMEOUT = Duration.ofSeconds(60); - public static final Duration GET_SPACES_TIMEOUT = Duration.ofSeconds(20); - public static final Duration GET_USERNAME_TIMEOUT = Duration.ofSeconds(5); - public static final Duration GET_SMALL_INFO_TIMEOUT = Duration.ofSeconds(20); - - private static final boolean DEBUG = (""+Platform.getLocation()).contains("kdvolder") || (""+Platform.getLocation()).contains("bamboo"); -// private static final boolean DEBUG_REACTOR = (""+Platform.getLocation()).contains("kdvolder"); - //|| (""+Platform.getLocation()).contains("bamboo"); - - - private static void debug(String string) { - if (DEBUG) { - System.out.println(string); - } - } - -// static { -// if (DEBUG_REACTOR) { -// Loggers.enableExtension(new Extension() { -// @Override -// public void log(String category, java.util.logging.Level level, String msg, Object... arguments) { -// debug(category +"["+level + "] : "+MessageFormatter.format(msg, arguments).getMessage()); -// } -// }); -// } -// } - - - private CFClientParams params; - private CloudFoundryClient _client ; - private UaaClient _uaa; - private CloudFoundryOperations _operations; - - private Mono orgId; - private Mono info; - private AbstractUaaTokenProvider _tokenProvider; - private DefaultConnectionContext _connection; - private String refreshToken = null; - private Flux refreshTokensFlux; - - private CompletableFuture _disposed = new CompletableFuture<>(); - - public DefaultClientRequestsV2(CloudFoundryClientCache clients, CFClientParams params) { - this.params = params; - CFClientProvider provider = clients.getOrCreate(params.getUsername(), params.getCredentials(), params.getHost(), params.skipSslValidation()); - this._client = provider.client; - this._uaa = provider.uaaClient; - this._tokenProvider = (AbstractUaaTokenProvider) provider.tokenProvider; - this._connection = provider.connection; - refreshTokensFlux = _tokenProvider.getRefreshTokens(_connection).takeUntilOther(Mono.fromFuture(_disposed)); - refreshTokensFlux.doOnNext((t) -> { - this.refreshToken = t; - }).subscribe(); - - debug(">>> creating cf operations"); - this._operations = DefaultCloudFoundryOperations.builder() - .cloudFoundryClient(_client) - .dopplerClient(provider.doppler) - .uaaClient(provider.uaaClient) - .organization(params.getOrgName()) - .space(params.getSpaceName()) - .build(); - debug("<<< creating cf operations"); - this.orgId = getOrgId(); - // Use cached info, workaround for https://www.pivotaltracker.com/story/show/158741609 - this.info = provider.info; - debug("DefaultClientRequestsV2 created: "+instances.incrementAndGet()); - } - - private Mono client_createOperations(OrganizationSummary org) { - return log("client.createOperations(org="+org.getName()+")", - Mono.fromCallable(() -> DefaultCloudFoundryOperations.builder() - .cloudFoundryClient(_client) - .organization(org.getName()) - .build() - ) - ); - } - - private Mono getOrgId() { - String orgName = params.getOrgName(); - if (orgName==null) { - return Mono.error(new IOException("No organization targetted")); - } else { - return operations_getOrgId().cache(); - } - } - - @Override - public List getApplicationsWithBasicInfo() throws Exception { - return ReactorUtils.get(operations_listApps()); - } - - private ApplicationExtras getApplicationExtras(String appName) { - //Stuff used in computing the 'extras'... - Mono appIdMono = getApplicationId(appName); - Mono entity = appIdMono - .flatMap((appId) -> - client_getApplication(appId) - ) - .map((appResource) -> appResource.getEntity()) - .cache(); - - //The stuff returned from the getters of 'extras'... - Mono> services = prefetch("services", getBoundServicesList(appName)); - Mono> env = prefetch("env", - DefaultClientRequestsV2.this.getEnv(appName) - ); - Mono buildpack = prefetch("buildpack", - entity.flatMap((e) -> Mono.justOrEmpty(e.getBuildpack())) - ); - - Mono stack = prefetch("stack", - entity.flatMap((e) -> Mono.justOrEmpty(e.getStackId())) - .flatMap((stackId) -> { - return client_getStack(stackId); - }).map((response) -> { - return response.getEntity().getName(); - }) - ); - Mono timeout = prefetch("timeout", - entity - .flatMap((v) -> Mono.justOrEmpty(v.getHealthCheckTimeout())) - ); - - Mono command = prefetch("command", - entity.flatMap((e) -> Mono.justOrEmpty(e.getCommand())) - ); - - Mono healthCheckType = prefetch("healthCheckType", - entity.flatMap((e) -> Mono.justOrEmpty(e.getHealthCheckType())) - ); - - Mono healthCheckHttpEndpoint = prefetch("healthCheckHttpEndpoint", - entity.flatMap((e) -> Mono.justOrEmpty(e.getHealthCheckHttpEndpoint())) - ); - - return new ApplicationExtras() { - @Override - public Mono> getServices() { - return services; - } - - @Override - public Mono> getEnv() { - return env; - } - - @Override - public Mono getBuildpack() { - return buildpack; - } - - @Override - public Mono getStack() { - return stack; - } - - @Override - public Mono getTimeout() { - return timeout; - } - - @Override - public Mono getCommand() { - return command; - } - - @Override - public Mono getHealthCheckType() { - return healthCheckType; - } - - @Override - public Mono getHealthCheckHttpEndpoint() { - return healthCheckHttpEndpoint; - } - }; - } - - private Mono prefetch(String id, Mono toFetch) { - return toFetch -// .log(id + " before error handler") - .onErrorResume((error) -> { - Log.log(new IOException("Failed prefetch '"+id+"'", error)); - return Mono.empty(); - }) -// .log(id + " after error handler") - .cache() -// .log(id + "after cache") - ; - } - -// private Mono prefetch(Mono toFetch) { -// Mono result = toFetch -// .cache(); // It should only be fetched once. -// -// //We must ensure the 'result' is being consumed by something to force its execution: -// result -// .publishOn(SCHEDULER_GROUP) //Ensure the consume is truly async or it may block here. -// .consume((dont_care) -> {}); -// -// return result; -// } - - @Override - public List getServices() throws Exception { - return ReactorUtils.get(GET_SERVICES_TIMEOUT, CancelationTokens.NULL, - log("operations.services.listInstances()", - _operations - .services() - .listInstances() - .flatMap(this::getServiceDetails) - .map(CFWrappingV2::wrap) - .collectList() - .map(ImmutableList::copyOf) - ) - ); - } - - - private Mono getServiceDetails(ServiceInstanceSummary summary) { - return log("operations.service.getServiceInstance", - _operations.services().getInstance(GetServiceInstanceRequest.builder() - .name(summary.getName()) - .build() - ) - ); - } - /** - * Get details for a given list of applications. This does a 'best' effort getting the details for - * as many apps as possible but it does not guarantee that it will return details for each app in the - * list. This is to avoid one 'bad apple' from spoiling the whole batch. (I.e if failing to fetch details for - * some apps we can still return details for the others rather than throw an exception). - */ - @Override - public Flux getApplicationDetails(List appsToLookUp) throws Exception { - return Flux.fromIterable(appsToLookUp) - .flatMap((CFApplication appSummary) -> { - return getApplicationDetail(appSummary.getName()) - .onErrorResume((error) -> { - Log.log(ExceptionUtil.coreException("getting application details for '"+appSummary.getName()+"' failed", error)); - return Mono.empty(); - }) - .map((ApplicationDetail appDetails) -> CFWrappingV2.wrap((CFApplicationSummaryData)appSummary, appDetails)); - }); - } - - @Override - public Disposable streamLogs(String appName, IApplicationLogConsole logConsole) throws Exception { - Flux stream = log("operations.applications.logs()", - _operations.applications() - .logs(LogsRequest.builder() - .name(appName) - // BUG: show recent appears to throw exception with PWS. May be fixed in the future, but now only "pure" streaming is supported - .recent(false) - .build() - ) - ) - .retryWhen(retryInterval(Duration.ofMillis(500), Duration.ofMinutes(1))) - ; - - Disposable cancellation = ReactorUtils.sort( - stream, - (m1, m2) -> Long.compare(m1.getTimestamp(), m2.getTimestamp()), - Duration.ofSeconds(1) - ) - .map(this::convertMessageFromDoppler) - .subscribe(logConsole::onMessage, logConsole::onError); - - return cancellation; - } - - - private org.springframework.ide.eclipse.boot.dash.console.LogMessage convertMessageFromDoppler(LogMessage msg) { - return new org.springframework.ide.eclipse.boot.dash.console.LogMessage( - convertMessageTypeFromDoppler(msg.getMessageType()), - msg.getMessage() - ); - } - - private LogType convertMessageTypeFromDoppler(MessageType mt) { - switch (mt) { - case OUT: - return LogType.APP_OUT; - case ERR: - return LogType.APP_ERROR; - default: - return LogType.APP_OUT; - } - } - /** - * Creates a retry 'signal factory' to be used with Flux.retryWhen. - *

- * @param timeBetween How much time to wait before retrying after a failure - * @param duration If this much time has elapsed when the error happens there will be no further retries. - * @return Functon that can be passed to retryWhen. - */ - private Function, Flux> retryInterval(Duration timeBetween, Duration duration) { - Predicate falseAfterDuration = falseAfter(duration); - return (errors) -> { - return errors.flatMap((error) -> { - if (falseAfterDuration.test(error)) { - return Mono.delay(timeBetween); - } else { - return Mono.error(error); - } - }); - }; - } - - private Predicate falseAfter(Duration timeToWait) { - return new Predicate() { - - private Long firstCalledAt; - - @Override - public boolean test(Throwable t) { - if (firstCalledAt==null) { - firstCalledAt = System.currentTimeMillis(); - } - long waitedTime = System.currentTimeMillis() - firstCalledAt; - //debug("falseAfter: remaining = "+(timeToWait.toMillis() - waitedTime)); - return waitedTime < timeToWait.toMillis(); - } - - }; - } - - @Override - public void stopApplication(String appName) throws Exception { - ReactorUtils.get( - stopApp(appName) - ); - } - - private Mono stopApp(String appName) { - return log("operations.applications.stop(name="+appName+")", - _operations.applications().stop(StopApplicationRequest.builder() - .name(appName) - .build() - ) - ); - } - - @Override - public void restartApplication(String appName, CancelationToken cancelationToken) throws Exception { - ReactorUtils.get(APP_START_TIMEOUT, cancelationToken, - restartApp(appName) - ); - } - - private Mono restartApp(String appName) { - return log("operations.applications().restart(name="+appName+")", - _operations.applications().restart(RestartApplicationRequest.builder() - .name(appName) - .build()) - ); - } - - @Override - public void dispose() { - synchronized (this) { - if (_client!=null) { - _client = null; - _connection = null; - _operations = null; - _disposed.complete(true); - debug("DefaultClientRequestsV2.logout: "+instances.decrementAndGet()); - } - } - } - - public boolean isLoggedOut() { - return _client==null; - } - - @Override - public List getStacks() throws Exception { - return ReactorUtils.get( - log("operations.stacks().list()", - _operations.stacks() - .list() - .map(CFWrappingV2::wrap) - .collectList() - ) - ); - } - - @Override - public SshClientSupport getSshClientSupport() throws Exception { - return new SshClientSupport() { - - @Override - public String getSshUser(UUID appGuid, int instance) { - return "cf:"+appGuid+"/" + instance; - } - - @Override - public String getSshUser(String appName, int instance) throws Exception { - return ReactorUtils.get( - getApplicationId(appName) - .map((guid) -> getSshUser(guid, instance)) - ); - } - - @Override - public SshHost getSshHost() throws Exception { - return ReactorUtils.get( - info.flatMap((i) -> { - String fingerPrint = i.getApplicationSshHostKeyFingerprint(); - String host = i.getApplicationSshEndpoint(); - int port = 22; //Default ssh port - if (host!=null) { - if (host.contains(":")) { - String[] pieces = host.split(":"); - host = pieces[0]; - port = Integer.parseInt(pieces[1]); - } - } - if (host!=null) { - return Mono.just(new SshHost(host, port, fingerPrint)); - } - // Workaround for bug in Eclipse Neon.1 JDT cannot properly infer type SshHost. - // Works in Mars. Returning Mono.empty() results in compilation error in Neon.1 - return Mono.empty(); - }) - ); - } - - @Override - public String getSshCode() throws Exception { - return ReactorUtils.get( - log("operations.advanced.sshCode()", - _operations.advanced().sshCode() - ) - ); - } - }; - } - - private Mono operationsFor(OrganizationSummary org) { - return client_createOperations(org); - } - - @Override - public List getSpaces() throws Exception { - Object it = ReactorUtils.get(GET_SPACES_TIMEOUT, log("operations.organizations().list()", - _operations.organizations() - .list() - ) - .flatMap((OrganizationSummary org) -> { - return operationsFor(org).flatMapMany((operations) -> - log("operations.spaces.list(org="+org.getId()+")", - operations - .spaces() - .list() - .map((space) -> CFWrappingV2.wrap(org, space)) - ) - ); - }) - .collectList() - ); - //workaround eclipse jdt bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=501949 - return (List) it; - } - - @Override - public String getHealthCheck(UUID appGuid) throws Exception { - //XXX CF V2: getHealthcheck (via operations API) - // See: https://www.pivotaltracker.com/story/show/116462215 - return ReactorUtils.get( - client_getApplication(appGuid) - .map((response) -> response.getEntity().getHealthCheckType()) - ); - } - - @Override - public void setHealthCheck(UUID guid, String hcType) throws Exception { - //XXX CF V2: setHealthCheck (via operations API) - // See: https://www.pivotaltracker.com/story/show/116462369 - ReactorUtils.get( - client_setHealthCheck(guid, hcType) - ); - } - - @Override - public List getDomains() throws Exception { - return getDomainsOracle() - .getDomainsList(); - } - - private DomainsOracle getDomainsOracle() { - return new DomainsOracle(); - } - - /** - * DomainsOracle answers questions about domains. It only reads the domain information from - * CF once. (However, every newly created instance of DomainsOracle will read the info the - * first time it needs it. - */ - private class DomainsOracle { - private Mono> domains = orgId - .flatMapMany(this::requestDomains) - .map(CFWrappingV2::wrap) - .collectList() - .cache(); - - private Mono> domainsByName = domains - .map(allDomains -> { - ImmutableMap.Builder builder = ImmutableMap.builder(); - for (CFCloudDomain d : allDomains) { - builder.put(d.getName(), d); - } - return (Map)builder.build(); - }) - .cache(); - - public Mono> getDomainsMono() { - return domains; - } - - public List getDomainsList() throws Exception { - return ReactorUtils.get(domains); - } - - private Flux requestDomains(String orgId) { - return log("operations.domains.list", - _operations.domains().list() - ); - } - - public Mono isTcp(String domainName) { - return domainsByName.flatMap(dmap -> { - CFCloudDomain domain = dmap.get(domainName); - return Mono.just(domain!=null && domain.getType()==CFDomainType.TCP); - }); - } - } - - @Override - public List getBuildpacks() throws Exception { - //XXX CF V2: getBuilpacks using 'operations' API. - return ReactorUtils.get( - PaginationUtils.requestClientV2Resources((page) -> { - return client_listBuildpacks(page); - }) - .map(CFWrappingV2::wrap) - .collectList() - ); - } - - @Override - public CFApplicationDetail getApplication(String appName) throws Exception { - return ReactorUtils.get( - getApplicationMono(appName) - // .log("getApplication("+appName+")") - ); - } - - private Mono getApplicationMono(String appName) { - return getApplicationDetail(appName) - .map((appDetail) -> { - //TODO: we have 'real' appdetails now so we could get most of the 'application extras' info from that. - return CFWrappingV2.wrap(appDetail, getApplicationExtras(appName)); - }) - .onErrorResume(ReactorUtils.suppressException(IllegalArgumentException.class)); - } - - @Override - public Version getApiVersion() throws Exception { - return ReactorUtils.get(info - .map((i) -> new Version(i.getApiVersion())) - ); - } - - @Override - public Version getSupportedApiVersion() { - return new Version(CloudFoundryClient.SUPPORTED_API_VERSION); - } - - @Override - public void deleteApplication(String appName) throws Exception { - ReactorUtils.get( - log("operations.applications().delete(name="+appName+")", - _operations.applications().delete(DeleteApplicationRequest - .builder() - .name(appName) - .build() - ) - ) - ); - } - - @Override - public boolean applicationExists(String appName) throws Exception { - return ReactorUtils.get( - getApplicationMono(appName) - .map((app) -> true) - .switchIfEmpty(Mono.just(false)) - ); - } - - public Mono ifApplicationExists(String appName, Function> then, Mono els) throws Exception { - return getApplicationDetail(appName) - .map((app) -> Optional.of(app)) - .switchIfEmpty(Mono.just(Optional.empty())) - .onErrorResume((error) -> Mono.just(Optional.empty())) - .flatMap((Optional app) -> { - if (app.isPresent()) { - return then.apply(app.get()); - } else { - return els; - } - }); - } - - @Override - public void push(CFPushArguments params, CancelationToken cancelationToken) throws Exception { - ReactorUtils.get(APP_START_TIMEOUT, cancelationToken, - v2Push(params) - ); - } - - private Mono v2Push(CFPushArguments params) { - String appName = params.getAppName(); - - // Routes are set AFTER push, so for initial push, make sure no route is set - boolean noRoute = true; - - // Environment variables require app start, so for initial push, do not start app. - // This will happen afterwards - boolean noStart = true; - PushApplicationManifestRequest req = PushApplicationManifestRequest.builder() - .manifest(ApplicationManifest.builder() - .name(appName) - // resource matching occurs under the hood in the push operation - .path(params.getApplicationDataAsFile().toPath()) - .memory(params.getMemory()) - .disk(params.getDiskQuota()) - .timeout(params.getTimeout()) - .healthCheckType(resolveHealthCheckType(params.getHealthCheckType()).orElse(null)) - .healthCheckHttpEndpoint(params.getHealthCheckHttpEndpoint()==null?"/":params.getHealthCheckHttpEndpoint()) - .buildpack(params.getBuildpack()) - .command(params.getCommand()) - .stack(params.getStack()) - .noRoute(noRoute) - .instances(params.getInstances()) - .build() - ) - .noStart(noStart) - .build(); - - return log("client.applications.pushManifest("+req+")", - _operations.applications().pushManifest(req) - ) - .then(mono_debug("Updating routes, bound services, and environment variables...")) - .then(getApplicationDetail(appName)) - .flatMap((appDetail) -> { - return Flux.merge( - setRoutes(appDetail, params.getRoutes(), params.getRandomRoute()), - bindAndUnbindServices(appName, params.getServices()), - // This requires app restart - setEnvVars(appDetail, params.getEnv()) - ).then(); - }) - // Start app only after environment variables are set - .then(params.isNoStart() - ? stopApp(appName) - : restartApp(appName) - ) - .then(Mono.empty()); - } - - private Mono mono_debug(String string) { - return Mono.fromRunnable(() -> debug(string)); - } - - private Mono> getStackId(CFPushArguments params) { - String stackName = params.getStack(); - if (stackName==null) { - return Mono.just(Optional.empty()); - } else { - return log("operations.stacks.get("+stackName+")", - _operations.stacks().get(org.cloudfoundry.operations.stacks.GetStackRequest.builder() - .name(stackName) - .build() - ) - .map((stack) -> Optional.of(stack.getId())) - ); - } - } - - private Optional resolveHealthCheckType(String type) { - ApplicationHealthCheck appHealthCheck = null; - if (type != null) { - try { - appHealthCheck = ApplicationHealthCheck.from(type); - } catch (IllegalArgumentException e) { - Log.log(e); - } - } - return Optional.ofNullable(appHealthCheck); - } - - private Mono getApplicationDetail(String appName) { - return log("operations.applications.get(name="+appName+")", - _operations.applications().get(GetApplicationRequest.builder() - .name(appName) - .build() - ) - ); - } - - public Mono setRoutes(ApplicationDetail appDetails, Collection desiredUrls, boolean randomRoute) { - debug("setting routes for '"+appDetails.getName()+"': "+desiredUrls+", "+randomRoute); - DomainsOracle domains = new DomainsOracle(); - - //Carefull! It is not safe map/unnmap multiple routes in parallel. Doing so causes some of the - // operations to fail, presumably because of some 'optimisitic locking' being used in the database - // that keeps track of routes. - //To avoid this problem we must execute all that map / unmap calls in sequence! - return ReactorUtils.sequence( - unmapUndesiredRoutes(appDetails.getName(), desiredUrls), - mapDesiredRoutes(appDetails, domains, desiredUrls, randomRoute) - ); - } - - public Mono setRoutes(String appName, Collection desiredUrls, boolean randomRoute) { - return getApplicationDetail(appName) - .flatMap(appDetails -> setRoutes(appDetails, desiredUrls, randomRoute)); - } - - private Mono mapDesiredRoutes(ApplicationDetail appDetail, DomainsOracle domains, Collection desiredUrls, boolean randomRoute) { - Set currentUrls = ImmutableSet.copyOf(appDetail.getUrls()); - String appName = appDetail.getName(); - - debug("currentUrls = "+currentUrls); - return Flux.fromIterable(desiredUrls) - .flatMap((url) -> { - if (currentUrls.contains(url)) { - debug("skipping: "+url); - return Mono.empty(); - } else { - debug("mapping: "+url); - return mapRoute(domains, appName, url, randomRoute); - } - }, 1) //!!!IN SEQUENCE!!! - .then(); - } - - private Mono mapRoute(DomainsOracle domains, String appName, String desiredUrl, boolean randomRoute) { - debug("mapRoute: "+appName+" -> "+desiredUrl); - return toRoute(domains, desiredUrl) - .flatMap((CFRoute route) -> mapRoute(domains, appName, route, randomRoute)) - .doOnError((e) -> { - Log.info("mapRoute FAILED!"); - Log.log(e); - }); - } - - private Mono mapRoute(DomainsOracle domains, String appName, CFRoute route, boolean randomRoute) { - // Let the client validate if any of these combinations are correct. - // However, only set these values only if they are present as not doing so causes NPE - Mono _builder = Mono.just(MapRouteRequest.builder() - .applicationName(appName) - ); - if (StringUtil.hasText(route.getDomain())) { - _builder = _builder.map(builder -> builder.domain(route.getDomain())); - } - if (randomRoute) { - _builder = _builder.flatMap((MapRouteRequest.Builder builder) -> - // Can only set random port to true if route is TCP route - domains.isTcp(route.getDomain()).map(isTcp -> { - if (isTcp) { - builder.randomPort(randomRoute); - } else { - if (route.getHost()==null) { - builder.host(appName+"-"+RandomStringUtils.randomAlphabetic(8).toLowerCase()); - } - } - return builder; - }) - ); - } - _builder = _builder.map(builder -> { - if (StringUtil.hasText(route.getHost())) { - builder.host(route.getHost()); - } - if (StringUtil.hasText(route.getPath())) { - builder.path(route.getPath()); - } - if (route.getPort() != CFRoute.NO_PORT) { - builder.port(route.getPort()); - } - return builder; - }); - return _builder.flatMap(builder -> { - MapRouteRequest mapRouteReq = builder.build(); - return log("operations.routes.map("+mapRouteReq+")", - _operations.routes().map(mapRouteReq) - ); - }) - .then(); - } - - private Mono toRoute(DomainsOracle domains, String desiredUrl) { - return domains.getDomainsMono().flatMap((ds) -> { - try { - CFRoute route = CFRoute.builder().from(desiredUrl, ds).build(); - route.validate(); - return Mono.just(route); - } catch (Exception e) { - return Mono.error(e); - } - }); - } - -// private Set getUrls(ApplicationDetail app) { -// return operations.applications().get(GetApplicationRequest.builder() -// .name(appName) -// .build() -// ) -// .map((app) -> ImmutableSet.copyOf(app.getUrls())); -// } - - private Mono unmapUndesiredRoutes(String appName, Collection desiredUrls) { - return getExistingRoutes(appName) - .flatMap((route) -> { - debug("unmap? "+route); - if (desiredUrls.contains(getUrl(route))) { - debug("unmap? "+route+" SKIP"); - return Mono.empty(); - } else { - debug("unmap? "+route+" UNMAP"); - return unmapRoute(appName, route); - } - }, 1) //!!!IN SEQUENCE!!! - .then(); - } - - private String getUrl(CFRoute route) { -// String url = route.getDomain(); -// if (route.getHost()!=null) { -// url = route.getHost() + "." + url; -// } -// String path = route.getPath(); -// if (path!=null) { -// while (path.startsWith("/")) { -// path = path.substring(1); -// } -// if (StringUtils.hasText(path)) { -// url = url +"/" +path; -// } -// } - return route.getRoute(); - } - - private Mono unmapRoute(String appName, CFRoute route) { -// if (!StringUtil.hasText(path)) { -// //client doesn't like to get 'empty string' it will complain that route doesn't exist. -// path = null; -// } - org.cloudfoundry.operations.routes.UnmapRouteRequest.Builder unmapBuilder = UnmapRouteRequest.builder() - .applicationName(appName) - .domain(route.getDomain()) - .host(route.getHost()); - - // Have to check if port and path are set. Cannot just set them without checking - // otherwise exception throw, even if these values are "empty/null" in the route - if (route.getPort() != CFRoute.NO_PORT) { - unmapBuilder.port(route.getPort()); - } - if (StringUtil.hasText(route.getPath())) { - unmapBuilder.path(route.getPath()); - } - UnmapRouteRequest req = unmapBuilder - .build(); - return log("operations.routes.unmap("+req+")", - _operations.routes().unmap(req) - ); - } - - public Flux getExistingRoutes(String appName) { - return log("operations.routes.list(level=SPACE)", - _operations.routes().list(ListRoutesRequest.builder() - .level(Level.SPACE) - .build() - ) - ) - .flatMap((route) -> { - for (String app : route.getApplications()) { - if (app.equals(appName)) { - return Mono.just(CFRoute.builder().from(route).build()); - } - }; - return Mono.empty(); - }); - } - - public Mono bindAndUnbindServices(String appName, List _services) { - debug("bindAndUnbindServices "+_services); - Set services = ImmutableSet.copyOf(_services); - return getBoundServicesSet(appName) - .flatMapMany((boundServices) -> { - debug("boundServices = "+boundServices); - Set toUnbind = Sets.difference(boundServices, services); - Set toBind = Sets.difference(services, boundServices); - debug("toBind = "+toBind); - debug("toUnbind = "+toUnbind); - return Flux.merge( - bindServices(appName, toBind), - unbindServices(appName, toUnbind) - ); - }) - .then(); - } - - public Flux getBoundServices(String appName) { - return log("operations.services.listInstances()", - _operations.services().listInstances() - ) - .filter((service) -> isBoundTo(service, appName)) - .map(ServiceInstanceSummary::getName); - } - - public Mono> getBoundServicesSet(String appName) { - return getBoundServices(appName) - .collectList() - .map(ImmutableSet::copyOf); - } - - public Mono> getBoundServicesList(String appName) { - return getBoundServices(appName) - .collectList() - .map(ImmutableList::copyOf); - } - - private boolean isBoundTo(ServiceInstanceSummary service, String appName) { - return service.getApplications().stream() - .anyMatch((boundAppName) -> boundAppName.equals(appName)); - } - - private Flux bindServices(String appName, Set services) { - return Flux.fromIterable(services) - .flatMap((service) -> { - return log("operations.services().bind(appName="+appName+", services="+services+")", - _operations.services().bind(BindServiceInstanceRequest.builder() - .applicationName(appName) - .serviceInstanceName(service) - .build() - ) - ); - }); - } - - private Flux unbindServices(String appName, Set toUnbind) { - return Flux.fromIterable(toUnbind) - .flatMap((service) -> { - return log("operations.services.unbind(appName="+appName+", serviceInstanceName="+service+")", - _operations.services().unbind(UnbindServiceInstanceRequest.builder() - .applicationName(appName) - .serviceInstanceName(service) - .build() - ) - ); - }); - } - - - protected Mono startApp(String appName) { - return log("operations.applications.start(name="+appName+")", - _operations.applications() - .start(StartApplicationRequest.builder() - .name(appName) - .build() - ) - ); - } - - private Mono getApplicationId(String appName) { - return log("operations.applications.get(name="+appName+")", - _operations.applications().get(GetApplicationRequest.builder() - .name(appName) - .build() - ) - ).map((app) -> UUID.fromString(app.getId())); - } - - public Mono setEnvVars(ApplicationDetail appDetail, Map environment) { - return setEnvVars(UUID.fromString(appDetail.getId()), environment); - } - - public Mono setEnvVars(UUID appId, Map environment) { - return client_setEnv(appId, environment); - } - - public Mono setEnvVars(String appName, Map environment) { - return getApplicationId(appName) - .flatMap((applicationId) -> setEnvVars(applicationId, environment)); - } - -// protected Publisher setEnvVar(String appName, String var, String value) { -// System.out.println("Set var starting: "+var +" = "+value); -// return operations.applications() -// .setEnvironmentVariable(SetEnvironmentVariableApplicationRequest.builder() -// .name(appName) -// .variableName(var) -// .variableValue(value) -// .build() -// ) -// .after(() -> { -// System.out.println("Set var complete: "+var +" = "+value); -// return Mono.empty(); -// }); -// } - - public Mono createService(String name, String service, String plan) { - return log("operations.services.createInstance(instanceName="+name+",serviceName="+service+",planName="+plan+")", - _operations.services().createInstance(CreateServiceInstanceRequest.builder() - .serviceInstanceName(name) - .serviceName(service) - .planName(plan) - .build() - ) - ); - } - - public Mono createUserProvidedService(String name, Map credentials) { - return log("operations.services.createUserProvidedInstance(name="+name+")", - _operations.services().createUserProvidedInstance(CreateUserProvidedServiceInstanceRequest.builder() - .name(name) - .credentials(credentials) - .build() - ) - ); - } - -// @Override -// public void deleteService(String serviceName) { -// deleteServiceMono(serviceName).get(); -// } - - @Override - public Mono deleteServiceAsync(String serviceName) { - return getService(serviceName) - .flatMap(this::deleteServiceInstance); - } - - protected Mono deleteServiceInstance(ServiceInstance s) { - switch (s.getType()) { - case MANAGED: - return client_deleteServiceInstance(s); - case USER_PROVIDED: - return client_deleteUserProvidedService(s); - default: - return Mono.error(new IllegalStateException("Unknown service type: "+s.getType())); - } - } - - protected Mono getService(String serviceName) { - return log("operations.services.getInstance(name="+serviceName+")", - _operations.services().getInstance(GetServiceInstanceRequest.builder() - .name(serviceName) - .build() - ) - ); - } - - public Mono> getEnv(String appName) { - return log("operations.applications.getEnvironments(appName="+appName+")", - _operations.applications().getEnvironments(GetApplicationEnvironmentsRequest.builder() - .name(appName) - .build() - ) - ) - .map((envs) -> envs.getUserProvided()) - .map(this::dropObjectsFromMap); - } - - @Override - public Map getApplicationEnvironment(String appName) throws Exception { - return ReactorUtils.get(getEnv(appName)); - } - - private Map dropObjectsFromMap(Map map) { - Builder builder = ImmutableMap.builder(); - for (Entry entry : map.entrySet()) { - try { - builder.put(entry.getKey(), (String) entry.getValue()); - } catch (ClassCastException e) { - Log.log(e); - } - } - return builder.build(); - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - //// calls to client and operations with 'logging'. - - private Flux log(String msg, Flux flux) { - if (DEBUG) { - return flux - .doOnSubscribe((sub) -> debug(">>> "+msg)) - .doOnComplete(() -> { - debug("<<< "+msg+" OK"); - }) - .doOnCancel(() -> { - debug("<<< "+msg+" CANCEL"); - }) - .doOnError((error) -> { - debug("<<< "+msg+" ERROR: "+ExceptionUtil.getMessage(error)); - }); - } else { - return flux; - } - } - - private Mono log(String msg, Mono mono) { - if (DEBUG) { - return mono - .doOnSubscribe((sub) -> debug(">>> "+msg)) - .doOnCancel(() -> debug("<<< "+msg+" CANCEL")) - .doOnSuccess((data) -> { - debug("<<< "+msg+" OK"); - }) - .doOnError((error) -> { - debug("<<< "+msg+" ERROR: "+ExceptionUtil.getMessage(error)); - }); - } else { - return mono; - } - } - - private Mono client_getInfo() { - return log("client.info().get()", - _client.info().get(GetInfoRequest.builder().build()) - ); - } - - private Mono operations_getOrgId() { - return log("operations.organizations.get(name="+params.getOrgName()+")", - _operations.organizations().get(OrganizationInfoRequest.builder() - .name(params.getOrgName()) - .build() - ) - .map(OrganizationDetail::getId) - ); - } - - private Mono> operations_listApps() { - return log("operations.applications.list()", - _operations.applications() - .list() - .map((appSummary) -> - CFWrappingV2.wrap(appSummary, getApplicationExtras(appSummary.getName())) - ) - .collectList() - .map(ImmutableList::copyOf) - ); - } - - private Mono client_getApplication(UUID appId) { - return log("client.applicationsV2.get(id="+appId+")", - _client.applicationsV2() - .get(org.cloudfoundry.client.v2.applications.GetApplicationRequest.builder() - .applicationId(appId.toString()) - .build() - ) - ); - } - - private Mono client_getStack(String stackId) { - return log("client.stacks.get(id="+stackId+")", - _client.stacks().get(GetStackRequest.builder() - .stackId(stackId) - .build() - ) - ); - } - - private Mono client_setHealthCheck(UUID guid, String hcType) { - return log("client.applicationsV2.update(id="+guid+", hcType="+hcType+")", - _client.applicationsV2() - .update(UpdateApplicationRequest.builder() - .applicationId(guid.toString()) - .healthCheckType(hcType) - .build() - ) - ); - } - - private Mono client_listBuildpacks(Integer page) { - return log("client.buildpacks.list(page="+page+")", - _client.buildpacks() - .list(ListBuildpacksRequest.builder() - .page(page) - .build() - ) - ); - } - - private Mono client_setEnv(UUID appId, Map environment) { - return log("client.applicationsV2.update(id="+appId+", env=...)", - _client.applicationsV2() - .update(UpdateApplicationRequest.builder() - .applicationId(appId.toString()) - .environmentJsons(environment) - .build()) - .then() - ); - } - - private Mono client_deleteServiceInstance(ServiceInstance s) { - return log("client.serviceInstances.delete(id="+s.getId()+")", - _client.serviceInstances().delete(DeleteServiceInstanceRequest.builder() - .serviceInstanceId(s.getId()) - .build() - ) - .then() - ); - } - - private Mono client_deleteUserProvidedService(ServiceInstance s) { - return log("client.userProvidedServiceInstances.delete(id="+s.getId()+")", - _client.userProvidedServiceInstances().delete(DeleteUserProvidedServiceInstanceRequest.builder() - .userProvidedServiceInstanceId(s.getId()) - .build() - ) - ); - } - - @Override - public Mono getUserName() { - return log("uaa.getUsername", - /* - * UAA times out at start until the client is cached. Needs ~2 mins to fetch the user. - * Instead get userID from client info and then fetch the user complete data from id to get the user name. This works and bypasses UAA - */ -// _uaa.getUsername() - info - .flatMap(info -> _client - .users() - .get(GetUserRequest.builder().userId(info.getUser()).build()) - .map(response -> response.getEntity().getUsername())) - ).timeout(GET_USERNAME_TIMEOUT); - } - - @Override - public String getRefreshToken() { - return refreshToken; - } - - @Override - public Flux getRefreshTokens() { - return refreshTokensFlux; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/DefaultCloudFoundryClientFactoryV2.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/DefaultCloudFoundryClientFactoryV2.java deleted file mode 100644 index f288f9631..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/DefaultCloudFoundryClientFactoryV2.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.client.v2; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.CloudFoundryClientFactory; - -public class DefaultCloudFoundryClientFactoryV2 extends CloudFoundryClientFactory { - - public static final DefaultCloudFoundryClientFactoryV2 INSTANCE = new DefaultCloudFoundryClientFactoryV2(); - - /** - * Use 'INSTANCE' constant instead. This class is a singleton. - */ - private DefaultCloudFoundryClientFactoryV2() {} - - private CloudFoundryClientCache clientFactory = new CloudFoundryClientCache(); - - @Override - public ClientRequests getClient(CFClientParams params) { - return new DefaultClientRequestsV2(clientFactory, params); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/ReactorUtils.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/ReactorUtils.java deleted file mode 100644 index 1a25e4dd0..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/client/v2/ReactorUtils.java +++ /dev/null @@ -1,289 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 2018 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.cf.client.v2; - -import java.io.IOException; -import java.time.Duration; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.PriorityQueue; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; - -import org.eclipse.core.runtime.OperationCanceledException; -import org.reactivestreams.Publisher; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Schedulers; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -/** - * @author Kris De Volder - */ -public class ReactorUtils { - - private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(45); // reflects default timeout of Mono.block in reactor 2.x. - public static boolean DUMP_STACK_ON_TIMEOUT = false; - - /** - * Convert a {@link CancelationToken} into a Mono that raises - * an {@link OperationCanceledException} when the token is canceled. - */ - public static Mono toMono(CancelationToken cancelToken) { - return Mono.delay(Duration.ofSeconds(1)) - .flatMap((ping) -> - cancelToken.isCanceled() - ? Mono.error(new OperationCanceledException()) - : Mono.empty() - ) - .repeatWhenEmpty((x) -> x); - } - - /** - * Similar to Mono.get but logs a more traceable version of the exception to Eclipse's error - * log before 'rethrowing' it. - *

- * This is useful because the actual exception is pretty hard to trace. It doesn't even 'point' - * to the line where 'get' was called. - */ - public static T get(Mono mono) throws Exception { - try { - return mono.block(DEFAULT_TIMEOUT); - } catch (Exception e) { - dumpStacks(); - throw new IOException(e); - } - } - - /** - * Similar to Mono.get but logs a more traceable version of the exception to Eclipse's error - * log before 'rethrowing' it. - *

- * This is useful because the actual exception is pretty hard to trace. It doesn't even 'point' - * to the line where 'get' was called. - */ - public static T get(Duration timeout, CancelationToken cancelationToken, Mono mono) throws Exception { - try { - return Mono.first(mono, toMono(cancelationToken)) - .onErrorResume(errorFilter(cancelationToken)) - .block(timeout); - } catch (Exception e) { - //dumpStacks(); - throw new IOException(e); - } - } - - - public static List get(Duration t, Mono> m) throws IOException { - try { - return m.block(t); - } catch (Exception e) { - dumpStacks(); - throw new IOException(e); - } - } - - private static void dumpStacks() { - if (DUMP_STACK_ON_TIMEOUT) { - System.out.println(getStackDumps().toString()); - } - } - - /** - * A 'filter' to use as a Mono.otherwise hanlder. It transforms any exception into {@link OperationCanceledException} - * when cancelationToken has been canceled. - */ - private static Function> errorFilter(CancelationToken cancelationToken) { - return (Throwable e) -> cancelationToken.isCanceled()?Mono.error(new OperationCanceledException()):Mono.error(e); - } - - /** - * Deprecated because this is really the same as Mono.justOrEmpty, so use that instead. - */ - @Deprecated - public static Mono just(T it) { - return it == null ? Mono.empty() : Mono.just(it); - } - - /** - * @return A function that can be passed to Mono.otherwise to convert a specific exception type into - * Mono.empty(). - */ - public static Function> suppressException(Class exceptionType) { - return (Throwable caught) -> { - if (exceptionType.isAssignableFrom(caught.getClass())) { - return Mono.empty(); - } else { - return Mono.error(caught); - } - }; - } - - /** - * Build a Mono that executes a given number of Mono one after the - * other. - */ - @SafeVarargs - public static Mono sequence(Mono... tasks) { - Mono seq = Mono.empty(); - for (Mono t : tasks) { - seq = seq.then(t); - } - return seq; - } - - /** - * Execute a bunch of mono in parallel. All monos are executed to completion (rather than canceled early - * when one of them fails) - *

- * When at least one operation has failed then, upon completion or failure of the last Mono we guarantee that at least - * one of the exceptions is propagated. - */ - public static Mono safeMerge(Flux> operations, int concurrency) { - AtomicReference failure = new AtomicReference<>(null); - return Flux.merge( - operations - .map((Mono op) -> { - return op.onErrorResume((e) -> { - failure.compareAndSet(null, e); - return Mono.empty(); - }); - }), - concurrency //limit concurrency otherwise troubles (flooding/choking request broker?) - ) - .then(Mono.defer(() -> { - Throwable error = failure.get(); - if (error!=null) { - return Mono.error(error); - } else { - return Mono.empty(); - } - })); - } - - /** - * Attach a timestamp to each element in a Stream - */ - public static Flux> timestamp(Flux stream) { - return stream.map((e) -> Tuples.of(e, System.currentTimeMillis())); - } - - /** - * Sorts the elements in a flux in a moving time window. I.e. this assumes element order may be - * scrambled but the scrambling has a certain 'time localilty' to it. So we only need to consider - * sorting of elements that arrive 'close to eachother'. - *

- * WARNING: The returned flux is intended for a single subscriber. It only maintains a - * single buffer for sorting stream elements. This buffer is consumed when elements - * are released to any subscriber. Therefore if one subscriber received a element it is gone - * from the buffer and will not be delivered to the other subscribers. - * - * @param stream The stream to be sorted - * @param comparator Compare function to sort with - * @param bufferTime The 'window' of time beyond which we don't need to compare elements. - */ - public static Flux sort(Flux stream, Comparator comparator, Duration bufferTime) { - - class SorterAccumulator { - - final PriorityQueue> holdingPen = new PriorityQueue<>((Tuple2 o1, Tuple2 o2) -> { - return comparator.compare(o1.getT1(), o2.getT1()); - }); - - final Flux released = Flux.fromIterable(() -> new Iterator() { - @Override - public boolean hasNext() { - Tuple2 nxt; - synchronized (holdingPen) { - nxt = holdingPen.peek(); - } - return nxt!=null && isOldEnough(nxt); - } - - private boolean isOldEnough(Tuple2 nxt) { - long age = System.currentTimeMillis() - nxt.getT2(); - return age > bufferTime.toMillis(); - } - - @Override - public T next() { - synchronized (holdingPen) { - return holdingPen.remove().getT1(); - } - } - }); - - public SorterAccumulator next(Flux> window) { - window.subscribe((e) -> { - synchronized (holdingPen) { - holdingPen.add(e); - } - }); - return this; - } - - public Flux getReleased() { - return released; - } - - public Publisher drain() { - return Flux.fromIterable(holdingPen) - .map(Tuple2::getT1); - } - } - - SorterAccumulator sorter = new SorterAccumulator(); - return timestamp(stream) - .window(bufferTime) - .scan(sorter, SorterAccumulator::next) - .concatMap(SorterAccumulator::getReleased) - .concatWith(sorter.drain()); - } - - protected static StringBuffer getStackDumps() { - StringBuffer sb = new StringBuffer(); - Map traces = Thread.getAllStackTraces(); - for (Map.Entry entry : traces.entrySet()) { - sb.append(entry.getKey().toString()); - sb.append("\n"); - for (StackTraceElement element : entry.getValue()) { - sb.append(" "); - sb.append(element.toString()); - sb.append("\n"); - } - sb.append("\n"); - } - return sb; - } - - - /** - * Connect a mono to a CompletableFuture so that the result of the mono - * can be retrieved from the {@link CompletableFuture} by calling it's 'get' - * method. - */ - public static void completeWith(CompletableFuture future, Mono mono) { - mono.doOnNext((T v) -> { - future.complete(v); - }) - .doOnError((Throwable e) -> { - future.completeExceptionally(e); - }) - .subscribeOn(Schedulers.elastic()) - .subscribe(); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/DebugStrategyManager.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/DebugStrategyManager.java deleted file mode 100644 index ac8afb9c4..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/DebugStrategyManager.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.debug; - -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -import org.springsource.ide.eclipse.commons.livexp.ui.Disposable; - -/** - * This class is responsible for managing the debug strategies. It is also responsible for managing the life - * cycle of process listeners abd other {@link Disposable}s that may be associated with a debug strategy and - * should be disposed when the manager itself is disposed. - *

- * - * @author Kris De Volder - */ -public class DebugStrategyManager implements Disposable { - - - private DebugSupport strategy; - private Disposable processTracker; - - public DebugStrategyManager(List list, BootDashViewModel viewModel) { - // At the moment there's only one supported debug strategy, in the future there may be more than one. - // In that case this class may need be generalized to manage a collection of strategies somehow. - Assert.isLegal(list.size()==1); - this.strategy = list.get(0); - this.processTracker = strategy.createProcessTracker(viewModel); - } - - @Override - public void dispose() { - if (this.processTracker!=null) { - this.processTracker.dispose(); - this.processTracker = null; - } - } - - public DebugSupport getStrategy() { - return strategy; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/DebugSupport.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/DebugSupport.java deleted file mode 100644 index 7a0e60ce8..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/DebugSupport.java +++ /dev/null @@ -1,112 +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.cf.debug; - -import java.util.Map; - -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.model.IDebugTarget; -import org.eclipse.debug.core.model.IProcess; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.ops.Operation; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; -import org.springframework.ide.eclipse.boot.util.ProcessListenerAdapter; -import org.springframework.ide.eclipse.boot.util.ProcessTracker; - -/** - * Abstract class that must be implemented to add debug support to a CF application. - * - * @author Kris De Volder - */ -public abstract class DebugSupport { - - /** - * Determine whether debugging can be supported (using the strategy impemented by this DebugSupport instance) - */ - public abstract boolean isSupported(CloudAppDashElement app); - /** - * If isSupported returns false than the support strategy may also return an explanation why the strategy is not - * supported (e.g. PCF version too old, SSH support disabled etc.) - */ - public abstract String getNotSupportedMessage(CloudAppDashElement app); - - /** - * Creates operation that does whatever is needed to get debugger connected to the targetted app. - */ - public abstract Operation createOperation(CloudAppDashElement app, String opName, UserInteractions ui, CancelationToken cancelToken); - - /** - * Called to allow debug support to muck around with environment variables so that it can - * do things like add debugging options to 'JAVA_OPTS'. - */ - public abstract void setupEnvVars(Map environmentVariables); - - /** - * Like setupEnvVars, but called when debugging is disabled. The debug strategy should try to - * undo any changes it made to the env vars to enable debugging. - */ - public abstract void clearEnvVars(Map environmentVariables); - - /** - * Determines whether debugger is currently attached to the targetted app. - */ - public abstract boolean isDebuggerAttached(CloudAppDashElement app); - - /** - * A debug strategy typically involves creating some type of launch that establishes - * a debug connection. To be able to update the debug state in response to changes in - * launches, its necessary to be able to determine what dashboard element corresponds to - * a given launch. Therefore a debug strategy must implement this method. - * - * @return The corresponding CDE for a given launch, or null - */ - public abstract CloudAppDashElement getElementFor(ILaunch l, BootDashViewModel viewModel); - - /** - * Provides a process tracker. Subclasses may override if the default implementation is not suitable. - *

- * The process tracker is responsible to listen for changes in the Eclipse debug ui so it can make - * bootdash elements 'debug' state update when processes and/or debug targets are created or terminated. - */ - public ProcessTracker createProcessTracker(final BootDashViewModel viewModel) { - return new ProcessTracker(new ProcessListenerAdapter() { - @Override - public void debugTargetCreated(ProcessTracker tracker, IDebugTarget target) { - handleStateChange(target.getLaunch(), "debugTargetCreated"); - } - @Override - public void debugTargetTerminated(ProcessTracker tracker, IDebugTarget target) { - handleStateChange(target.getLaunch(), "debugTargetTerminated"); - } - - @Override - public void processTerminated(ProcessTracker tracker, IProcess process) { - //Typically a debug strategy only needs to care about debugtargets, not IProcesses. - // So nothing to do here. - } - @Override - public void processCreated(ProcessTracker tracker, IProcess process) { - //Typically a debug strategy only needs to care about debugtargets, not IProcesses. - // So nothing to do here. - } - private void handleStateChange(ILaunch l, Object info) { - CloudAppDashElement e = getElementFor(l, viewModel); - if (e!=null) { - BootDashModel model = e.getBootDashModel(); - model.notifyElementChanged(e, info); - } - } - }); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SelectRunTargetLaunchTabModel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SelectRunTargetLaunchTabModel.java deleted file mode 100644 index da3459271..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SelectRunTargetLaunchTabModel.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.debug; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springframework.ide.eclipse.boot.launch.LaunchTabSelectionModel; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; - -import com.google.common.collect.ImmutableSet; - -public class SelectRunTargetLaunchTabModel extends LaunchTabSelectionModel { - -// public static SelectProjectLaunchTabModel create() { -// LiveVariable project = new LiveVariable(); -// ExistingBootProjectSelectionValidator validator = new ExistingBootProjectSelectionValidator(project); -// return new SelectProjectLaunchTabModel(project, validator); -// } - - private BootDashViewModel context; - - public SelectRunTargetLaunchTabModel(LiveVariable variable, LiveExpression validator, BootDashViewModel context) { - super(variable, validator); - this.context = context; - } - - @Override - public void initializeFrom(ILaunchConfiguration conf) { - selection.setValue(SshDebugLaunchConfigurationDelegate.getRunTarget(conf, context)); - getDirtyState().setValue(false); - } - - @Override - public void performApply(ILaunchConfigurationWorkingCopy conf) { - SshDebugLaunchConfigurationDelegate.setRunTarget(conf, selection.getValue()); - getDirtyState().setValue(false); - } - - @Override - public void setDefaults(ILaunchConfigurationWorkingCopy conf) { -// if (choices.length>0) { -// SshDebugLaunchConfigurationDelegate.setRunTarget(conf, choices[0]); -// } - } - - public CloudFoundryRunTarget[] getChoices() { - ImmutableSet targets = context.getRunTargets().getValues(); - ArrayList interesting = new ArrayList<>(targets.size()); - for (RunTarget t : targets) { - if (t instanceof CloudFoundryRunTarget) { - interesting.add((CloudFoundryRunTarget) t); - } - } - return interesting.toArray(new CloudFoundryRunTarget[interesting.size()]); - } - -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SelectRunTargetLaunchTabSection.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SelectRunTargetLaunchTabSection.java deleted file mode 100644 index 064a08ac5..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SelectRunTargetLaunchTabSection.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.debug; - -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.util.NameableLabelProvider; -import org.springframework.ide.eclipse.boot.launch.util.DelegatingLaunchConfigurationTabSection; -import org.springframework.ide.eclipse.boot.launch.util.ILaunchConfigurationTabSection; -import org.springsource.ide.eclipse.commons.livexp.ui.ChooseOneSectionCombo; -import org.springsource.ide.eclipse.commons.livexp.ui.IPageWithSections; - -/** - * @author Kris De Volder - */ -public class SelectRunTargetLaunchTabSection { - - public static ILaunchConfigurationTabSection create(IPageWithSections owner, SelectRunTargetLaunchTabModel model) { - ChooseOneSectionCombo ui = - new ChooseOneSectionCombo(owner, "Target", model, model.getChoices()); - ui.setLabelProvider(new NameableLabelProvider()); - return new DelegatingLaunchConfigurationTabSection(owner, model, ui); - } - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugLaunchConfigurationDelegate.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugLaunchConfigurationDelegate.java deleted file mode 100644 index 41f97dc52..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugLaunchConfigurationDelegate.java +++ /dev/null @@ -1,386 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.debug; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchConfigurationType; -import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; -import org.eclipse.debug.core.ILaunchManager; -import org.eclipse.debug.core.model.IDebugTarget; -import org.eclipse.debug.core.model.IProcess; -import org.eclipse.jdt.internal.launching.LaunchingMessages; -import org.eclipse.jdt.internal.launching.LaunchingPlugin; -import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; -import org.eclipse.jdt.launching.IVMConnector; -import org.eclipse.jdt.launching.JavaRuntime; -import org.eclipse.osgi.util.NLS; -import org.springframework.ide.eclipse.boot.core.BootActivator; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.client.SshClientSupport; -import org.springframework.ide.eclipse.boot.dash.cf.client.SshHost; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springframework.ide.eclipse.boot.launch.AbstractBootLaunchConfigurationDelegate; -import org.springframework.ide.eclipse.boot.launch.BootLaunchConfigurationDelegate; -import org.springframework.ide.eclipse.boot.launch.util.WaitFor; -import org.springframework.ide.eclipse.boot.util.ProcessListenerAdapter; -import org.springframework.ide.eclipse.boot.util.ProcessTracker; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -@SuppressWarnings("restriction") -public class SshDebugLaunchConfigurationDelegate extends AbstractBootLaunchConfigurationDelegate { - - public static final String TYPE_ID = "org.springframework.ide.eclipse.boot.dash.ssh.tunnel.launch"; - - private static final long DEBUG_CONNECT_TIMEOUT = 20000; - public static final String RUN_TARGET = "ssh.debug.runtarget.id"; - public static final String APP_NAME = "ssh.debug.app.name"; - public static final String INSTANCE_IDX = "ssh.debug.app.instance"; - - private static BootDashViewModel getContext() { - //TODO: it may be necessary to allow injecting this, for example via setting a threadlocal, - // to make code more amenable to unit testing. - //This method is here because LaunchConf delegates are created by eclipse debug framework and - // so we can't easily inject a context object into it. - //The only method that should be calling this is 'launch'. Everything else should be doing - // the proper thing and pass in the model as parameter somehow. - return BootDashActivator.getDefault().getModel(); - } - - @Override - public void launch(ILaunchConfiguration conf, String mode, ILaunch launch, IProgressMonitor mon) - throws CoreException { - conf = configureClassPathProviders(conf); - Assert.isTrue(ILaunchManager.DEBUG_MODE.equals(mode)); - BootDashViewModel context = getContext(); - mon.beginTask("Establish SSH Debug Connection to "+getAppName(conf)+" on "+getRunTarget(conf, context), 4); - CloudAppDashElement app = null; - try { - CloudFoundryRunTarget target = getRunTarget(conf, context); - SshDebugSupport debugSupport = getDebugSupport(conf, context); - - app = getApp(conf, context); - - if (app!=null && target!=null && debugSupport.isSupported(app)) { - //1: determine SSH tunnel parameters - app.log("Fetching SSH tunnel parameters..."); - SshClientSupport sshInfo = target.getSshClientSupport(); - SshHost sshHost = sshInfo.getSshHost(); - String sshUser = sshInfo.getSshUser(app.getAppGuid(), getInstanceIndex(conf)); - String sshCode = sshInfo.getSshCode(); - int remotePort = debugSupport.getRemotePort(); - - app.log("SSH tunnel parameters:"); - app.log(" host: "+sshHost); - app.log(" user: "+sshUser); - app.log(" code: "+sshCode); - app.log(" remote port: "+remotePort); - mon.worked(1); - - //2: create tunnel - app.log("Creating tunnel..."); - SshTunnel tunnel = new SshTunnelImpl(sshHost, sshUser, sshCode, remotePort, app); //TODO: use SshTunnelFactory? - - //3: connect debugger stuff - app.log("Launching remote debug connector..."); - launchRemote(tunnel, conf, launch, new SubProgressMonitor(mon, 1)); - app.log("Launching remote debug connector... DONE"); - } - } catch (Exception e) { - if (app!=null) { - app.log("ERROR: "+ExceptionUtil.getMessage(e)); - } - throw ExceptionUtil.coreException(e); - } finally { - mon.done(); - } - } - - public static int getInstanceIndex(ILaunchConfiguration conf) { - try { - return conf.getAttribute(INSTANCE_IDX, 0); - } catch (Exception e) { - BootDashActivator.log(e); - } - return 0; - } - - private SshDebugSupport getDebugSupport(ILaunchConfiguration conf, BootDashViewModel context) { - CloudAppDashElement app = getApp(conf, context); - if (app!=null) { - DebugSupport ds = app.getDebugSupport(); - if (ds instanceof DebugSupport) { - return (SshDebugSupport) ds; - } - } - return null; - } - - - public static String getAppName(ILaunchConfiguration conf) { - return getString(conf, APP_NAME); - } - - public static CloudAppDashElement getApp(ILaunchConfiguration conf, BootDashViewModel context) { - String appName = getAppName(conf); - if (appName!=null) { - BootDashModel section = context.getSectionByTargetId(getRunTargetId(conf)); - if (section instanceof CloudFoundryBootDashModel) { - CloudFoundryBootDashModel cfmodel = (CloudFoundryBootDashModel) section; - return cfmodel.getApplication(appName); - } - } - return null; - } - - public static void setAppName(ILaunchConfigurationWorkingCopy conf, String name) { - if (name!=null) { - conf.setAttribute(APP_NAME, name); - } else { - conf.removeAttribute(APP_NAME); - } - } - - public static void setRunTarget(ILaunchConfigurationWorkingCopy conf, CloudFoundryRunTarget target) { - if (target!=null) { - conf.setAttribute(RUN_TARGET, target.getId()); - } else { - conf.removeAttribute(RUN_TARGET); - } - } - - private static String getRunTargetId(ILaunchConfiguration conf) { - String at = RUN_TARGET; - return getString(conf, at); - } - - - protected static String getString(ILaunchConfiguration conf, String attName) { - try { - return conf.getAttribute(attName, (String)null); - } catch (CoreException e) { - BootDashActivator.log(e); - } - return null; - } - - public static CloudFoundryRunTarget getRunTarget(ILaunchConfiguration conf, BootDashViewModel context) { - try { - String id = conf.getAttribute(RUN_TARGET, (String)null); - if (id!=null) { - RunTarget target = context.getRunTargetById(id); - if (target instanceof CloudFoundryRunTarget) { - return (CloudFoundryRunTarget) target; - } - } - } catch (Exception e) { - BootDashActivator.log(e); - } - return null; - } - - /** - * Create debugging target similar to a remote debugging session would and add them to the launch. - * This is to support debugging of the remote boot-app that is reachable over http tunnel - * the client creates. From our side this just as if we are opening a remote debug - * session to the client. - */ - private void launchRemote(final SshTunnel tunnel, ILaunchConfiguration configuration, final ILaunch launch, IProgressMonitor _monitor) throws CoreException { - int port = tunnel.getLocalPort(); - final IProgressMonitor monitor = _monitor==null?new NullProgressMonitor():_monitor; - - monitor.beginTask(NLS.bind(LaunchingMessages.JavaRemoteApplicationLaunchConfigurationDelegate_Attaching_to__0_____1, new String[]{configuration.getName()}), 3); - // check for cancellation - if (monitor.isCanceled()) { - return; - } - try { - monitor.subTask(LaunchingMessages.JavaRemoteApplicationLaunchConfigurationDelegate_Verifying_launch_attributes____1); - - //String connectorId = "org.eclipse.jdt.launching.socketListenConnector";//getVMConnectorId(configuration); - String connectorId = "org.eclipse.jdt.launching.socketAttachConnector"; - final IVMConnector connector = JavaRuntime.getVMConnector(connectorId); - if (connector == null) { - abort(LaunchingMessages.JavaRemoteApplicationLaunchConfigurationDelegate_Connector_not_specified_2, null, IJavaLaunchConfigurationConstants.ERR_CONNECTOR_NOT_AVAILABLE); - } - - final Map argMap = new HashMap<>(); - - int connectTimeout = Platform.getPreferencesService().getInt( - LaunchingPlugin.ID_PLUGIN, - JavaRuntime.PREF_CONNECT_TIMEOUT, - JavaRuntime.DEF_CONNECT_TIMEOUT, - null); - argMap.put("hostname", "localhost"); - argMap.put("timeout", ""+connectTimeout); - argMap.put("port", ""+port); - - // check for cancellation - if (monitor.isCanceled()) { - return; - } - - monitor.worked(1); - - - monitor.subTask(LaunchingMessages.JavaRemoteApplicationLaunchConfigurationDelegate_Creating_source_locator____2); - // set the default source locator if required - setDefaultSourceLocator(launch, configuration); - monitor.worked(1); - - // connect to remote VM - try { - new WaitFor(DEBUG_CONNECT_TIMEOUT) { - @Override - public void run() throws Exception { - connector.connect(argMap, monitor, launch); - } - }; - new ProcessTracker(new ProcessListenerAdapter() { - @Override - public void debugTargetTerminated(ProcessTracker tracker, IDebugTarget target) { - handleTermination(tracker, target.getLaunch()); - } - @Override - public void processTerminated(ProcessTracker tracker, IProcess process) { - handleTermination(tracker, process.getLaunch()); - } - private void handleTermination(ProcessTracker tracker, ILaunch targetLaunch) { - if (launch.equals(targetLaunch)) { - tracker.dispose(); - tunnel.dispose(); - } - } - }); - } catch (Exception e) { - terminateAllTargets(launch); - throw ExceptionUtil.coreException(e); - } - - // check for cancellation - if (monitor.isCanceled()) { - terminateAllTargets(launch); - return; - } - } - finally { - monitor.done(); - } - } - - public void terminateAllTargets(final ILaunch launch) { - //Note: its better to discconect debugtargets before terminating processes - // because that allows a cleaner disconnect from the debugged process. - // (If the devtools client process is terminated its no longer possible to talk to the - // debugged process). - IDebugTarget[] debugTargets = launch.getDebugTargets(); - for (int i = 0; i < debugTargets.length; i++) { - IDebugTarget target = debugTargets[i]; - if (target.canDisconnect()) { - try { - target.disconnect(); - } catch (Exception e) { - BootActivator.log(e); - } - } - } - IProcess[] processes = launch.getProcesses(); - for (IProcess process : processes) { - if (process.canTerminate()) { - try { - process.terminate(); - } catch (Exception e) { - BootActivator.log(e); - } - } - } - } - - - public static ILaunchConfiguration getOrCreateLaunchConfig(CloudAppDashElement app) throws CoreException { - IProject project = app.getProject(); - String appName = app.getName(); - CloudFoundryRunTarget target = app.getTarget(); - Assert.isTrue(project!=null); - ILaunchConfiguration existing = findConfig(project, target, appName); - ILaunchConfigurationWorkingCopy wc; - if (existing!=null) { - return existing; - } else { - wc = createConfiguration(project, target, appName); - return wc.doSave(); - } - } - - private static ILaunchConfigurationWorkingCopy createConfiguration(IProject project, CloudFoundryRunTarget target, String appName) throws CoreException { - ILaunchConfigurationType configType = getLaunchType(); - ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, getLaunchMan().generateLaunchConfigurationName("ssh-tunnel["+appName+"]")); - BootLaunchConfigurationDelegate.setProject(wc, project); - setRunTarget(wc, target); - setAppName(wc, appName); - wc.setMappedResources(new IResource[] {project}); - return wc; - } - - public static ILaunchConfiguration findConfig(CloudAppDashElement app) { - IProject project = app.getProject(); - String appName = app.getName(); - CloudFoundryRunTarget target = app.getTarget(); - return findConfig(project, target, appName); - } - - private static ILaunchConfiguration findConfig(IProject project, CloudFoundryRunTarget target, String appName) { - try { - if (project!=null) { - for (ILaunchConfiguration c : getLaunchMan().getLaunchConfigurations(getLaunchType())) { - if ( - project.equals(BootLaunchConfigurationDelegate.getProject(c)) && - target.getId().equals(getRunTargetId(c)) && - appName.equals(getAppName(c)) - ) { - return c; - } - } - } - } catch (CoreException e) { - BootActivator.log(e); - } - return null; - } - - public static ILaunchConfigurationType getLaunchType() { - return getLaunchMan().getLaunchConfigurationType(TYPE_ID); - } - - - public static void doLaunch(CloudAppDashElement app, IProgressMonitor monitor) throws CoreException { - ILaunchConfiguration conf = SshDebugLaunchConfigurationDelegate.getOrCreateLaunchConfig(app); - conf.launch(ILaunchManager.DEBUG_MODE, monitor); - } - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugLaunchConfigurationTabGroup.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugLaunchConfigurationTabGroup.java deleted file mode 100644 index b81ea213f..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugLaunchConfigurationTabGroup.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.debug; - -import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; -import org.eclipse.debug.ui.CommonTab; -import org.eclipse.debug.ui.ILaunchConfigurationDialog; -import org.eclipse.debug.ui.ILaunchConfigurationTab; -import org.eclipse.debug.ui.ILaunchConfigurationTabGroup; -import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; - -public class SshDebugLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup { - - /** - * @see ILaunchConfigurationTabGroup#createTabs(ILaunchConfigurationDialog, String) - */ - @Override - public void createTabs(ILaunchConfigurationDialog dialog, String mode) { - ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { - new SshDebugMainTab(), - //new JavaArgumentsTab(), - //new JavaJRETab(), - //new JavaClasspathTab(), - new SourceLookupTab(), - //new EnvironmentTab(), - new CommonTab() - }; - setTabs(tabs); - } - -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugLaunchUIModel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugLaunchUIModel.java deleted file mode 100644 index 3b297306f..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugLaunchUIModel.java +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.debug; - -import org.eclipse.core.resources.IProject; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -import org.springframework.ide.eclipse.boot.launch.ExistingBootProjectSelectionValidator; -import org.springframework.ide.eclipse.boot.launch.SelectProjectLaunchTabModel; -import org.springframework.ide.eclipse.boot.launch.devtools.DevtoolsEnabledValidator; -import org.springframework.ide.eclipse.boot.launch.devtools.StringFieldLaunchTabModel; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; -import org.springsource.ide.eclipse.commons.livexp.core.CompositeValidator; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.core.StringFieldModel; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; -import org.springsource.ide.eclipse.commons.livexp.core.Validator; - -/** - * Model for the 'main type' selection widgetry on a launchconfiguration tab. - *

- * Contains the 'logic' for the UI except for the widgets themselves. - * Can be unit tested without having to instantiate launch configuration dialogs - * etc. - * - * @author Kris De Volder - */ -public class SshDebugLaunchUIModel { - - public final SelectProjectLaunchTabModel project; - public final SelectRunTargetLaunchTabModel cfTarget; - public final StringFieldLaunchTabModel appName; - private BootDashViewModel context; - - public SshDebugLaunchUIModel(BootDashViewModel context) { - this.context = context; - project = createProjectSelectionModel(); - cfTarget = createCfTargetModel(context); - appName = createAppNameModel(); - } - - private SelectRunTargetLaunchTabModel createCfTargetModel(BootDashViewModel context) { - LiveVariable variable = new LiveVariable<>(); - LiveExpression validator = Validator.notNull(variable, "No Target selected"); - return new SelectRunTargetLaunchTabModel(variable, validator, context); - } - - private StringFieldLaunchTabModel createAppNameModel() { - StringFieldModel field = new StringFieldModel("App Name", ""); - field.validator(appNameValidator(project.selection, cfTarget.selection, field.getVariable())); - return new StringFieldLaunchTabModel(field, SshDebugLaunchConfigurationDelegate.APP_NAME); - } - - - private LiveExpression appNameValidator( - final LiveExpression projectSelection, - final LiveExpression targetSelection, - final LiveExpression appNameSelection - ) { - return new Validator() { - { - dependsOn(projectSelection); - dependsOn(appNameSelection); - dependsOn(targetSelection); - } - protected ValidationResult compute() { - CloudFoundryRunTarget target = targetSelection.getValue(); - if (target!=null) { - String name = appNameSelection.getValue(); - if (!StringUtil.hasText(name)) { - return ValidationResult.error("App Name not set"); - } - BootDashModel section = context.getSectionByTargetId(target.getId()); - if (section instanceof CloudFoundryBootDashModel) { - CloudFoundryBootDashModel cfSection = (CloudFoundryBootDashModel) section; - CloudAppDashElement app = cfSection.getApplication(name); - if (app==null) { - return ValidationResult.error("There is no app '"+name+"' in '"+target+"'"); - } - IProject project = projectSelection.getValue(); - IProject appProject = app.getProject(); - if (appProject==null) { - // we don't know what project goes with selected app so give the user - // the benefit of the doubdt - // => no error! - } else if (project==null) { - // not this validator's problem. (project validator should check this) - // => no error - } else { - if (!project.equals(appProject)) { - return ValidationResult.error("The app '"+name+"' is bound to a different project ("+appProject.getName()+")"); - } - } - } - } - return ValidationResult.OK; - } - }; - } - - private SelectProjectLaunchTabModel createProjectSelectionModel() { - LiveVariable project = new LiveVariable<>(); - CompositeValidator validator = new CompositeValidator(); - validator.addChild(new ExistingBootProjectSelectionValidator(project)); - validator.addChild(new DevtoolsEnabledValidator(project)); - return new SelectProjectLaunchTabModel(project, validator); - } - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugMainTab.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugMainTab.java deleted file mode 100644 index 75e6329de..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugMainTab.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.debug; - -import static org.springframework.ide.eclipse.boot.ui.BootUIImages.BOOT_DEVTOOLS_ICON; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.swt.graphics.Image; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.launch.SelectProjectLaunchTabSection; -import org.springframework.ide.eclipse.boot.launch.devtools.StringFieldLaunchTabSection; -import org.springframework.ide.eclipse.boot.launch.util.LaunchConfigurationTabWithSections; -import org.springframework.ide.eclipse.boot.ui.BootUIImages; -import org.springsource.ide.eclipse.commons.livexp.ui.IPageSection; -import org.springsource.ide.eclipse.commons.livexp.ui.IPageWithSections; - -/** - * @author Kris De Volder - */ -public class SshDebugMainTab extends LaunchConfigurationTabWithSections implements IPageWithSections { - - @Override - public String getName() { - return "SSH Tunnel"; - } - - @Override - public Image getImage() { - return BootUIImages.getImage(BOOT_DEVTOOLS_ICON); - } - - @Override - protected List createSections() { - SshDebugLaunchUIModel model = new SshDebugLaunchUIModel(BootDashActivator.getDefault().getModel()); - return Arrays.asList(new IPageSection[] { - SelectProjectLaunchTabSection.create(this, model.project), - SelectRunTargetLaunchTabSection.create(this, model.cfTarget), - StringFieldLaunchTabSection.create(this, model.appName) - }); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugStartOperation.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugStartOperation.java deleted file mode 100644 index 931efdfc6..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugStartOperation.java +++ /dev/null @@ -1,36 +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.cf.debug; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.ops.CloudApplicationOperation; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; - -/** - * @author Kris De Volder - */ -public class SshDebugStartOperation extends CloudApplicationOperation { - - private CloudAppDashElement app; - - public SshDebugStartOperation(CloudAppDashElement app, DebugSupport debugSupport, CancelationToken cancelationToken) { - super("Starting SSH debugging for app '"+app.getName()+"'", app.getBootDashModel(), app.getName(), cancelationToken); - this.app = app; - } - - @Override - protected void doCloudOp(IProgressMonitor monitor) throws Exception, OperationCanceledException { - //TODO: wireup a progress monitor to pass to 'doLaunch' so its aware of cancelation token - SshDebugLaunchConfigurationDelegate.doLaunch(app, monitor); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugSupport.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugSupport.java deleted file mode 100644 index 2658bf38d..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshDebugSupport.java +++ /dev/null @@ -1,154 +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.cf.debug; - -import static org.springframework.ide.eclipse.boot.dash.cf.debug.SshDebugLaunchConfigurationDelegate.getApp; -import static org.springframework.ide.eclipse.boot.dash.cf.debug.SshDebugLaunchConfigurationDelegate.getLaunchType; - -import java.util.Map; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchConfigurationType; -import org.eclipse.debug.core.model.IDebugTarget; -import org.springframework.ide.eclipse.boot.core.BootActivator; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.ops.Operation; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; -import org.springframework.ide.eclipse.boot.launch.util.BootLaunchUtils; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -/** - * Uses ssh tunnelling on Diego to support debugging of app running on CF. - * - * @author Kris De Volder - */ -public class SshDebugSupport extends DebugSupport { - - public static final SshDebugSupport INSTANCE = new SshDebugSupport(); - - private static final int REMOTE_DEBUG_PORT = 47822; - private static final String REMOTE_DEBUG_JVM_ARGS = "-Xdebug -Xrunjdwp:server=y,transport=dt_socket,suspend=n,address="+REMOTE_DEBUG_PORT; - private static final String JAVA_OPTS = "JAVA_OPTS"; - - private SshDebugSupport() {} - - @Override - public boolean isSupported(CloudAppDashElement app) { - String notSupportedMessage = getNotSupportedMessage(app); - return notSupportedMessage==null; - } - - @Override - public String getNotSupportedMessage(CloudAppDashElement app) { - //TODO: There are a number of different ways that ssh and/or diego might be disabled for - // an app. e.g. it can be disabled on the app itself, on the space, on the org or - // on the whole CF installation. This check should recognize these situation. - // At the moment it pretty much returns true if the CF has global info about the 'ssh-host', - // but this probably usually the case on any recent enough version of PCF, even if - // ssh has been explicitly disabled. - CloudFoundryRunTarget target = app.getTarget(); - try { - if (target.getSshClientSupport().getSshHost()==null) { - return "Cloud controller doesn't specify an ssh-host. This probably means your version of CloudFoundry doesn't support SSH."; - } - return null; - } catch (Exception e) { - BootDashActivator.log(e); //for traceability - String msg = ExceptionUtil.getMessage(e); - if (!StringUtil.hasText(msg)) { - msg = "Exception: "+e.getClass().getName(); - } - return msg; - } - } - - @Override - public boolean isDebuggerAttached(CloudAppDashElement app) { - ILaunchConfiguration conf = SshDebugLaunchConfigurationDelegate.findConfig(app); - if (conf!=null) { - for (ILaunch l : BootLaunchUtils.getLaunches(conf)) { - if (!l.isTerminated()) { - for (IDebugTarget dt : l.getDebugTargets()) { - if (!dt.isTerminated()) { - //Active debug target found, so debugger is attached. - return true; - } - } - return true; - } - } - } - return false; - } - - @Override - public Operation createOperation(CloudAppDashElement app, String opName, UserInteractions ui, CancelationToken cancelationToken) { - return new SshDebugStartOperation(app, this, cancelationToken); - } - - @Override - public void setupEnvVars(Map env) { - String javaOpts = clearJavaOpts(env.get(JAVA_OPTS)); - StringBuilder sb = new StringBuilder(javaOpts); - if (sb.length() > 0) { - sb.append(' '); - } - sb.append(REMOTE_DEBUG_JVM_ARGS); - env.put(JAVA_OPTS, sb.toString()); - - } - - private static String clearJavaOpts(String opts) { - if (opts!=null) { - opts = opts.replaceAll(REMOTE_DEBUG_JVM_ARGS + "\\s*", ""); - return opts; - } else { - return ""; - } - } - - - @Override - public void clearEnvVars(Map env) { - String jopts = clearJavaOpts(env.get(JAVA_OPTS)); - if (StringUtil.hasText(jopts)) { - env.put(JAVA_OPTS, clearJavaOpts(env.get(JAVA_OPTS))); - } else { - env.remove(JAVA_OPTS); - } - } - - public int getRemotePort() { - return REMOTE_DEBUG_PORT; - } - - @Override - public CloudAppDashElement getElementFor(ILaunch l, BootDashViewModel context) { - try { - ILaunchConfigurationType interestingType = getLaunchType(); - ILaunchConfiguration conf = l.getLaunchConfiguration(); - if (interestingType.equals(conf.getType())) { - return getApp(conf, context); - } - } catch (CoreException e) { - BootActivator.log(e); - } - return null; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshTunnel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshTunnel.java deleted file mode 100644 index dc02b4be7..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshTunnel.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.springframework.ide.eclipse.boot.dash.cf.debug; - -import org.springsource.ide.eclipse.commons.livexp.core.OnDispose; -import org.springsource.ide.eclipse.commons.livexp.ui.Disposable; - -public interface SshTunnel extends Disposable, OnDispose { - - int getLocalPort(); - - boolean isDisposed(); - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshTunnelFactory.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshTunnelFactory.java deleted file mode 100644 index 42b1ed206..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshTunnelFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 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.cf.debug; - -import org.springframework.ide.eclipse.boot.dash.cf.client.SshHost; -import org.springframework.ide.eclipse.boot.dash.util.LogSink; - -@FunctionalInterface -public interface SshTunnelFactory { - - SshTunnel create( - SshHost sshHost, - String user, - String oneTimeCode, - int remotePort, - LogSink log, - int localPort - ) throws Exception; - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshTunnelImpl.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshTunnelImpl.java deleted file mode 100644 index a346a6d99..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/debug/SshTunnelImpl.java +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.debug; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.SocketTimeoutException; - -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.dash.cf.client.SshHost; -import org.springframework.ide.eclipse.boot.dash.util.LogSink; -import org.springsource.ide.eclipse.commons.livexp.core.AbstractDisposable; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -import net.schmizz.keepalive.KeepAliveProvider; -import net.schmizz.keepalive.KeepAliveRunner; -import net.schmizz.sshj.DefaultConfig; -import net.schmizz.sshj.SSHClient; -import net.schmizz.sshj.connection.channel.direct.LocalPortForwarder; - -/** - * This class is responsible for creating an ssh tunnel to a remote port. This class implements - * Closeable, its close method must be called to close the tunnel and avoid resource leak. - */ -public class SshTunnelImpl extends AbstractDisposable implements SshTunnel { - - private boolean closeRequested = false; - private int localPort; - private SSHClient ssh; - private LocalPortForwarder portForwarder; - - public SshTunnelImpl(SshHost sshHost, String user, String oneTimeCode, int remotePort, LogSink log) throws Exception { - this(sshHost, user, oneTimeCode, remotePort, log, 0); - } - - public SshTunnelImpl(SshHost sshHost, String user, String oneTimeCode, int remotePort, LogSink log, int _localPort) throws Exception { - DefaultConfig config = new DefaultConfig(); - config.setKeepAliveProvider(KeepAliveProvider.KEEP_ALIVE); // Hopefuly this is better at detecting dropped connections from server (e.g. when app is stopped or dies). - ssh = new SSHClient(config); - ssh.addHostKeyVerifier(sshHost.getFingerPrint()); - log.log("Ssh client created"); - - ssh.connect(sshHost.getHost(), sshHost.getPort()); - ssh.authPassword(user, oneTimeCode); - KeepAliveRunner keepAlive = (KeepAliveRunner) ssh.getConnection().getKeepAlive(); - keepAlive.setKeepAliveInterval(5); - keepAlive.setMaxAliveCount(1); - log.log("Ssh client connected"); - - ServerSocket ss = new ServerSocket(_localPort); - ss.setSoTimeout(5_000); - localPort = ss.getLocalPort(); - Job job = new Job("SshTunnel port forwarding") { - - @Override - protected IStatus run(IProgressMonitor arg0) { - final LocalPortForwarder.Parameters params = new LocalPortForwarder.Parameters("0.0.0.0", localPort, "localhost", remotePort); - try { - portForwarder = ssh.newLocalPortForwarder(params, ss); - boolean retry; - do { - retry = false; - try { - portForwarder.listen(); - } catch (IOException e) { - if (!closeRequested) { - if (e instanceof SocketTimeoutException) { - //don't log it happens all the time and is expected - } else { - log.log(ExceptionUtil.getMessage(e)); - } - retry = true; - } - } - } while (retry); - } finally { - try { - ss.close(); - } catch (IOException e) { - } - } - return Status.OK_STATUS; - } - }; - job.setSystem(true); - job.schedule(); - log.log("Ssh tunnel created: localPort = "+localPort); - } - - @Override - synchronized public void dispose() { - if (portForwarder!=null) { - try { - portForwarder.close(); - } catch (Exception e) { - } - portForwarder = null; - } - if (ssh!=null) { - try { - ssh.disconnect(); - } catch (Exception e) { - } - ssh = null; - } - super.dispose(); - } - - public int getLocalPort() { - return localPort; - } - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameAnnotation.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameAnnotation.java deleted file mode 100644 index ce99337aa..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameAnnotation.java +++ /dev/null @@ -1,139 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.deployment; - -import org.eclipse.jface.text.source.Annotation; -import org.eclipse.jface.text.source.IAnnotationPresentation; -import org.eclipse.jface.text.source.ImageUtilities; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Canvas; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; - -/** - * Annotation for application name. Can be selected and unselected. Based on JDT - * projection annotation - * - * @author Alex Boyko - * - */ -public class AppNameAnnotation extends Annotation implements IAnnotationPresentation { - /** - * The type of CF application name annotations. - */ - public static final String TYPE = "cf.app.name"; //$NON-NLS-1$ - - private static final int COLOR= SWT.COLOR_GRAY; - - /** The state of this annotation */ - private boolean fIsSelected= false; - /** Indicates whether this annotation should be painted as range */ - private boolean fIsRangeIndication= false; - - /** - * Creates a new annotation. When isSelected - * is true the annotation is initially selected. - * - * @param isSelected true if the annotation should initially be selected, false otherwise - */ - public AppNameAnnotation(String text) { - super(TYPE, false, text); - } - - /** - * Creates a new annotation. - * - * @param text the app name - * @param selected selected or unselected - */ - public AppNameAnnotation(String text, boolean selected) { - this(text); - fIsSelected = selected; - } - - /** - * Enables and disables the range indication for this annotation. - * - * @param rangeIndication the enable state for the range indication - */ - public void setRangeIndication(boolean rangeIndication) { - fIsRangeIndication= rangeIndication; - } - - private void drawRangeIndication(GC gc, Canvas canvas, Rectangle r) { - final int MARGIN= 3; - - /* cap the height - at least on GTK, large numbers are converted to - * negatives at some point */ - int height= Math.min(r.y + r.height - MARGIN, canvas.getSize().y); - - gc.setForeground(canvas.getDisplay().getSystemColor(COLOR)); - gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance - gc.drawLine(r.x + 4, r.y + 12, r.x + 4, height); - gc.drawLine(r.x + 4, height, r.x + r.width - MARGIN, height); - } - - /* - * @see org.eclipse.jface.text.source.IAnnotationPresentation#paint(org.eclipse.swt.graphics.GC, org.eclipse.swt.widgets.Canvas, org.eclipse.swt.graphics.Rectangle) - */ - public void paint(GC gc, Canvas canvas, Rectangle rectangle) { - Image image= getImage(); - if (image != null) { - ImageUtilities.drawImage(image, gc, canvas, rectangle, SWT.CENTER, SWT.TOP); - if (fIsRangeIndication) { - FontMetrics fontMetrics= gc.getFontMetrics(); - int delta= (fontMetrics.getHeight() - image.getBounds().height)/2; - rectangle.y += delta; - rectangle.height -= delta; - drawRangeIndication(gc, canvas, rectangle); - } - } - } - - /* - * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer() - */ - public int getLayer() { - return IAnnotationPresentation.DEFAULT_LAYER; - } - - private Image getImage() { - return isSelected() ? BootDashActivator.getDefault().getImageRegistry().get(BootDashActivator.CHECK_ICON) - : BootDashActivator.getDefault().getImageRegistry().get(BootDashActivator.CHECK_GREYSCALE_ICON); - } - - /** - * Returns the state of this annotation. - * - * @return true if collapsed - */ - public boolean isSelected() { - return fIsSelected; - } - - /** - * Marks this annotation as being selected. - */ - public void markSelected() { - fIsSelected= true; - } - - /** - * Marks this annotation as being unselected. - */ - public void markUnselected() { - fIsSelected= false; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameAnnotationModel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameAnnotationModel.java deleted file mode 100644 index 5b04ff392..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameAnnotationModel.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 2019 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.cf.deployment; - -import java.util.Iterator; - -import org.eclipse.jface.text.source.Annotation; -import org.eclipse.jface.text.source.AnnotationModel; - -/** - * Application Name annotations model - * - * @author Alex Boyko - * - */ -public class AppNameAnnotationModel extends AnnotationModel { - - /** - * Annotation model key for attachment to viewer visual annotations model - */ - public static final Object APP_NAME_MODEL_KEY = new Object(); - - /** - * Constant application name. If not null then corresponding annotation must be selected - */ - public final String fixedAppName; - - /** - * Creates a new, empty projection annotation model. - */ - public AppNameAnnotationModel(String fixedAppName) { - this.fixedAppName = fixedAppName; - } - - /** - * Marks the given annotation as selected. An appropriate - * annotation model change event is sent out. - * - * @param annotation the annotation - */ - public void markSelected(Annotation annotation) { - if (annotation instanceof AppNameAnnotation) { - AppNameAnnotation appName = (AppNameAnnotation) annotation; - Iterator iterator= getAnnotationIterator(); - while(iterator.hasNext()) { - Object o = iterator.next(); - if (o instanceof AppNameAnnotation && appName != o) { - AppNameAnnotation a = (AppNameAnnotation) o; - if (a.isSelected()) { - a.markUnselected(); - modifyAnnotation(a, true); - } - } - } - if (!appName.isSelected()) { - appName.markSelected(); - modifyAnnotation(appName, true); - } - } - } - - /** - * Finds the first selected annotation - * - * @return the selected annotation - */ - public AppNameAnnotation getSelectedAppAnnotation() { - Iterator iterator= getAnnotationIterator(); - while(iterator.hasNext()) { - Object o = iterator.next(); - if (o instanceof AppNameAnnotation) { - AppNameAnnotation a = (AppNameAnnotation) o; - if (a.isSelected()) { - return a; - } - } - } - return null; - } - - /** - * Finds application name annotation corresponding to the passed in - * application name text parameter - * - * @param text Application name text - * @return annotation corresponding to the application name text - */ - public AppNameAnnotation getAnnotation(String text) { - if (text != null) { - Iterator iterator= getAnnotationIterator(); - while(iterator.hasNext()) { - Object o = iterator.next(); - if (o instanceof AppNameAnnotation) { - AppNameAnnotation a = (AppNameAnnotation) o; - if (text.equals(a.getText())) { - return a; - } - } - } - } - return null; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameAnnotationSupport.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameAnnotationSupport.java deleted file mode 100644 index 48ffc32a3..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameAnnotationSupport.java +++ /dev/null @@ -1,260 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 2019 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.cf.deployment; - -import java.util.Iterator; - -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.ITextInputListener; -import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.source.Annotation; -import org.eclipse.jface.text.source.AnnotationPainter; -import org.eclipse.jface.text.source.IAnnotationAccess; -import org.eclipse.jface.text.source.IAnnotationHover; -import org.eclipse.jface.text.source.IAnnotationModel; -import org.eclipse.jface.text.source.IAnnotationModelExtension; -import org.eclipse.jface.text.source.ISharedTextColors; -import org.eclipse.jface.text.source.ISourceViewer; -import org.eclipse.jface.text.source.ISourceViewerExtension2; -import org.eclipse.jface.text.source.SourceViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.custom.StyledTextContent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.RGB; -import org.springsource.ide.eclipse.commons.livexp.util.Log; - -/** - * Application name annotation support for the {@link ISourceViewer} - * - * @author Alex Boyko - * - */ -public class AppNameAnnotationSupport { - - /** - * Unselected application name annotation line color - */ - private static final RGB APP_NAME_COLOR = new RGB(0xBB, 0xBB, 0xBB); - - /** - * Selected application name annotation line color - */ - private static final RGB SELECTED_APP_NAME_COLOR = new RGB(0x00, 0x87, 0x00); - - /** - * Alpha value for painting application name annotations line highlighting - * (Must be close to 0 to ensure the text behind is visible enough) - */ - private static final int APP_NAME_ANNOTATION_ALPHA = 0x17; - - /** - * Width of the application name annotations vertical ruler control - */ - private static final int ANNOTATION_COLUMN_WIDTH = 12; - - /** - * The source viewer - */ - private SourceViewer fViewer = null; - - /** - * Application name annotations vertical ruler - */ - private AppNameRulerColumn fColumn = null; - - /** - * Constant colors cache (passed in) - */ - private ISharedTextColors fColorsCache; - - private final String fixedAppName; - - /** - * Listen to viewer input changes to attach the application name annotations model if necessary - */ - private ITextInputListener textInputListener = new ITextInputListener() { - - public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { - } - - @Override - public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { - initAppAnnotationModel(); - } - - }; - - private void initAppAnnotationModel() { - IAnnotationModel annotationModel = fViewer.getVisualAnnotationModel(); - if (annotationModel instanceof IAnnotationModelExtension) { - IAnnotationModelExtension extension = (IAnnotationModelExtension) annotationModel; - if (extension.getAnnotationModel(AppNameAnnotationModel.APP_NAME_MODEL_KEY) == null) { - extension.addAnnotationModel(AppNameAnnotationModel.APP_NAME_MODEL_KEY, new AppNameAnnotationModel(fixedAppName)); - } - } - fColumn.setModel(annotationModel); - } - - public AppNameAnnotationSupport(SourceViewer viewer, IAnnotationAccess annotationAccess, ISharedTextColors colorsCache, String fixedAppName) { - super(); - this.fixedAppName = fixedAppName; - fViewer = viewer; - fViewer.addTextInputListener(textInputListener); - - fColorsCache = colorsCache; - fColumn = new AppNameRulerColumn(ANNOTATION_COLUMN_WIDTH, annotationAccess); - fColumn.addAnnotationType(AppNameAnnotation.TYPE); - - /* - * Setup tooltip for application name annotations - */ - fColumn.setHover(new IAnnotationHover() { - @Override - public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { - for (Iterator itr = fColumn.getModel().getAnnotationIterator(); itr.hasNext();) { - Object o = itr.next(); - if (o instanceof AppNameAnnotation) { - AppNameAnnotation a = (AppNameAnnotation) o; - Position p = fColumn.getModel().getPosition(a); - try { - if (fViewer.getDocument().getLineOfOffset(p.getOffset()) <= lineNumber && fViewer.getDocument().getLineOfOffset(p.getOffset() + p.getLength() - 1) >= lineNumber) { - String hoverText = "Application '" + a.getText() + "'"; - if (a.isSelected()) { - hoverText += " is selected"; - } - return hoverText; - } - } catch (BadLocationException e) { - Log.log(e); - } - } - } - return null; - } - - }); - - /* - * Setup application name line highlight painting on the viewer's text widget - */ - AppNameAnnotationsPainter annotationPainter= new AppNameAnnotationsPainter(fViewer, annotationAccess); - annotationPainter.addDrawingStrategy(AppNameAnnotationModel.APP_NAME_MODEL_KEY, new AppNameDrawingStrategy()); - annotationPainter.addAnnotationType(AppNameAnnotation.TYPE, AppNameAnnotationModel.APP_NAME_MODEL_KEY); - annotationPainter.setAnnotationTypeColor(AppNameAnnotation.TYPE, fViewer.getControl().getDisplay().getSystemColor(SWT.COLOR_GRAY)); - initAppAnnotationModel(); - fViewer.addPainter(annotationPainter); - - /* - * Attach application annotations ruler to the viewer - */ - if (fixedAppName == null) { - fViewer.addVerticalRulerColumn(fColumn); - } - } - - public void dispose() { - fViewer.removeTextInputListener(textInputListener); - } - - /** - * Finds and returns viewer's application name annotations model - * - * @param viewer Source viewer - * @return Viewer's application name annotations model - */ - public static AppNameAnnotationModel getAppNameAnnotationModel(ISourceViewer viewer) { - IAnnotationModel model = viewer instanceof ISourceViewerExtension2 - ? ((ISourceViewerExtension2) viewer).getVisualAnnotationModel() : viewer.getAnnotationModel(); - AppNameAnnotationModel appNameModel = null; - if (model instanceof IAnnotationModelExtension) { - appNameModel = (AppNameAnnotationModel) ((IAnnotationModelExtension) model) - .getAnnotationModel(AppNameAnnotationModel.APP_NAME_MODEL_KEY); - } else if (model instanceof AppNameAnnotationModel) { - appNameModel = (AppNameAnnotationModel) model; - } - return appNameModel; - } - - private static class AppNameAnnotationsPainter extends AnnotationPainter { - - /** - * Creates a new painter indicating the location of collapsed regions. - * - * @param sourceViewer the source viewer for the painter - * @param access the annotation access - */ - public AppNameAnnotationsPainter(ISourceViewer sourceViewer, IAnnotationAccess access) { - super(sourceViewer, access); - } - - /* - * @see org.eclipse.jface.text.source.AnnotationPainter#findAnnotationModel(org.eclipse.jface.text.source.ISourceViewer) - */ - protected IAnnotationModel findAnnotationModel(ISourceViewer sourceViewer) { - return getAppNameAnnotationModel(sourceViewer); - } - - /* - * @see org.eclipse.jface.text.source.AnnotationPainter#skip(org.eclipse.jface.text.source.Annotation) - */ - protected boolean skip(Annotation annotation) { - return !(annotation instanceof AppNameAnnotation); - } - } - - private class AppNameDrawingStrategy implements AnnotationPainter.IDrawingStrategy { - /* - * @see org.eclipse.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(org.eclipse.swt.graphics.GC, org.eclipse.swt.custom.StyledText, int, int, org.eclipse.swt.graphics.Color) - */ - public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { - if (annotation instanceof AppNameAnnotation) { - AppNameAnnotation a = (AppNameAnnotation) annotation; - StyledTextContent content = textWidget.getContent(); - final int line = content.getLineAtOffset(offset); - if (gc == null) { - /* - * Clear off highlighting case - */ - textWidget.setLineBackground(line, 1, null); - textWidget.redrawRange(offset, length, true); - } else { - /* - * Show highlighting case IMPORTANT: do not modify - * 'textWidget' graphical parameters! It would start - * scheduling async updates indefinitely! Hence other parts - * of the UI won't have a chance to repaint themselves - */ - Position p = fColumn.getModel().getPosition(annotation); - if (p != null && line == content.getLineAtOffset(p.getOffset())) { - /* - * Draw transparent line highlight rectangle. Ensure - * it's transparent such that text behind it is visible - */ - Color lineColor = a.isSelected() ? fColorsCache.getColor(SELECTED_APP_NAME_COLOR) - : fColorsCache.getColor(APP_NAME_COLOR); - Color c = gc.getBackground(); - int opacity = gc.getAlpha(); - gc.setBackground(lineColor); - gc.setAlpha(APP_NAME_ANNOTATION_ALPHA); - gc.fillRectangle(0, textWidget.getLocationAtOffset(offset).y, textWidget.getClientArea().width, - textWidget.getLineHeight()); - gc.setAlpha(opacity); - gc.setBackground(c); - } - } - } - } - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameReconciler.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameReconciler.java deleted file mode 100644 index 532b045cc..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameReconciler.java +++ /dev/null @@ -1,239 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 2019 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.cf.deployment; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.source.Annotation; -import org.eclipse.jface.text.source.IAnnotationModelExtension; -import org.springframework.ide.eclipse.editor.support.yaml.ast.YamlASTProvider; -import org.springframework.ide.eclipse.editor.support.yaml.ast.YamlFileAST; -import org.springsource.ide.eclipse.commons.livexp.util.Log; -import org.yaml.snakeyaml.nodes.Node; -import org.yaml.snakeyaml.nodes.ScalarNode; -import org.yaml.snakeyaml.nodes.SequenceNode; -import org.yaml.snakeyaml.parser.ParserException; -import org.yaml.snakeyaml.scanner.ScannerException; - -/** - * Reconciler responsible for creating annotation at application names positions - * in the Deployment YAML document - * - * @author Alex Boyko - * - */ -public class AppNameReconciler { - - /** - * YAML parser - */ - private YamlASTProvider fParser; - - public AppNameReconciler(YamlASTProvider parser) { - fParser = parser; - } - - /** - * Re-populates annotation model with app name annotations based on document contents - * - * @param document The YAML document - * @param annotationModel Application Names annotation model - * @param monitor Progress monitor - */ - public void reconcile(IDocument document, AppNameAnnotationModel annotationModel, IProgressMonitor monitor) { - if (annotationModel == null) { - return; - } - - List toRemove= new ArrayList<>(); - - Iterator iter= annotationModel.getAnnotationIterator(); - while (iter.hasNext()) { - Annotation annotation= iter.next(); - if (AppNameAnnotation.TYPE.equals(annotation.getType())) { - toRemove.add(annotation); - } - } - Annotation[] annotationsToRemove= toRemove.toArray(new Annotation[toRemove.size()]); - - /* - * Create brand new annotation to position map based on docs contents - */ - Map annotationsToAdd = createAnnotations(document, annotationModel, monitor); - - /* - * Update annotation model - */ - if (annotationModel instanceof IAnnotationModelExtension) - ((IAnnotationModelExtension)annotationModel).replaceAnnotations(annotationsToRemove, annotationsToAdd); - else { - for (int i= 0; i < annotationsToRemove.length; i++) - annotationModel.removeAnnotation(annotationsToRemove[i]); - for (iter= annotationsToAdd.keySet().iterator(); iter.hasNext();) { - Annotation annotation= iter.next(); - annotationModel.addAnnotation(annotation, annotationsToAdd.get(annotation)); - } - } - } - - /** - * Create new annotation to position mapping based on the document contents - * - * @param annotationModel Application name annotations model - * @return Map of annotations to their corresponding positions - */ - private Map createAnnotations(IDocument document, AppNameAnnotationModel annotationModel, IProgressMonitor monitor) { - Map annotationsMap = new LinkedHashMap<>(); - monitor.beginTask("Calculating application names", 100); - try { - YamlFileAST ast = fParser.getAST(document); - String contents = document.get(); - List rootList = ast.getNodes(); - monitor.worked(70); - if (rootList.size() == 1) { - Node root = rootList.get(0); - SequenceNode applicationsNode = YamlGraphDeploymentProperties.getNode(root, ApplicationManifestHandler.APPLICATIONS_PROP, SequenceNode.class); - if (applicationsNode == null) { - /* - * No 'applications' YAML node consider root elements to the deployment properties of an application - */ - ScalarNode node = YamlGraphDeploymentProperties.getPropertyValue(root, ApplicationManifestHandler.NAME_PROP, ScalarNode.class); - if (node != null) { - /* - * There is 'name' property present, so yes root has application deployment props - */ - annotationsMap.put(new AppNameAnnotation(node.getValue(), true), - new Position(root.getStartMark().getIndex(), - getLastWhiteCharIndex(contents, root.getEndMark().getIndex()) - - root.getStartMark().getIndex())); - } - } else { - /* - * Go through entries in the 'applications' sequence node - */ - for (Node appNode : applicationsNode.getValue()) { - ScalarNode node = YamlGraphDeploymentProperties.getNode(appNode, ApplicationManifestHandler.NAME_PROP, ScalarNode.class); - if (node != null) { - /* - * Add application name annotation entry - */ - annotationsMap.put(new AppNameAnnotation(node.getValue()), new Position(appNode.getStartMark().getIndex(), getLastWhiteCharIndex(contents, appNode.getEndMark().getIndex()) - appNode.getStartMark().getIndex())); - } - } - } - monitor.worked(20); - if (!annotationsMap.isEmpty()) { - if (annotationModel.fixedAppName == null) { - /* - * Select either previously selected app name annotation or the first found - */ - reselectAnnotation(annotationModel, annotationsMap); - } else { - /* - * Select annotation corresponding to application name == to fAppName - */ - selectAnnotationByAppName(annotationsMap, annotationModel.fixedAppName); - } - monitor.worked(10); - } - } - } catch (ParserException | ScannerException e) { - // Ignore these exceptions as they'd appear as syntax errors in the editor - } catch (Throwable t) { - Log.log(t); - } finally { - monitor.done(); - } - return annotationsMap; - } - - /** - * Selects annotation from the map corresponding to currently selected - * annotation. Otherwise just selects the first found annotation - * - * @param annotationModel Application name annotations model - * @param annotationsMap Map of application name annotations to positions - */ - private void reselectAnnotation(AppNameAnnotationModel annotationModel, Map annotationsMap) { - AppNameAnnotation selected = annotationModel.getSelectedAppAnnotation(); - Map.Entry newSelected = null; - if (selected != null) { - Position selectedPosition = annotationModel.getPosition(selected); - for (Map.Entry entry : annotationsMap.entrySet()) { - /* - * Check if application name matches - */ - if (entry.getKey().getText().equals(selected.getText())) { - /* - * If name matches see if previous match is further away - * from previously selected annotation offset than the - * current match. Update the match accordingly. - */ - if (newSelected == null) { - newSelected = entry; - } else if (Math.abs(newSelected.getValue().getOffset() - selectedPosition.getOffset()) > Math.abs(entry.getValue().getOffset() - selectedPosition.getOffset())){ - newSelected = entry; - } - } else if (entry.getValue().getOffset() == selectedPosition.getOffset() && newSelected == null) { - newSelected = entry; - } - } - } - if (newSelected == null) { - /* - * No matches found. Select the first annotation to have something selected. - */ - newSelected = annotationsMap.entrySet().iterator().next(); - } - newSelected.getKey().markSelected(); - } - - /** - * Select annotation matching constant application name, i.e. FAppName - * - * @param annotationsMap Map of application name annotations to positions - */ - private void selectAnnotationByAppName(Map annotationsMap, String appName) { - for (Map.Entry entry : annotationsMap.entrySet()) { - if (entry.getKey().getText().equals(appName)) { - entry.getKey().markSelected(); - return; - } - } - } - - /** - * Returns the first 'white' char after a word appearing before the passed index - * - * @param text Text - * @param index Index to start looking from - * @return The first 'white' char position in a string - */ - private static int getLastWhiteCharIndex(String text, int index) { - if (index == text.length()) { - return index; - } - int i = index; - for (; i >= 0 && Character.isWhitespace(text.charAt(i)); i--) { - // Nothing to do - } - // Special case: if non white char is at position 'index' then return value of 'index' - return i == index ? i : i + 1; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameReconcilingStrategy.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameReconcilingStrategy.java deleted file mode 100644 index 33f5aba68..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameReconcilingStrategy.java +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 2019 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.cf.deployment; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.Region; -import org.eclipse.jface.text.reconciler.DirtyRegion; -import org.eclipse.jface.text.reconciler.IReconcilingStrategy; -import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension; -import org.eclipse.jface.text.source.IAnnotationModel; -import org.eclipse.jface.text.source.IAnnotationModelExtension; -import org.eclipse.jface.text.source.ISourceViewer; -import org.eclipse.jface.text.source.ISourceViewerExtension2; -import org.springframework.ide.eclipse.editor.support.yaml.ast.YamlASTProvider; - -/** - * Reconciling strategy responsible for keeping track of application name - * annotations - * - * @author Alex Boyko - * - */ -public class AppNameReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension { - - /** - * Reconciler for application name annotations - */ - private AppNameReconciler fReconciler; - - /** - * Source viewer - */ - private ISourceViewer fViewer; - - /** - * Document to perform reconciling on - */ - private IDocument fDocument; - - /** - * Reconciling cycle progress monitor - */ - private IProgressMonitor fProgressMonitor; - - /** - * Creates new instance of the reconciler - * - * @param viewer Source viewer - * @param parser YAML parser - * @param appName Application name to keep selected all the time - */ - public AppNameReconcilingStrategy(YamlASTProvider parser) { - fReconciler = new AppNameReconciler(parser); - } - - /* - * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile() - */ - public void initialReconcile() { - reconcile(new Region(0, fDocument.getLength())); - } - - /* - * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion,org.eclipse.jface.text.IRegion) - */ - public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) { - try { - IRegion startLineInfo= fDocument.getLineInformationOfOffset(subRegion.getOffset()); - IRegion endLineInfo= fDocument.getLineInformationOfOffset(subRegion.getOffset() + Math.max(0, subRegion.getLength() - 1)); - if (startLineInfo.getOffset() == endLineInfo.getOffset()) - subRegion= startLineInfo; - else - subRegion= new Region(startLineInfo.getOffset(), endLineInfo.getOffset() + Math.max(0, endLineInfo.getLength() - 1) - startLineInfo.getOffset()); - - } catch (BadLocationException e) { - subRegion= new Region(0, fDocument.getLength()); - } - reconcile(subRegion); - } - - private AppNameAnnotationModel getAppNameAnnotationModel() { - IAnnotationModel model = fViewer instanceof ISourceViewerExtension2 ? ((ISourceViewerExtension2)fViewer).getVisualAnnotationModel() : fViewer.getAnnotationModel(); - if (model instanceof IAnnotationModelExtension) { - return (AppNameAnnotationModel) ((IAnnotationModelExtension) model).getAnnotationModel(AppNameAnnotationModel.APP_NAME_MODEL_KEY); - } - return (AppNameAnnotationModel) model; - } - - @Override - public void reconcile(IRegion region) { - fReconciler.reconcile(fDocument, getAppNameAnnotationModel(), fProgressMonitor); - } - - /* - * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor) - */ - public final void setProgressMonitor(IProgressMonitor monitor) { - fProgressMonitor= monitor; - } - - @Override - public void setDocument(IDocument document) { - fDocument= document; - } - - public void install(ISourceViewer viewer) { - fViewer = viewer; - } - - public void uninstall() { - fViewer = null; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameRulerColumn.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameRulerColumn.java deleted file mode 100644 index a0b14cf5d..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/AppNameRulerColumn.java +++ /dev/null @@ -1,227 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.deployment; - -import java.util.Iterator; - -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.source.AnnotationRulerColumn; -import org.eclipse.jface.text.source.CompositeRuler; -import org.eclipse.jface.text.source.IAnnotationAccess; -import org.eclipse.jface.text.source.IAnnotationModel; -import org.eclipse.jface.text.source.IAnnotationModelExtension; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackAdapter; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -/** - * Application name annotations ruler control. Implementation based on - * ProjectionRulerColumn class implementation - * - * @author Alex Boyko - * - */ -public class AppNameRulerColumn extends AnnotationRulerColumn { - - /** - * Currently examined/hovered over annotation - */ - private AppNameAnnotation fCurrentAnnotation; - - /** - * Line number recorded on mouse down. - */ - private int fMouseDownLine; - - public AppNameRulerColumn(IAnnotationModel model, int width, IAnnotationAccess annotationAccess) { - super(model, width, annotationAccess); - } - - public AppNameRulerColumn(int width, IAnnotationAccess annotationAccess) { - super(width, annotationAccess); - } - - @Override - protected void mouseClicked(int line) { - clearCurrentAnnotation(); - if (fMouseDownLine != line) - return; - AppNameAnnotation annotation= findAnnotation(line, true); - if (annotation != null) { - AppNameAnnotationModel model= (AppNameAnnotationModel) getModel(); - model.markSelected(annotation); - } - } - - @Override - protected void mouseDown(int rulerLine) { - fMouseDownLine= rulerLine; - } - - @Override - protected void mouseDoubleClicked(int rulerLine) { - if (findAnnotation(rulerLine, true) != null) - return; - - AppNameAnnotation annotation= findAnnotation(rulerLine, false); - if (annotation != null) { - AppNameAnnotationModel model= (AppNameAnnotationModel) getModel(); - model.markSelected(annotation); - } - } - - /** - * Returns the app's name annotation of the column's annotation - * model that contains the given line. - * - * @param line the line - * @param exact true if the annotation range must match exactly - * @return the app name annotation containing the given line - */ - private AppNameAnnotation findAnnotation(int line, boolean exact) { - - AppNameAnnotation previousAnnotation= null; - - IAnnotationModel model= getModel(); - if (model != null) { - IDocument document= getCachedTextViewer().getDocument(); - - int previousDistance= Integer.MAX_VALUE; - - Iterator e= model.getAnnotationIterator(); - while (e.hasNext()) { - Object next= e.next(); - if (next instanceof AppNameAnnotation) { - AppNameAnnotation annotation= (AppNameAnnotation) next; - Position p= model.getPosition(annotation); - if (p == null) - continue; - - int distance= getDistance(annotation, p, document, line); - if (distance == -1) - continue; - - if (!exact) { - if (distance < previousDistance) { - previousAnnotation= annotation; - previousDistance= distance; - } - } else if (distance == 0) { - previousAnnotation= annotation; - } - } - } - } - - return previousAnnotation; - } - - /** - * Returns the distance of the given line to the start line of the given position in the given document. The distance is - * -1 when the line is not included in the given position. - * - * @param annotation the annotation - * @param position the position - * @param document the document - * @param line the line - * @return -1 if line is not contained, a position number otherwise - */ - private int getDistance(AppNameAnnotation annotation, Position position, IDocument document, int line) { - if (position.getOffset() > -1 && position.getLength() > -1) { - try { - int startLine= document.getLineOfOffset(position.getOffset()); - int endLine= document.getLineOfOffset(position.getOffset() + position.getLength()); - if (startLine <= line && line < endLine) { - return line - startLine; - } - } catch (BadLocationException x) { - } - } - return -1; - } - - private boolean clearCurrentAnnotation() { - if (fCurrentAnnotation != null) { - fCurrentAnnotation.setRangeIndication(false); - fCurrentAnnotation= null; - return true; - } - return false; - } - - @Override - public Control createControl(CompositeRuler parentRuler, Composite parentControl) { - Control control= super.createControl(parentRuler, parentControl); - - // set background - Color background= getCachedTextViewer().getTextWidget().getBackground(); - control.setBackground(background); - - // install hover listener - control.addMouseTrackListener(new MouseTrackAdapter() { - public void mouseExit(MouseEvent e) { - if (clearCurrentAnnotation()) - redraw(); - } - }); - - // install mouse move listener - control.addMouseMoveListener(new MouseMoveListener() { - public void mouseMove(MouseEvent e) { - boolean redraw= false; - AppNameAnnotation annotation= findAnnotation(toDocumentLineNumber(e.y), false); - if (annotation != fCurrentAnnotation) { - if (fCurrentAnnotation != null) { - fCurrentAnnotation.setRangeIndication(false); - redraw= true; - } - fCurrentAnnotation= annotation; - if (fCurrentAnnotation != null) { - fCurrentAnnotation.setRangeIndication(true); - redraw= true; - } - } - if (redraw) - redraw(); - } - }); - return control; - } - - @Override - public void setModel(IAnnotationModel model) { - if (!(model instanceof AppNameAnnotationModel) && model instanceof IAnnotationModelExtension) { - IAnnotationModelExtension extension= (IAnnotationModelExtension) model; - model= extension.getAnnotationModel(AppNameAnnotationModel.APP_NAME_MODEL_KEY); - } - super.setModel(model); - } - - /* - * @see org.eclipse.jface.text.source.AnnotationRulerColumn#isPropagatingMouseListener() - */ - protected boolean isPropagatingMouseListener() { - return false; - } - - /* - * @see org.eclipse.jface.text.source.AnnotationRulerColumn#hasAnnotation(int) - */ - protected boolean hasAnnotation(int lineNumber) { - return findAnnotation(lineNumber, true) != null; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/ApplicationManifestHandler.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/ApplicationManifestHandler.java deleted file mode 100644 index 27d2af68a..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/ApplicationManifestHandler.java +++ /dev/null @@ -1,1021 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2022 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.cf.deployment; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.apache.commons.lang3.RandomStringUtils; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubMonitor; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFStack; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFDomainStatus; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFRoute; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentProperties; -import org.springframework.ide.eclipse.boot.util.Log; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.DumperOptions.FlowStyle; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; -import org.yaml.snakeyaml.representer.Representer; - -import com.google.common.collect.ImmutableList; - -/** - * Reads and creates manifest.yml content from a specific location relative to - * an {@link IProject}. - * - */ -public class ApplicationManifestHandler { - - public static final String RANDOM_VAR = "${random}"; //$NON-NLS-1$ - - public static final String APPLICATIONS_PROP = "applications"; - - public static final String NAME_PROP = "name"; - - public static final String MEMORY_PROP = "memory"; - - public static final String INSTANCES_PROP = "instances"; - - public static final String SUB_DOMAIN_PROP = "host"; - - public static final String SUB_DOMAINS_PROP = "hosts"; - - public static final String DOMAIN_PROP = "domain"; - - public static final String DOMAINS_PROP = "domains"; - - public static final String NO_ROUTE_PROP = "no-route"; - - public static final String NO_HOSTNAME_PROP = "no-hostname"; - - public static final String RANDOM_ROUTE_PROP = "random-route"; - - public static final String SERVICES_PROP = "services"; - - public static final String LABEL_PROP = "label"; - - public static final String PROVIDER_PROP = "provider"; - - public static final String VERSION_PROP = "version"; - - public static final String PLAN_PROP = "plan"; - - public static final String PATH_PROP = "path"; - - public static final String BUILDPACK_PROP = "buildpack"; - - public static final String BUILDPACKS_PROP = "buildpacks"; - - public static final String ENV_PROP = "env"; - - public static final String DISK_QUOTA_PROP = "disk_quota"; - - public static final String INHERIT_PROP = "inherit"; - - public static final String TIMEOUT_PROP = "timeout"; - - public static final String HEALTH_CHECK_TYPE_PROP = "health-check-type"; - - public static final String HEALTH_CHECK_HTTP_ENDPOINT_PROP = "health-check-http-endpoint"; - - public static final String COMMAND_PROP = "command"; - - public static final String STACK_PROP = "stack"; - - public static final String ROUTES_PROP = "routes"; - - public static final String ROUTE_PROP = "route"; - - private final IProject project; - - private final IFile manifestFile; - - private final CloudData cloudData; - - public ApplicationManifestHandler(IProject project, CloudData cloudData) { - this(project, cloudData, null); - } - - public ApplicationManifestHandler(IProject project, CloudData cloudData, IFile manifestFile) { - this.project = project; - this.manifestFile = manifestFile; - this.cloudData = cloudData; - } - - protected InputStream getInputStream() throws Exception { - - File file = getManifestFile(); - if (file != null && file.exists()) { - return new FileInputStream(file); - } else { - throw ExceptionUtil.coreException("No manifest.yml file found in project: " + project.getName()); - } - } - - /** - * - * @return manifest file if it exists. Null otherwise - */ - public File getManifestFile() { - if (manifestFile != null) { - URI locationURI = manifestFile.getLocationURI(); - if (locationURI != null) { - File file = new File(locationURI); - return file.exists() ? file : null; - } - } - return null; - } - - public boolean hasManifest() { - File file = getManifestFile(); - return file != null && file.exists(); - } - - /** - * - * @param applicationName - * name of application to lookup in the manifest file. - * @param propertyName - * String value property to retrieve from manifest for given - * application entry. - * @return Value of property, or null if not found, or entry for application - * in manifest does not exist. - */ - public String getApplicationProperty(String appName, String propertyName, IProgressMonitor monitor) { - try { - Map appMap = getApplicationMap(appName, monitor); - if (appMap != null) { - return getValue(appMap, propertyName, String.class); - } - } catch (Exception e) { - Log.log(e); - } - return null; - } - - public Map getApplicationMap(String appName, IProgressMonitor monitor) throws Exception { - Map allResults = parseManifestFromFile(); - - List> appMaps = getApplications(allResults); - - for (Map appMap : appMaps) { - - String existingAppName = getValue(appMap, NAME_PROP, String.class); - if (existingAppName != null && existingAppName.equals(appName)) { - return appMap; - } - } - return null; - } - - /** - * - * @param containerMap - * @param propertyName - * @return map of values for the given property name, or null if it cannot - * be resolved - */ - @SuppressWarnings("unchecked") - protected Map getContainingPropertiesMap(Map containerMap, String propertyName) { - if (containerMap == null || propertyName == null) { - return null; - } - Object yamlElementObj = containerMap.get(propertyName); - - if (yamlElementObj instanceof Map) { - return (Map) yamlElementObj; - } else { - return null; - } - } - -// protected String getStringValue(Map containingMap, String propertyName) { -// -// if (containingMap == null) { -// return null; -// } -// -// Object valObj = containingMap.get(propertyName); -// -// if (valObj instanceof String) { -// return (String) valObj; -// } -// return null; -// } -// - @SuppressWarnings("unchecked") - protected static T getValue(Map containingMap, String propertyName, Class type) { - if (containingMap == null) { - return null; - } - Object valObj = containingMap.get(propertyName); - - if (valObj != null && type.isAssignableFrom(valObj.getClass())) { - return (T) valObj; - } - return null; - } - - protected static boolean hasValue(Map containingMap, String propertyName) { - return containingMap != null && containingMap.containsKey(propertyName); - } - - public static List> getApplications(Map results) throws CoreException { - - Object applicationsObj = results.get(APPLICATIONS_PROP); - if (!(applicationsObj instanceof List)) { - return null; - } - - List applicationsList = (List) applicationsObj; - - List> applications = new ArrayList<>(); - - // Use only the first application entry - if (!applicationsList.isEmpty()) { - for (Object val : applicationsList) { - if (val instanceof Map) { - applications.add((Map) val); - } - - } - } - - return applications; - } - - protected CloudApplicationDeploymentProperties getDeploymentProperties(Map appMap, - Map allResults, IProgressMonitor monitor) throws Exception { - - CloudApplicationDeploymentProperties properties = new CloudApplicationDeploymentProperties(); - - String appName = getValue(appMap, NAME_PROP, String.class); - - properties.setAppName(appName); - properties.setProject(project); - properties.setManifestFile(manifestFile); - - readMemory(appMap, allResults, properties); - - readDiskQuota(appMap, allResults, properties); - - readApplicationURL(appMap, allResults, properties); - - readBuildpack(appMap, allResults, properties); - - readBuildpacks(appMap, allResults, properties); - - readEnvVars(appMap, allResults, properties); - - readServices(appMap, allResults, properties); - - readInstances(appMap, allResults, properties); - - readTimeout(appMap, allResults, properties); - - readHealthCheckType(appMap, allResults, properties); - - readHealthCheckHttpEndpoint(appMap, allResults, properties); - - readCommand(appMap, allResults, properties); - - readStack(appMap, allResults, properties); - - return properties; - } - - public List load(IProgressMonitor monitor) throws Exception { - SubMonitor subMonitor = SubMonitor.convert(monitor); - subMonitor.beginTask("Loading manifest.yml", 6); - - try { - - Map allResults = parseManifestFromFile(); - - if (allResults == null || allResults.isEmpty()) { - throw ExceptionUtil - .coreException("No content found in manifest.yml. Make sure the manifest is valid."); - - } - - List> appMaps = getApplications(allResults); - - List properties = new ArrayList<>(); - - if (appMaps == null) { - CloudApplicationDeploymentProperties props = getDeploymentProperties(allResults, allResults, subMonitor); - if (props != null) { - properties.add(props); - } - } else { - for (Map app : appMaps) { - CloudApplicationDeploymentProperties props = getDeploymentProperties(app, allResults, subMonitor); - if (props != null) { - properties.add(props); - } - } - } - - return properties; - - } finally { - subMonitor.done(); - } - - } - - /** - * Creates a new manifest.yml file. If one already exists, the existing one - * will not be replaced. - * - * @return true if new file created with content. False otherwise - * @throws Exception - * if error occurred during file creation or serialising - * manifest content - */ - public boolean create(IProgressMonitor monitor, CloudApplicationDeploymentProperties properties) throws Exception { - - if (properties == null) { - return false; - } - File file = getManifestFile(); - if (file != null) { - Log.warn( - "Manifest.yml file already found at: " + manifestFile.getFullPath() + ". New content will not be written."); - return false; - } - - Map deploymentInfoYaml = toYaml(properties, cloudData); - DumperOptions options = new DumperOptions(); - options.setExplicitStart(true); - options.setCanonical(false); - options.setPrettyFlow(true); - options.setDefaultFlowStyle(FlowStyle.BLOCK); - Yaml yaml = new Yaml(new SafeConstructor(), new Representer(options), options); - String manifestValue = yaml.dump(deploymentInfoYaml); - - if (manifestValue == null) { - throw ExceptionUtil.coreException("Failed to generate manifesty.yml for: " + properties.getAppName() - + " Unknown problem trying to serialise content of manifest into: " + deploymentInfoYaml); - } - - createFile(project, manifestFile, manifestValue, monitor); - return true; - } - - public static Map toYaml(DeploymentProperties properties, CloudData cloudData) { - return toYaml(properties, cloudData, false); - } - - @SuppressWarnings("unchecked") - public static Map toYaml(DeploymentProperties properties, CloudData cloudData, boolean legacyHostDomain) { - Map deploymentInfoYaml = new LinkedHashMap<>(); - - Object applicationsObj = deploymentInfoYaml.get(APPLICATIONS_PROP); - List> applicationsList = null; - if (applicationsObj == null) { - applicationsList = new ArrayList<>(); - deploymentInfoYaml.put(APPLICATIONS_PROP, applicationsList); - } else if (applicationsObj instanceof List) { - applicationsList = (List>) applicationsObj; - } - - Map application = new LinkedHashMap<>(); - applicationsList.add(application); - - application.put(NAME_PROP, properties.getAppName()); - - String memory = getMemoryAsString(properties.getMemory()); - if (memory != null) { - application.put(MEMORY_PROP, memory); - } - - String diskQuota = getMemoryAsString(properties.getDiskQuota()); - if (diskQuota != null && properties.getDiskQuota() != DeploymentProperties.DEFAULT_MEMORY) { - application.put(DISK_QUOTA_PROP, diskQuota); - } - - if (properties.getInstances() != DeploymentProperties.DEFAULT_INSTANCES) { - application.put(ApplicationManifestHandler.INSTANCES_PROP, properties.getInstances()); - } - if (properties.getTimeout() != null) { - application.put(ApplicationManifestHandler.TIMEOUT_PROP, properties.getTimeout()); - } - String healthCheck = properties.getHealthCheckType(); - if (healthCheck != null) { - application.put(ApplicationManifestHandler.HEALTH_CHECK_TYPE_PROP, healthCheck); - } - String healthCheckHttpEndpoint = properties.getHealthCheckHttpEndpoint(); - if (healthCheckHttpEndpoint != null) { - application.put(ApplicationManifestHandler.HEALTH_CHECK_HTTP_ENDPOINT_PROP, healthCheckHttpEndpoint); - } - if (properties.getCommand() != null) { - application.put(ApplicationManifestHandler.COMMAND_PROP, properties.getCommand()); - } - if (properties.getStack() != null) { - application.put(ApplicationManifestHandler.STACK_PROP, properties.getStack()); - } - if (properties.getServices() != null && !properties.getServices().isEmpty()) { - application.put(SERVICES_PROP, properties.getServices()); - } - if (properties.getEnvironmentVariables() != null && !properties.getEnvironmentVariables().isEmpty()) { - application.put(ENV_PROP, properties.getEnvironmentVariables()); - } - if (properties.getBuildpack() != null) { - application.put(ApplicationManifestHandler.BUILDPACK_PROP, properties.getBuildpack()); - } - - if (legacyHostDomain) { - Set hosts = new LinkedHashSet<>(); - Set domains = new LinkedHashSet<>(); - List cloudDomains = cloudData.getDomains(); - extractHostsAndDomains(properties.getUris(), cloudDomains, hosts, domains); - for (String uri : properties.getUris()) { - try { - // Find the first valid URL - CFRoute route = CFRoute.builder().from(uri, cloudDomains).build(); - if (route.getHost() != null) { - hosts.add(route.getHost()); - } - if (route.getDomain() != null) { - domains.add(route.getDomain()); - } - } catch (Exception e) { - // ignore - } - } - if (hosts.isEmpty() && domains.isEmpty()) { - application.put(NO_ROUTE_PROP, true); - } else { - if (hosts.isEmpty()) { - application.put(NO_HOSTNAME_PROP, true); - } else if (hosts.size() == 1) { - String host = hosts.iterator().next(); - if (!properties.getAppName().equals(host)) { - application.put(SUB_DOMAIN_PROP, host); - } - } else { - application.put(SUB_DOMAINS_PROP, new ArrayList<>(hosts)); - } - if (domains.size() == 1) { - application.put(DOMAIN_PROP, domains.iterator().next()); - } else if (domains.size() > 1) { - application.put(DOMAINS_PROP, new ArrayList<>(domains)); - } - } - } else { - Set uris = properties.getUris(); - if (uris == null || uris.isEmpty()) { - application.put(NO_ROUTE_PROP, true); - } else { - application.put(ApplicationManifestHandler.ROUTES_PROP, uris.stream().map(uri -> { - Map route = new LinkedHashMap<>(); - route.put(ApplicationManifestHandler.ROUTE_PROP, uri); - return route; - }).collect(Collectors.toList())); - } - } - - return deploymentInfoYaml; - } - - public static void extractHostsAndDomains(Collection uris, List cloudDomains, Set hostsSet, Set domainsSet) { - for (String uri : uris) { - try { - // Find the first valid URL - CFRoute route = CFRoute.builder().from(uri, cloudDomains).build(); - if (route.getHost() != null) { - hostsSet.add(route.getHost()); - } - if (route.getDomain() != null) { - domainsSet.add(route.getDomain()); - } - } catch (Exception e) { - // ignore - } - } - } - - public void createFile(IProject project, IFile file, String data, IProgressMonitor monitor) throws CoreException { - file.create(new ByteArrayInputStream(data.getBytes()), true, monitor); - project.refreshLocal(IResource.DEPTH_INFINITE, monitor); - } - - protected void readEnvVars(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - Map propertiesMap = new LinkedHashMap<>(); - Map map = getContainingPropertiesMap(allResults, ENV_PROP); - if (map != null) { - propertiesMap.putAll(map); - } - map = getContainingPropertiesMap(application, ENV_PROP); - if (map != null) { - propertiesMap.putAll(map); - } - - if (propertiesMap.isEmpty()) { - return; - } - - Map loadedVars = new HashMap<>(); - - for (Entry entry : propertiesMap.entrySet()) { - if ((entry.getKey() instanceof String)) { - String varName = (String) entry.getKey(); - String varValue = null; - if (entry.getValue() instanceof String) { - varValue = (String) entry.getValue(); - } else if (entry.getValue() instanceof Integer) { - varValue = Integer.toString((Integer) entry.getValue()); - } - if (varName != null && varValue != null) { - loadedVars.put(varName, varValue); - } - } - } - properties.setEnvironmentVariables(loadedVars); - } - - protected void readServices(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - - Object yamlElementObj = allResults.get(SERVICES_PROP); - List cloudServices = new ArrayList<>(); - - if (yamlElementObj instanceof List) { - addTo((List) yamlElementObj, cloudServices); - } - - yamlElementObj = application.get(SERVICES_PROP); - if (yamlElementObj instanceof List) { - addTo((List) yamlElementObj, cloudServices); - } - - properties.setServices(cloudServices); - } - - protected void readBuildpacks(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - - Object yamlElementObj = allResults.get(BUILDPACKS_PROP); - List buildpacks = new ArrayList<>(); - - if (yamlElementObj instanceof List) { - addTo((List) yamlElementObj, buildpacks); - } - - yamlElementObj = application.get(BUILDPACKS_PROP); - if (yamlElementObj instanceof List) { - addTo((List) yamlElementObj, buildpacks); - } - - properties.setBuildpacks(buildpacks); - } - - protected void addTo(List from, List to) { - - for (Object obj : from) { - if (obj instanceof String && !to.contains(obj)) { - String val = (String) obj; - to.add(val); - } - } - } - - protected void readInstances(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - - Integer instances = getValue(application, INSTANCES_PROP, Integer.class); - if (instances == null) { - instances = getValue(allResults, INSTANCES_PROP, Integer.class); - } - if (instances != null) { - properties.setInstances(instances); - } - } - - protected void readTimeout(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - - Integer timeout = getValue(application, TIMEOUT_PROP, Integer.class); - if (timeout == null) { - timeout = getValue(allResults, TIMEOUT_PROP, Integer.class); - } - if (timeout != null) { - properties.setTimeout(timeout); - } - } - - private void readHealthCheckType(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - String hc = getValue(application, HEALTH_CHECK_TYPE_PROP, String.class); - if (hc == null) { - hc = getValue(allResults, HEALTH_CHECK_TYPE_PROP, String.class); - } - if (hc != null) { - properties.setHealthCheckType(hc); - } - } - - private void readHealthCheckHttpEndpoint(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - String hche = getValue(application, HEALTH_CHECK_HTTP_ENDPOINT_PROP, String.class); - if (hche == null) { - hche = getValue(allResults, HEALTH_CHECK_HTTP_ENDPOINT_PROP, String.class); - } - if (hche != null) { - properties.setHealthCheckHttpEndpoint(hche); - } - } - - protected void readBuildpack(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - - String buildpack = getValue(application, BUILDPACK_PROP, String.class); - if (buildpack == null) { - buildpack = getValue(allResults, BUILDPACK_PROP, String.class); - } - if (buildpack != null) { - properties.setBuildpack(buildpack); - } - } - - protected void readCommand(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - - String command = getValue(application, COMMAND_PROP, String.class); - if (command == null) { - command = getValue(allResults, COMMAND_PROP, String.class); - } - if (command != null) { - properties.setCommand(command); - } - } - - protected void readStack(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - - String stack = getValue(application, STACK_PROP, String.class); - if (stack == null) { - stack = getValue(allResults, STACK_PROP, String.class); - } - if (stack != null && isStackValid(stack, cloudData.getStacks())) { - properties.setStack(stack); - } - } - - private boolean noRoute(Map application, Map allResults) { - Boolean noRoute = getValue(application, NO_ROUTE_PROP, Boolean.class); - if (noRoute == null) { - noRoute = getValue(allResults, NO_ROUTE_PROP, Boolean.class); - } - return Boolean.TRUE.equals(noRoute); - } - - /** - * - * @param application - * @param allResults - * @param properties - * @param randomRoute true if random host should be generated - * @return non-null list of URIs parsed from domains and hosts. May be empty - */ - @SuppressWarnings("unchecked") - private List fromDomainsAndHosts(Map application, Map allResults, - CloudApplicationDeploymentProperties properties, boolean randomRoute) { - - HashSet hostsSet = new LinkedHashSet<>(); - HashSet domainsSet = new LinkedHashSet<>(); - - /* - * Gather domains from app node and root node from 'domain' and 'domains' attributes - */ - String domain = getValue(application, DOMAIN_PROP, String.class); - if (domain == null) { - domain = getValue(allResults, DOMAIN_PROP, String.class); - } - if (domain != null) { - domainsSet.add(domain); - } - List domainList = (List) getValue(allResults, DOMAINS_PROP, List.class); - if (domainList != null) { - domainsSet.addAll(domainList); - } - domainList = (List) getValue(application, DOMAINS_PROP, List.class); - if (domainList != null) { - domainsSet.addAll(domainList); - } - - /* - * Gather domains from app node and root node from 'host' and 'hosts' - * attributes. Account for ${random} in host's name - */ - String host = getValue(application, SUB_DOMAIN_PROP, String.class); - if (host == null) { - host = getValue(allResults, SUB_DOMAIN_PROP, String.class); - } - if (host != null) { - hostsSet.add(host); - } - List hostList = (List) getValue(allResults, SUB_DOMAINS_PROP, List.class); - if (hostList != null) { - hostsSet.addAll(hostList); - } - hostList = (List) getValue(application, SUB_DOMAINS_PROP, List.class); - if (hostList != null) { - hostsSet.addAll(hostList); - } - - /* - * If no host names found check for "random-route: true" and - * "no-hostname: true" otherwise take app name as the host name - */ - if (hostsSet.isEmpty()) { - if (randomRoute) { - //hostsSet.add(extractHost("${random}", 10)); - if (domainsSet.isEmpty()) { - domainsSet.add(cloudData.getDefaultDomain()); - } - } else { - Boolean noHostName = getValue(application, NO_HOSTNAME_PROP, Boolean.class); - if (noHostName == null) { - noHostName = getValue(allResults, NO_HOSTNAME_PROP, Boolean.class); - } - if (!Boolean.TRUE.equals(noHostName)) { - /* - * Assumes name is set before URIs are processed - */ - hostsSet.add(properties.getAppName()); - } - } - } - - /* - * Set a domain if they are still empty - */ - if (domainsSet.isEmpty()) { - domainsSet.add(cloudData.getDefaultDomain()); - } - - /* - * Compose URIs for application based on hosts and domains - */ - List uris = new ArrayList<>(hostsSet.isEmpty() ? 1 : hostsSet.size() * domainsSet.size()); - for (String d : domainsSet) { - if (hostsSet.isEmpty()) { - uris.add(CFRoute.builder().domain(d).build().getRoute()); - } else { - for (String h : hostsSet) { - uris.add(CFRoute.builder().host(h).domain(d).build().getRoute()); - } - } - } - - return uris; - } - - protected void readApplicationURL(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - Boolean randomRoute = getValue(application, RANDOM_ROUTE_PROP, Boolean.class); - if (randomRoute == null) { - randomRoute = getValue(allResults, RANDOM_ROUTE_PROP, Boolean.class); - } - boolean useRandomRoute = Boolean.TRUE.equals(randomRoute); - properties.setRandomRoute(useRandomRoute); - - /* - * Check for "no-route: true". If set then uris list should be empty - */ - if (!noRoute(application, allResults)) { - // Manifest documentation states: - // "The routes attribute cannot be used in conjunction with the - // following - // attributes: host, hosts, domain, domains, and no-hostname. - // An error will result." - // If only routes are available, then only parse routes. Do NOT - // also create a default URI from domain and app name if routes are available. - // This appears to be consistent with cf CLI behaviour as well. - // Otherwise fall back to parsing from domains and hosts - List uris = null; - if (hasRoutesProperty(application, allResults)) { - uris = fromRoutesProperty(application, allResults, properties); - } else { - uris = fromDomainsAndHosts(application, allResults, properties, useRandomRoute); - } - properties.setUris(uris); - } - } - - private List fromRoutesProperty(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) { - Set uris = new LinkedHashSet<>(); - List domains = cloudData.getDomains(); - List routes = getValue(application, ROUTES_PROP, List.class); - List rootRoutes = getValue(allResults, ROUTES_PROP, List.class); - if (routes != null || rootRoutes != null) { - routes = routes == null ? Collections.emptyList() : routes; - rootRoutes = rootRoutes == null ? Collections.emptyList() : rootRoutes; - - return ImmutableList.copyOf(Stream.concat(routes.stream(), rootRoutes.stream()) - .filter(o -> o instanceof Map) - .map(o -> (Map) o) - .map(routeMap -> routeMap.get(ROUTE_PROP)) - .filter(Objects::nonNull) - .filter(route -> route instanceof String) - .map(route -> { - String url = (String) route; - CFRoute rt = CFRoute.builder().from(url, domains).build(); - return rt.getRoute(); - }) - .collect(Collectors.toSet())); - } - return ImmutableList.copyOf(uris); - } - - protected boolean hasRoutesProperty(Map application, Map allResults) { - return hasValue(application, ROUTES_PROP) || hasValue(allResults, ROUTES_PROP); - } - - public static boolean isStackValid(String stack, List stacks) { - for (CFStack cloudStack : stacks) { - if (cloudStack.getName().equals(stack)) { - return true; - } - } - return false; - } - - private String extractHost(String subdomain, int length) { - // Check for random word - int varIndex = subdomain.indexOf(RANDOM_VAR); - while (varIndex >= 0) { - String randomWord = RandomStringUtils.randomAlphabetic(length); - subdomain = subdomain.replace(subdomain.substring(varIndex, RANDOM_VAR.length()), randomWord); - varIndex = subdomain.indexOf(RANDOM_VAR); - } - return subdomain; - } - - protected void readMemory(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) throws Exception { - int memoryValue = readMemoryValue(application, allResults, MEMORY_PROP); - if (memoryValue >= 0) { - properties.setMemory(memoryValue); - } - } - - protected void readDiskQuota(Map application, Map allResults, - CloudApplicationDeploymentProperties properties) throws Exception { - int memoryValue = readMemoryValue(application, allResults, DISK_QUOTA_PROP); - if (memoryValue >= 0) { - properties.setDiskQuota(memoryValue); - } - } - - protected int readMemoryValue(Map application, Map allResults, - String propertyKey) throws Exception { - // Check if value in integer form - Integer memoryVal = getValue(application, propertyKey, Integer.class); - if (memoryVal != null) { - return memoryVal.intValue(); - } - - // If not in Integer form, try String as the memory may end in with a 'G' or 'M' - String memoryStringVal = getValue(application, propertyKey, String.class); - if (memoryStringVal == null) { - // Check if there is memory property set for all apps if nothing set for the app specifically - memoryVal = getValue(allResults, propertyKey, Integer.class); - if (memoryVal == null) { - // Not in integer form - memoryStringVal = getValue(allResults, propertyKey, String.class); - } else { - // Integer form? Return the value right away - return memoryVal.intValue(); - } - } - - // Should only get here if memory value not in integer form - if (memoryStringVal != null && memoryStringVal.length() > 0) { - // Parse non-integer memory value - return convertMemory(memoryStringVal); - } - - // No memory property specified? Assume the default - return DeploymentProperties.DEFAULT_MEMORY; - } - - public static int convertMemory(String memoryStringVal) throws CoreException { - String memoryIndicator[] = { "m", "g", "mb", "gb" }; - int gIndex = -1; - boolean gb = false; - - for (String indicator : memoryIndicator) { - int beginIndex = memoryStringVal.length() - indicator.length(); - if (beginIndex >= 0) { - if (indicator.equalsIgnoreCase(memoryStringVal.substring(beginIndex))) { - gIndex = beginIndex; - gb = indicator.charAt(0) == 'g'; - break; - } - } - } - - // There has to be a number before the 'G' or 'M', if 'G' or 'M' - // is used, or its not a valid - // memory - if (gIndex > 0) { - memoryStringVal = memoryStringVal.substring(0, gIndex); - } else if (gIndex == 0) { - throw ExceptionUtil.coreException("Failed to read memory value. Invalid memory: " + memoryStringVal); - } - - try { - return Integer.valueOf(memoryStringVal) * (gb ? 1024 : 1); - } catch (NumberFormatException e) { - throw ExceptionUtil.coreException("Failed to parse memory due to: " + e.getMessage()); - } - } - - /** - * - * @return map of parsed manifest file, if the file exists. If the file does - * not exist, return null. - * @throws CoreException - * if manifest file exists, but error occurred that prevents a - * map to be generated. - */ - @SuppressWarnings("unchecked") - protected Map parseManifestFromFile() throws Exception { - - InputStream inputStream = getInputStream(); - - if (inputStream != null) { - Yaml yaml = new Yaml(new SafeConstructor()); - - try { - Object results = yaml.load(inputStream); - - if (results instanceof Map) { - return (Map) results; - } else { - String source = manifestFile == null ? "entered manifest" : "file " + manifestFile.getFullPath(); - throw ExceptionUtil.coreException("Expected a map of values for " - + source + ". Unable to load manifest content. Actual results: " + results); - } - - } finally { - try { - inputStream.close(); - } catch (IOException e) { - // Ignore - } - } - - } - return null; - } - - static protected String getMemoryAsString(int memory) { - if (memory < 1) { - return null; - } - return memory + "M"; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/ApplicationNameReconciler.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/ApplicationNameReconciler.java deleted file mode 100644 index 2f11cd405..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/ApplicationNameReconciler.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019 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.cf.deployment; - -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.reconciler.Reconciler; -import org.eclipse.jface.text.source.ISourceViewer; -import org.springframework.ide.eclipse.editor.support.yaml.ast.YamlASTProvider; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; - -/** - * Reconciler for Application names in CF deployment manifest YAML - * - * @author Alex Boyko - * - */ -public class ApplicationNameReconciler extends Reconciler { - - private AppNameReconcilingStrategy strategy; - - public ApplicationNameReconciler() { - super(); - YamlASTProvider parser = new YamlASTProvider(new Yaml(new SafeConstructor())); - strategy= new AppNameReconcilingStrategy(parser); - this.setReconcilingStrategy(strategy, IDocument.DEFAULT_CONTENT_TYPE); - } - - @Override - public void install(ITextViewer textViewer) { - super.install(textViewer); - if (textViewer instanceof ISourceViewer) { - strategy.install((ISourceViewer)textViewer); - } - } - - @Override - public void uninstall() { - super.uninstall(); - strategy.uninstall(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/CloudApplicationDeploymentProperties.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/CloudApplicationDeploymentProperties.java deleted file mode 100644 index eee7aea5e..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/CloudApplicationDeploymentProperties.java +++ /dev/null @@ -1,329 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2018 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.cf.deployment; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFPushArguments; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFRoute; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentProperties; -import org.springframework.ide.eclipse.boot.util.JavaProjectUtil; - -import com.google.common.collect.ImmutableList; - -public class CloudApplicationDeploymentProperties implements DeploymentProperties { - - private boolean enableJmxSshTunnel; - private List boundServices; - private Map environmentVariables; - private String buildpack; - private List buildpacks; - - private int instances; - - /* - * URLs should never be null. If no URLs are needed, keep list empty - */ - private LinkedHashSet urls; - - private String appName; - - public boolean getEnableJmxSshTunnel() { - return enableJmxSshTunnel; - } - - public void setEnableJmxSshTunnel(boolean enableJmxSshTunnel) { - this.enableJmxSshTunnel = enableJmxSshTunnel; - } - - private IProject project; - - private int memory; - - private int diskQuota; - - private IFile manifestFile; - - private Integer timeout; - - private String command; - - private String stack; - - /** - * Path to a zipFile containing the contents of the stuff to deploy. - */ - private File archive; - private String healthCheckType; - private String healthCheckHttpEndpoint; - private boolean randomeRoute = false; - - public CloudApplicationDeploymentProperties() { - boundServices = new ArrayList<>(); - environmentVariables = new HashMap<>(); - buildpack = ""; - buildpacks = new ArrayList<>(); - instances = DeploymentProperties.DEFAULT_INSTANCES; - urls = new LinkedHashSet<>(); - appName = null; - project = null; - memory = DeploymentProperties.DEFAULT_MEMORY; - diskQuota = DeploymentProperties.DEFAULT_MEMORY; - manifestFile = null; - timeout = null; - command = null; - stack = null; - } - - public void setProject(IProject project) { - this.project = project; - } - - public IProject getProject() { - return project; - } - - public void setMemory(int memory) { - this.memory = memory; - } - - public int getMemory() { - return memory; - } - - public void setDiskQuota(int diskQuota) { - this.diskQuota = diskQuota; - } - - public int getDiskQuota() { - return diskQuota; - } - - public void setTimeout(Integer timeout) { - this.timeout = timeout; - } - - public Integer getTimeout() { - return timeout; - } - - public String getHealthCheckType() { - return healthCheckType; - } - - public void setHealthCheckType(String healthCheckType) { - this.healthCheckType = healthCheckType; - } - - public String getHealthCheckHttpEndpoint() { - return healthCheckHttpEndpoint; - } - - public void setHealthCheckHttpEndpoint(String hche) { - this.healthCheckHttpEndpoint = hche; - } - - public void setCommand(String command) { - this.command = command; - } - - public String getCommand() { - return command; - } - - public void setStack(String stack) { - this.stack = stack; - } - - public String getStack() { - return stack; - } - - public void setManifestFile(IFile file) { - this.manifestFile = file; - } - - public IFile getManifestFile() { - return this.manifestFile; - } - - /** - * Returns a copy of the list of URLs for the application - * - * @return never null - */ - public Set getUris() { - return urls; - } - - public void setUris(Collection urls) { - this.urls = urls == null ? new LinkedHashSet<>() : new LinkedHashSet<>(urls); - } - - public void setAppName(String appName) { - this.appName = appName; - } - - public String getAppName() { - return this.appName; - } - - public void setBuildpack(String buildpack) { - this.buildpack = buildpack; - } - - public void setServices(List services) { - /* - * List should be read/write accessible hence create new instance rather - * than use emptyList from Collections if null is passed in - */ - boundServices = services == null ? new ArrayList<>() : services; - } - - public void setBuildpacks(List buildpacks) { - this.buildpacks = buildpacks == null ? new ArrayList<>() : buildpacks; - } - - public void setInstances(int instances) { - this.instances = instances; - } - - public void setRandomRoute(boolean randomRoute) { - this.randomeRoute = randomRoute; - } - - public boolean getRandomRoute() { - return this.randomeRoute ; - } - - public void setEnvironmentVariables(Map environmentVariables) { - /* - * Map should be read/write accessible hence create new instance rather - * than use emptyMap from Collections if null is passed in - */ - this.environmentVariables = environmentVariables == null ? new HashMap<>() : environmentVariables; - } - - public String getBuildpack() { - return buildpack == null || buildpack.isEmpty() ? null : buildpack; - } - - @Override - public List getBuildpacks() { - return ImmutableList.copyOf(buildpacks); - } - - public int getInstances() { - return instances; - } - - /** - * @return never null - */ - public Map getEnvironmentVariables() { - return environmentVariables; - } - - /** - * - * @return never null - */ - public List getServices() { - return boundServices; - } - - public static CloudApplicationDeploymentProperties getFor(IProject project, CloudData cloudData, CFApplication app) { - - CloudApplicationDeploymentProperties properties = new CloudApplicationDeploymentProperties(); - - properties.setAppName(app == null ? project.getName() : app.getName()); - properties.setProject(project); - properties.setBuildpack(app == null ? cloudData.getBuildpack() : app.getBuildpackUrl()); - - /* - * TODO: Re-evaluate whether JAVA_OPTS need to be treated differently - * Boot Dash Tooling adds staff to JAVA-OPTS behind the scenes. Consider - * JAVA_OPTS env variable as the one not exposed to users - */ - Map env = new LinkedHashMap<>(); - if (app != null) { - env.putAll(app.getEnvAsMap()); - env.remove("JAVA_OPTS"); - } - - // PT 174076433 - Support deploying of Java 11 apps to CF - if (JavaProjectUtil.isJava11(project)) { - env.put("JBP_CONFIG_OPEN_JDK_JRE", "{ jre: { version: 11.+}}"); - } - - properties.setEnvironmentVariables(env); - - properties.setInstances(app == null ? 1 : app.getInstances()); - properties.setMemory(app == null ? DeploymentProperties.DEFAULT_MEMORY : app.getMemory()); - properties.setServices(app == null ? Collections.emptyList() : app.getServices()); - properties.setDiskQuota(app == null ? DeploymentProperties.DEFAULT_MEMORY : app.getDiskQuota()); - properties.setTimeout(app == null ? null : app.getTimeout()); - properties.setHealthCheckType(app==null ? null : app.getHealthCheckType()); - properties.setHealthCheckHttpEndpoint(app == null ? null : app.getHealthCheckHttpEndpoint()); - properties.setCommand(app == null ? null : app.getCommand()); - properties.setStack(app == null ? null : app.getStack()); - - if (app == null) { - CFRoute route = CFRoute.builder().host(project.getName()).domain(cloudData.getDefaultDomain()).build(); - properties.setUris(Collections.singletonList(route.getRoute())); - } else { - properties.setUris(app.getUris()); - } - return properties; - } - - public CFPushArguments toPushArguments(List cloudDomains) throws Exception { - Set uris = getUris(); - CFPushArguments args = new CFPushArguments(); - args.setRoutes(uris); - args.setAppName(getAppName()); - args.setMemory(getMemory()); - args.setDiskQuota(getDiskQuota()); - args.setTimeout(getTimeout()); - args.setHealthCheckType(getHealthCheckType()); - args.setHealthCheckHttpEndpoint(getHealthCheckHttpEndpoint()); - args.setBuildpack(getBuildpack()); - args.setCommand(getCommand()); - args.setStack(getStack()); - args.setEnv(getEnvironmentVariables()); - args.setInstances(getInstances()); - args.setServices(getServices()); - args.setApplicationData(getArchive()); - args.setRandomRoute(getRandomRoute()); - return args; - } - - public File getArchive() { - return archive; - } - - public void setArchive(File archive) { - this.archive = archive; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/CloudData.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/CloudData.java deleted file mode 100644 index 8d07ec8d0..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/CloudData.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Spring IDE Developers - * 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: - * Spring IDE Developers - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.deployment; - -import java.util.List; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFStack; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFDomainStatus; - -import com.google.common.collect.ImmutableList; - -public class CloudData { - - private List domains; - private String buildpack; - private List stacks; - - public CloudData(List domains, String buildpack, List stacks) { - this.domains = domains; - this.buildpack = buildpack; - this.stacks = stacks; - } - - public String getBuildpack() { - return buildpack; - } - - public List getDomains() { - if (domains!=null) { - return domains; - } - return ImmutableList.of(); - } - - public List getStacks() { - if (stacks!=null) { - return stacks; - } - return ImmutableList.of(); - } - - public String getDefaultDomain() { - return getDomains().stream() - .filter(d -> d.getStatus()==CFDomainStatus.SHARED && d.getType()==CFDomainType.HTTP) - .findFirst() - .map(d -> d.getName()) - .orElse(null); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/ManifestDiffDialog.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/ManifestDiffDialog.java deleted file mode 100644 index 2234be66d..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/ManifestDiffDialog.java +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.deployment; - -import org.eclipse.compare.CompareEditorInput; -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.dialogs.DialogSettings; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.dialogs.IMessageProvider; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel; -import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel.Result; - -/** - * Dialog to compare and merge manifest file with deployment properties from CF. - * Hosts eclipse's compare and merge editor composite. - * - * @author Alex Boyko - * - */ -public class ManifestDiffDialog extends TitleAreaDialog { - - protected final CompareEditorInput fCompareEditorInput; - private String title = "Merge Manifest File"; - - /** - * Create a dialog to host the given input. - * @param shell a shell - * @param input the dialog input - */ - public ManifestDiffDialog(Shell shell, ManifestDiffDialogModel model) { - super(shell); - CompareEditorInput input = model.getInput(); - setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX); - Assert.isNotNull(input); - fCompareEditorInput= input; - } - - public ManifestDiffDialog(Shell shell, ManifestDiffDialogModel model, String title) { - this(shell, model); - this.title = title; - } - - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.YES_ID, "Use Manifest", true); - createButton(parent, IDialogConstants.CANCEL_ID, fCompareEditorInput.getCancelButtonLabel(), false); - createButton(parent, IDialogConstants.NO_ID, "Forget Manifest", false); - } - - protected Control createDialogArea(Composite parent2) { - - Composite parent= (Composite) super.createDialogArea(parent2); - - Control c= fCompareEditorInput.createContents(parent); - c.setLayoutData(new GridData(GridData.FILL_BOTH)); - - Shell shell= c.getShell(); - shell.setText(fCompareEditorInput.getTitle()); - shell.setImage(fCompareEditorInput.getTitleImage()); - applyDialogFont(parent); - return parent; - } - - @Override - public void create() { - super.create(); - setTitle(title); - if (fCompareEditorInput != null && fCompareEditorInput.getMessage() != null) { - setMessage(fCompareEditorInput.getMessage(), IMessageProvider.WARNING); - } else { - setMessage( - "Manifest file deployment properties are different from current deployment properties on CF. Please merge changes if applicable.", - IMessageProvider.INFORMATION); - } - } - - protected void buttonPressed(int buttonId) { - switch (buttonId) { - case IDialogConstants.NO_ID: - fCompareEditorInput.cancelPressed(); - setReturnCode(buttonId); - close(); - break; - case IDialogConstants.YES_ID: - if (fCompareEditorInput.isDirty()) { - if (!fCompareEditorInput.okPressed()) - return; - } else { - fCompareEditorInput.cancelPressed(); - } - setReturnCode(buttonId); - close(); - break; - case IDialogConstants.CANCEL_ID: - fCompareEditorInput.cancelPressed(); - super.buttonPressed(buttonId); - break; - default: - super.buttonPressed(buttonId); - } - } - - protected IDialogSettings getDialogBoundsSettings() { - return DialogSettings.getOrCreateSection(BootDashActivator.getDefault().getDialogSettings(), "MergeManifestDialog"); - } - - /** - * Return the compare editor input for this dialog. - * @return the compare editor input for this dialog - */ - protected final CompareEditorInput getInput() { - return fCompareEditorInput; - } - - @Override - protected int getDialogBoundsStrategy() { - return DIALOG_PERSISTSIZE; - } - - public static Result getResultForCode(int buttonId) { - switch (buttonId) { - case IDialogConstants.NO_ID: - return Result.FORGET_MANIFEST; - case IDialogConstants.YES_ID: - return Result.USE_MANIFEST; - case IDialogConstants.CANCEL_ID: - return Result.CANCELED; - default: - throw new IllegalArgumentException("Unknown button ID"); - } - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/UnsupportedPushProperties.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/UnsupportedPushProperties.java deleted file mode 100644 index 7c5db2a26..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/UnsupportedPushProperties.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 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.cf.deployment; - -import java.util.List; - -import org.eclipse.core.runtime.OperationCanceledException; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; - -import com.google.common.collect.ImmutableList; - -public class UnsupportedPushProperties { - - - - public UnsupportedPushProperties() { - } - - /** - * Check for unsupported push properties in the given deployment properties. Either allow the - * caller of this check to continue if unsupported properties are found, or - * cancel. If no unsupported properties are found, nothing happens. - * - * @param ui - * @param cde - * @param deploymentProperties - * @throws OperationCanceledException if operation is cancelled - */ - public void allowOrCancelIfFound(UserInteractions ui, - CloudApplicationDeploymentProperties deploymentProperties) throws OperationCanceledException { - List unsupportedProperties = findUnsupportedProperties(deploymentProperties); - if (!unsupportedProperties.isEmpty()) { - StringBuilder builder = new StringBuilder(); - builder.append( - "The following properties are not currently supported when pushing an application to Cloud Foundry. These properties will be ignored. Continue with deployment?"); - builder.append('\n'); - - for (String prop : unsupportedProperties) { - builder.append('\n'); - builder.append("- "); - builder.append(prop); - } - if (!ui.confirmOperation("Unsupported Push Properties", builder.toString())) { - throw new OperationCanceledException(); - } - } - } - - /** - * Check the given deployment properties for unsupported properties. Return - * properties found that are unsupported, or empty list if nothing is found. - * - * @param properties - * @return - */ - public List findUnsupportedProperties(CloudApplicationDeploymentProperties properties) { - if (properties != null) { - if (properties.getBuildpacks() != null && !properties.getBuildpacks().isEmpty()) { - return ImmutableList.of("buildpacks"); - } - } - return ImmutableList.of(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/YamlGraphDeploymentProperties.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/YamlGraphDeploymentProperties.java deleted file mode 100644 index 0642a03e9..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/deployment/YamlGraphDeploymentProperties.java +++ /dev/null @@ -1,1496 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 2018 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.cf.deployment; - -import java.io.ByteArrayInputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.text.edits.DeleteEdit; -import org.eclipse.text.edits.MultiTextEdit; -import org.eclipse.text.edits.ReplaceEdit; -import org.eclipse.text.edits.TextEdit; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFRoute; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentProperties; -import org.springframework.ide.eclipse.boot.util.Log; -import org.springframework.ide.eclipse.editor.support.reconcile.IProblemCollector; -import org.springframework.ide.eclipse.editor.support.yaml.ast.NodeMergeSupport; -import org.springframework.ide.eclipse.editor.support.yaml.ast.NodeUtil; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.DumperOptions.FlowStyle; -import org.yaml.snakeyaml.DumperOptions.LineBreak; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.composer.Composer; -import org.yaml.snakeyaml.constructor.Constructor; -import org.yaml.snakeyaml.constructor.SafeConstructor; -import org.yaml.snakeyaml.nodes.MappingNode; -import org.yaml.snakeyaml.nodes.Node; -import org.yaml.snakeyaml.nodes.NodeTuple; -import org.yaml.snakeyaml.nodes.ScalarNode; -import org.yaml.snakeyaml.nodes.SequenceNode; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.parser.ParserImpl; -import org.yaml.snakeyaml.reader.StreamReader; -import org.yaml.snakeyaml.representer.Representer; -import org.yaml.snakeyaml.resolver.Resolver; - -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -/** - * Deployment properties based on YAML Graph. Instance of this class has ability - * to compute text differences between this instance and deployment properties - * passed as parameter - * - * @author Alex Boyko - * - */ -public class YamlGraphDeploymentProperties implements DeploymentProperties { - - private String content; - private MappingNode appNode; - private Node root; - private SequenceNode applicationsValueNode; - private Yaml yaml; - private CloudData cloudData; - - public YamlGraphDeploymentProperties(String content, String appName, CloudData cloudData) { - super(); - this.appNode = null; - this.applicationsValueNode = null; - this.root = null; - this.cloudData = cloudData; - this.content = content; - initializeYaml(appName); - } - - private void initializeYaml(String appName) { - Composer composer = new Composer(new ParserImpl(new StreamReader(new InputStreamReader(new ByteArrayInputStream(content.getBytes())))), new Resolver()); - root = composer.getSingleNode(); - - NodeMergeSupport mergeSupport = new NodeMergeSupport(IProblemCollector.NULL); - mergeSupport.mergeAll(root); - - Node apps = YamlGraphDeploymentProperties.findValueNode(root, "applications"); - if (apps instanceof SequenceNode) { - applicationsValueNode = (SequenceNode) apps; - appNode = findAppNode(applicationsValueNode, appName); - } else if (root instanceof MappingNode) { - appNode = (MappingNode) root; - } - - DumperOptions options = createDumperOptions(); - this.yaml = new Yaml(new SafeConstructor(), new Representer(options), options); - } - - private static MappingNode findAppNode(SequenceNode seq, String name) { - if (name != null) { - for (Node n : seq.getValue()) { - Node nameValue = findValueNode(n, ApplicationManifestHandler.NAME_PROP); - if (nameValue instanceof ScalarNode && ((ScalarNode)nameValue).getValue().equals(name)) { - return (MappingNode) n; - } - } - } - return null; - } - - @Override - public String getYamlContent() { - return content; - } - - public static DumperOptions createDumperOptions() { - DumperOptions options = new DumperOptions(); - options.setExplicitStart(false); - options.setCanonical(false); - options.setPrettyFlow(true); - options.setDefaultFlowStyle(FlowStyle.BLOCK); - options.setLineBreak(LineBreak.getPlatformLineBreak()); - return options; - } - - @SuppressWarnings("unchecked") - static public T getNode(Node node, String key, Class type) { - Node n = findValueNode(node, key); - if (n != null && type.isAssignableFrom(n.getClass())) { - return (T) n; - } - return null; - } - - @Override - public String getAppName() { - /* - * Name must be located in the app node! - */ - return getPropertyValue(appNode, ApplicationManifestHandler.NAME_PROP, String.class); - } - - @Override - public int getMemory() { - String memoryStringValue = getAbsoluteValue(ApplicationManifestHandler.MEMORY_PROP, String.class); - if (memoryStringValue != null) { - try { - return ApplicationManifestHandler.convertMemory(memoryStringValue); - } catch (CoreException e) { - Log.log(e); - } - } - return DeploymentProperties.DEFAULT_MEMORY; - } - - public String getInheritFilePath() { - return getPropertyValue(root, ApplicationManifestHandler.INHERIT_PROP, String.class); - } - - @Override - public String getBuildpack() { - return getAbsoluteValue(ApplicationManifestHandler.BUILDPACK_PROP, String.class); - } - - @SuppressWarnings("unchecked") - @Override - public Map getEnvironmentVariables() { - Map map = getAbsoluteValue(ApplicationManifestHandler.ENV_PROP, Map.class); - return map == null ? Collections.emptyMap() : map; - } - - @Override - public int getInstances() { - Integer n = getAbsoluteValue(ApplicationManifestHandler.INSTANCES_PROP, Integer.class); - return n == null ? DeploymentProperties.DEFAULT_INSTANCES : n.intValue(); - } - - @Override - public Integer getTimeout() { - return getAbsoluteValue(ApplicationManifestHandler.TIMEOUT_PROP, Integer.class); - } - - @Override - public String getCommand() { - return getAbsoluteValue(ApplicationManifestHandler.COMMAND_PROP, String.class); - } - - @Override - public String getHealthCheckType() { - return getAbsoluteValue(ApplicationManifestHandler.HEALTH_CHECK_TYPE_PROP, String.class); - } - - @Override - public String getHealthCheckHttpEndpoint() { - return getAbsoluteValue(ApplicationManifestHandler.HEALTH_CHECK_HTTP_ENDPOINT_PROP, String.class); - } - - @Override - public String getStack() { - return getAbsoluteValue(ApplicationManifestHandler.STACK_PROP, String.class); - } - - @SuppressWarnings("unchecked") - @Override - public List getServices() { - List services = getAbsoluteValue(ApplicationManifestHandler.SERVICES_PROP, List.class); - return services == null ? Collections.emptyList() : services; - } - - public static Node findValueNode(Node node, String key) { - return NodeUtil.getProperty(node, key); - } - - public static NodeTuple findNodeTuple(MappingNode mapping, String key) { - if (mapping != null) { - for (NodeTuple tuple : mapping.getValue()) { - if (tuple.getKeyNode() instanceof ScalarNode) { - ScalarNode scalar = (ScalarNode) tuple.getKeyNode(); - if (key.equals(scalar.getValue())) { - return tuple; - } - } - } - } - return null; - } - - private ReplaceEdit addLineBreakIfMissing(int index) { - int i = index - 1; - for (; i >= 0 && Character.isWhitespace(content.charAt(i)) && content.charAt(i) != '\n'; i--); - if (i > 0 && content.charAt(i) != '\n') { - return new ReplaceEdit(index, 0, System.lineSeparator()); - } - return null; - } - - public MultiTextEdit getDifferences(DeploymentProperties props) { - MultiTextEdit edits = new MultiTextEdit(); - TextEdit edit; - - if (appNode == null) { - Map obj = ApplicationManifestHandler.toYaml(props, cloudData, isLegacyHostDomainManifestYaml(root)); - if (applicationsValueNode == null) { - DumperOptions options = new DumperOptions(); - options.setExplicitStart(true); - options.setCanonical(false); - options.setPrettyFlow(true); - options.setDefaultFlowStyle(FlowStyle.BLOCK); - options.setLineBreak(LineBreak.getPlatformLineBreak()); - edits.addChild(new ReplaceEdit(0, content.length(), new Yaml(new SafeConstructor(), new Representer(options), options).dump(obj))); - } else { - edit = addLineBreakIfMissing(applicationsValueNode.getEndMark().getIndex()); - if (edit != null) { - edits.addChild(edit); - } - @SuppressWarnings("unchecked") - /* - * Find the appropriate application Object in the list. - */ - List appsObj = (List) obj.get(ApplicationManifestHandler.APPLICATIONS_PROP); - Object appObject = appsObj.get(0); - for (Object entry : appsObj) { - if (entry instanceof Map && Objects.equal(props.getAppName(), ((Map)entry).get(ApplicationManifestHandler.NAME_PROP))) { - appObject = entry; - break; - } - } - edits.addChild(new ReplaceEdit(applicationsValueNode.getEndMark().getIndex(), 0, serializeListEntry(appObject, applicationsValueNode.getStartMark().getColumn()).toString())); - } - } else { - if (!Objects.equal(getAppName(), props.getAppName())) { - edit = createEdit(appNode, props.getAppName(), ApplicationManifestHandler.NAME_PROP); - if (edit != null) { - edits.addChild(edit); - } - } - - /* - * Compare value because strings may have 'G', 'M' etc post-fixes - */ - if (getMemory() != props.getMemory()) { - edit = createEdit(appNode, String.valueOf(props.getMemory()) + "M", ApplicationManifestHandler.MEMORY_PROP); - if (edit != null) { - edits.addChild(edit); - } - } - - if (getInstances() != props.getInstances()) { - getDifferenceForEntry(edits, ApplicationManifestHandler.INSTANCES_PROP, props.getInstances(), DEFAULT_INSTANCES, Integer.class); - } - - if (!Objects.equal(getTimeout(), props.getTimeout())) { - getDifferenceForEntry(edits, ApplicationManifestHandler.TIMEOUT_PROP, props.getTimeout(), null, Integer.class); - } - - if (!Objects.equal(getHealthCheckType(), props.getHealthCheckType())) { - getDifferenceForEntry(edits, ApplicationManifestHandler.HEALTH_CHECK_TYPE_PROP, props.getHealthCheckType(), - DeploymentProperties.DEFAULT_HEALTH_CHECK_TYPE, String.class); - } - - if (!Objects.equal(getHealthCheckHttpEndpoint(), props.getHealthCheckHttpEndpoint())) { - getDifferenceForEntry(edits, ApplicationManifestHandler.HEALTH_CHECK_HTTP_ENDPOINT_PROP, props.getHealthCheckHttpEndpoint(), - DeploymentProperties.DEFAULT_HEALTH_CHECK_HTTP_ENDPOINT, String.class); - } - - if (!Objects.equal(getCommand(), props.getCommand())) { - getDifferenceForEntry(edits, ApplicationManifestHandler.COMMAND_PROP, props.getCommand(), null, String.class); - } - - /* - * Only if 'stack' attribute is present in the manifest perform the comparison - */ - if (getStack() != null && !getStack().equals(props.getStack())) { - getDifferenceForEntry(edits, ApplicationManifestHandler.STACK_PROP, props.getStack(), null, String.class); - } - - if (getDiskQuota() != props.getDiskQuota()) { - edit = createEdit(appNode, String.valueOf(props.getDiskQuota()) + "M", ApplicationManifestHandler.DISK_QUOTA_PROP); - if (edit != null) { - edits.addChild(edit); - } - } - - if (!Objects.equal(getBuildpack(), props.getBuildpack())) { - edit = createEdit(appNode, props.getBuildpack(), ApplicationManifestHandler.BUILDPACK_PROP); - if (edit != null) { - edits.addChild(edit); - } - } - - if (!new HashSet<>(getServices()).equals(new HashSet<>(props.getServices()))) { - getDifferencesForList(edits, ApplicationManifestHandler.SERVICES_PROP, props.getServices(), String.class); - } - - if (!getEnvironmentVariables().equals(props.getEnvironmentVariables())) { - getDifferencesForMap(edits, ApplicationManifestHandler.ENV_PROP, props.getEnvironmentVariables()); - } - - /* - * If any text edits are produced then there are differences in the URIs - */ - Set currentUris = getUris(); - Set otherUris = props.getUris(); - if (!isRandomRouteMatch(currentUris, otherUris) && !currentUris.equals(otherUris)) { - if (isLegacyHostDomainManifestYaml(root)) { - getLegacyDifferenceForUris(otherUris, edits); - } else { - getDifferenceForUris(otherUris, edits); - } - } - } - return edits.hasChildren() ? edits : null; - } - - private boolean isRandomRouteMatch(Set currentUris, Set otherUris) { - if (currentUris.size() == 1 && otherUris.size() == 1) { - String uri = currentUris.iterator().next(); - String host = uri.substring(0, uri.indexOf('.')); - return ApplicationManifestHandler.RANDOM_VAR.equals(host); - } - return false; - } - - /** - * Creates diff text edits for entry in the map node given by the - * attribute's name based on its new value and type as well as the default - * value that is not serialized under normal circumstances - * - * @param me - * container to append text edits - * @param key - * manifest attribute name - * @param newValue - * the new value to create diff edits for - * @param defaultValue - * the default value for the attribute that is usually not - * serialized - * @param type - * type of the value for the attribute - */ - private void getDifferenceForEntry(MultiTextEdit me, String key, T newValue, T defaultValue, Class type) { - TextEdit edit = null; - if (Objects.equal(newValue, defaultValue)) { - /* - * New value is the default value. Check if entry can be safely removed from YAML - */ - T rootValue = getPropertyValue(root, key, type); - if (appNode != root && rootValue != null) { - if (newValue == null) { - me.addChild(createEdit((MappingNode)root, (Object) null, key)); - for (Node n : applicationsValueNode.getValue()) { - if (n instanceof MappingNode) { - MappingNode application = (MappingNode) n; - if (application == appNode) { - edit = createEdit(appNode, (Object) null, key); - if (edit != null) { - me.addChild(edit); - } - } else { - T appValue = getPropertyValue(application, key, type); - if (appValue == null) { - me.addChild(createEdit(application, rootValue, key)); - } - } - } - } - } else { - edit = createEdit(appNode, newValue, key); - if (edit != null) { - me.addChild(edit); - } - } - } else { - edit = createEdit(appNode, (T) null, key); - if (edit != null) { - me.addChild(edit); - } - } - } else { - /* - * New value is not default hence it have to be serialized and - * therefore would override the value in the root node for the same - * attribute - */ - edit = createEdit(appNode, newValue, key); - if (edit != null) { - me.addChild(edit); - } - } - } - - /** - * Creates text edits based on differences between current manifest - * attribute list value and the passed new list value. The manifest - * attribute value is considered to be defined either on the application or - * the root node of the manifest YAML and text edit is calculated - * accordingly. It also supports multiple apps defined in the manifest - * - * @param me - * multi text edit gathering all edits - * @param key - * manifest attribute name - * @param newValue - * the new value to set - */ - @SuppressWarnings("unchecked") - private void getDifferencesForList(MultiTextEdit me, String key, List newValue, Class type) { - TextEdit edit; - /* - * Moved new value entries in the set to avoid duplication - */ - LinkedHashSet otherValue = new LinkedHashSet<>(newValue); - /* - * Get the list value from the root node - */ - List rootList = root != appNode ? getPropertyValue(root, key, List.class) : Collections.emptyList(); - if (rootList == null) { - rootList = Collections.emptyList(); - } - if (otherValue.containsAll(rootList)) { - /* - * All list entries from the root are present in the new value - */ - otherValue.removeAll(rootList); - /* - * Create an edit for a difference between the remaining list of - * values and current app's node list - */ - edit = createEdit(appNode, new ArrayList<>(otherValue), key, type); - if (edit != null) { - me.addChild(edit); - } - } else { - /* - * Some list entries from the root are missing move all root values - * to application nodes. Applications value node must be present - * because rootList wasn't empty since we got here - */ - for (Node n : applicationsValueNode.getValue()) { - if (n instanceof MappingNode) { - MappingNode application = (MappingNode) n; - if (n == appNode) { - /* - * Current app node - */ - edit = createEdit(application, newValue, key, type); - if (edit != null) { - me.addChild(edit); - } - } else { - /* - * Any other app node. Get its list value for the attribute - */ - List currentValues = getPropertyValue(application, key, List.class); - if (currentValues == null) { - /* - * There is no value for the property so just create an edit for the list from the root - */ - edit = createEdit(application, rootList, key, type); - } else { - /* - * Create a joint list of values from app's node list value and root node list value - */ - LinkedHashSet values = new LinkedHashSet<>(currentValues); - values.addAll(rootList); - /* - * Create and edit with the new value being the joint list - */ - edit = createEdit(application, new ArrayList<>(values), key, type); - } - if (edit != null) { - me.addChild(edit); - } - } - } - } - /* - * Remove the list from the root node - */ - edit = createEdit((MappingNode)root, (Object)null, key); - if (edit != null) { - me.addChild(edit); - } - } - } - - /** - * Creates text edits based on differences between current manifest - * attribute map value and the passed new map value. The manifest - * attribute value is considered to be defined either on the application or - * the root node of the manifest YAML and text edit is calculated - * accordingly. It also supports multiple apps defined in the manifest - * - * @param me - * multi text edit gathering all edits - * @param key - * manifest attribute name - * @param newValue - * the new value to set - */ - @SuppressWarnings("unchecked") - private void getDifferencesForMap(MultiTextEdit me, String key, Map newValue) { - TextEdit edit; - /* - * Get the map value from the root node - */ - Map rootMap = root != appNode ? getPropertyValue(root, key, Map.class) : Collections.emptyMap(); - /* - * Copy the new value to leave it unchanged - */ - LinkedHashMap otherValue = new LinkedHashMap<>(newValue); - if (rootMap == null) { - rootMap = Collections.emptyMap(); - } - if (otherValue.keySet().containsAll(rootMap.keySet())) { - /* - * All map entries from the root are present in the new value - */ - for (String k : rootMap.keySet()) { - if (Objects.equal(otherValue.get(k), rootMap.get(k))) { - otherValue.remove(k); - } - } - /* - * Create an edit for a difference between the remaining map and - * current app's node map - */ - edit = createEdit(appNode, otherValue, key); - if (edit != null) { - me.addChild(edit); - } - } else { - /* - * Some map entries from the root must be removed. Move root node map to applications. - * Applications value node must be present because rootList wasn't empty since we got here. - */ - for (Node n : applicationsValueNode.getValue()) { - if (n instanceof MappingNode) { - MappingNode application = (MappingNode) n; - if (n == appNode) { - /* - * Current app node - */ - edit = createEdit(application, newValue, key); - if (edit != null) { - me.addChild(edit); - } - } else { - /* - * Any other app node. Get its map value for the attribute - */ - Map currentValues = getPropertyValue(application, key, Map.class); - if (currentValues == null) { - /* - * There is no value for the property so just create an edit for the map from the root - */ - edit = createEdit(application, rootMap, key); - } else { - /* - * Create a joint map of entries from app's node map value and root node map value - */ - for (Map.Entry entry : rootMap.entrySet()) { - if (!currentValues.containsKey(entry.getKey())) { - currentValues.put(entry.getKey(), entry.getValue()); - } - } - /* - * Create and edit with the new value being the joint map - */ - edit = createEdit(application, currentValues, key); - } - if (edit != null) { - me.addChild(edit); - } - } - } - } - /* - * Remove the list from the root node - */ - edit = createEdit((MappingNode)root, Collections.emptyMap(), key); - if (edit != null) { - me.addChild(edit); - } - - } - } - - private void getDifferenceForUris(Collection uris, MultiTextEdit me) { - Boolean randomRoute = getAbsoluteValue(ApplicationManifestHandler.RANDOM_ROUTE_PROP, Boolean.class); - Boolean noRoute = getAbsoluteValue(ApplicationManifestHandler.NO_ROUTE_PROP, Boolean.class); - boolean otherNoRoute = uris.isEmpty(); - boolean match = false; - - if (otherNoRoute) { - if (!Boolean.TRUE.equals(noRoute)) { - getDifferenceForEntry(me, ApplicationManifestHandler.NO_ROUTE_PROP, true, false, Boolean.class); - - if (getPropertyValue(appNode, ApplicationManifestHandler.RANDOM_ROUTE_PROP, Boolean.class) != null) { - me.addChild(createEdit(appNode, (String) null, ApplicationManifestHandler.RANDOM_ROUTE_PROP)); - } - } else { - match = true; - } - } else { - if (Boolean.TRUE.equals(noRoute)) { - getDifferenceForEntry(me, ApplicationManifestHandler.NO_ROUTE_PROP, false, false, Boolean.class); - } - - if (Boolean.TRUE.equals(randomRoute) && uris.size() == 1 && getAbsoluteValue(ApplicationManifestHandler.ROUTES_PROP, Map.class) == null) { - match = true; - } else if (getPropertyValue(appNode, ApplicationManifestHandler.RANDOM_ROUTE_PROP, Boolean.class) != null) { - me.addChild(createEdit(appNode, (String) null, ApplicationManifestHandler.RANDOM_ROUTE_PROP)); - } - } - - if (!match) { - getDifferencesForList(me, ApplicationManifestHandler.ROUTES_PROP, uris.stream().map(uri -> { - Map routeObj = new LinkedHashMap<>(); - routeObj.put(ApplicationManifestHandler.ROUTE_PROP, uri); - return routeObj; - }).collect(Collectors.toList()), Map.class); - } - - } - - private void getLegacyDifferenceForUris(Collection uris, MultiTextEdit me) { - List domains = cloudData.getDomains(); - - LinkedHashSet otherHosts = new LinkedHashSet<>(); - LinkedHashSet otherDomains = new LinkedHashSet<>(); - ApplicationManifestHandler.extractHostsAndDomains(uris, domains, otherHosts, otherDomains); - boolean otherNoRoute = otherHosts.isEmpty() && otherDomains.isEmpty(); - boolean otherNoHostname = otherHosts.isEmpty() && !otherDomains.isEmpty(); - - LinkedHashSet currentHosts = new LinkedHashSet<>(); - LinkedHashSet currentDomains = new LinkedHashSet<>(); - - /* - * Gather hosts from "host" and "hosts" attributes from app and root nodes - */ - String host = getAbsoluteValue(ApplicationManifestHandler.SUB_DOMAIN_PROP, String.class); - if (host != null) { - currentHosts.add(host); - } - List hostsList = getAbsoluteValue(ApplicationManifestHandler.SUB_DOMAINS_PROP, List.class); - if (hostsList != null) { - for (Object o : hostsList) { - if (o instanceof String) { - currentHosts.add((String) o); - } - } - } - - /* - * Gather domains from 'domain' and 'domains' attributes from app and root nodes - */ - String domain = getAbsoluteValue(ApplicationManifestHandler.DOMAIN_PROP, String.class); - if (domain != null) { - currentDomains.add(domain); - } - List domainsList = getAbsoluteValue(ApplicationManifestHandler.DOMAINS_PROP, List.class); - if (domainsList != null) { - for (Object o : domainsList) { - if (o instanceof String) { - currentDomains.add((String) o); - } - } - } - - boolean match = false; - Boolean noHost = getAbsoluteValue(ApplicationManifestHandler.NO_HOSTNAME_PROP, Boolean.class); - Boolean randomRoute = getAbsoluteValue(ApplicationManifestHandler.RANDOM_ROUTE_PROP, Boolean.class); - Boolean noRoute = getAbsoluteValue(ApplicationManifestHandler.NO_ROUTE_PROP, Boolean.class); - - if (otherNoRoute) { - if (!Boolean.TRUE.equals(noRoute)) { - getDifferenceForEntry(me, ApplicationManifestHandler.NO_ROUTE_PROP, true, false, Boolean.class); - - if (getPropertyValue(appNode, ApplicationManifestHandler.NO_HOSTNAME_PROP, Boolean.class) != null) { - me.addChild(createEdit(appNode, (String) null, ApplicationManifestHandler.NO_HOSTNAME_PROP)); - } - - if (getPropertyValue(appNode, ApplicationManifestHandler.RANDOM_ROUTE_PROP, Boolean.class) != null) { - me.addChild(createEdit(appNode, (String) null, ApplicationManifestHandler.RANDOM_ROUTE_PROP)); - } - } else { - match = true; - } - } else { - if (Boolean.TRUE.equals(noRoute)) { - getDifferenceForEntry(me, ApplicationManifestHandler.NO_ROUTE_PROP, false, false, Boolean.class); - } - - if (otherNoHostname) { - if (!Boolean.TRUE.equals(noHost)) { - me.addChild(createEdit(appNode, Boolean.TRUE, ApplicationManifestHandler.NO_HOSTNAME_PROP)); - } - } else { - /* - * There is at least a host in the deployment properties. Remove - * "no-hostname" attribute if there is one from the application - * node. Don't care if it's in the root or anywhere else - */ - if (getPropertyValue(appNode, ApplicationManifestHandler.NO_HOSTNAME_PROP, Boolean.class) != null) { - me.addChild(createEdit(appNode, (String) null, ApplicationManifestHandler.NO_HOSTNAME_PROP)); - } - } - - if (Boolean.TRUE.equals(randomRoute) && otherHosts.size() == 1 && otherDomains.size() == 1 && currentHosts.isEmpty()) { - match = true; - } else if (getPropertyValue(appNode, ApplicationManifestHandler.RANDOM_ROUTE_PROP, Boolean.class) != null) { - me.addChild(createEdit(appNode, (String) null, ApplicationManifestHandler.RANDOM_ROUTE_PROP)); - } - - if (currentHosts.isEmpty() && !Boolean.TRUE.equals(noHost)) { - currentHosts.add(getAppName()); - } - - if (currentDomains.isEmpty() && !domains.isEmpty()) { - currentDomains.add(cloudData.getDefaultDomain()); - } - } - - if (!match && (!currentHosts.equals(otherHosts) || !currentDomains.equals(otherDomains))) { - generateEditForHostsAndDomains(me, currentHosts, currentDomains, otherHosts, otherDomains); - } - - } - - private void generateEditForHostsAndDomains(MultiTextEdit me, Set currentHosts, Set currentDomains, Set otherHosts, Set otherDomains) { - /* - * Calculate current 'host' attrbute value - */ - String host = getAbsoluteValue(ApplicationManifestHandler.SUB_DOMAIN_PROP, String.class); - if (otherHosts.size() == 1) { - /* - * Only one host for deployment props - */ - String otherHost = otherHosts.iterator().next(); - /* - * If calculated host is different from deployment props create edit - */ - if (host == null || !otherHost.equals(host)) { - getDifferenceForEntry(me, ApplicationManifestHandler.SUB_DOMAIN_PROP, otherHost, null, String.class); - } - /* - * Ensure the deployment props hosts are empty since the difference has been dealt with here - */ - otherHosts.clear(); - } else { - /* - * Deployment props have more than one host. - * Check if current "host" attribute value is one of the hosts from deployment props - */ - if (host != null && !otherHosts.remove(host)) { - /* - * If current 'host' attribute value is not contained in - * deployment props hosts then ensure "host" attribute value is - * cleared - */ - getDifferenceForEntry(me, ApplicationManifestHandler.SUB_DOMAIN_PROP, null, null, String.class); - } - } - /* - * Calculate edit for hosts list - */ - getDifferencesForList(me, ApplicationManifestHandler.SUB_DOMAINS_PROP, new ArrayList<>(otherHosts), String.class); - - /* - * Calculate current 'domain' attribute value - */ - String domain = getAbsoluteValue(ApplicationManifestHandler.DOMAIN_PROP, String.class); - if (otherDomains.size() == 1) { - /* - * Only one domain for deployment props - */ - String otherDomain = otherDomains.iterator().next(); - /* - * If calculated domain is different from deployment props create edit - */ - if (domain == null || !otherDomain.equals(domain)) { - getDifferenceForEntry(me, ApplicationManifestHandler.DOMAIN_PROP, otherDomain, null, String.class); - } - /* - * Ensure the deployment props domains are empty since the difference has been dealt with here - */ - otherDomains.clear(); - } else { - /* - * Deployment props have more than one domain. - * Check if current "domain" attribute value is one of the domains from deployment props - */ - if (domain != null && !otherDomains.remove(domain)) { - /* - * If current 'domain' attribute value is not contained in - * deployment props domains then ensure "domain" attribute value is - * cleared - */ - getDifferenceForEntry(me, ApplicationManifestHandler.DOMAIN_PROP, null, null, String.class); - } - } - /* - * Calculate edit for domains list - */ - getDifferencesForList(me, ApplicationManifestHandler.DOMAINS_PROP, new ArrayList<>(otherDomains), String.class); - } - - /** - * Creates text edit for mapping node tuples where property and value are - * scalars (i.e. value is either string or some primitive type) - * - * @param parent - * the parent MappingNode - * @param otherValue - * the new value for the tuple - * @param property - * tuple's key - * @return the text edit - */ - private TextEdit createEdit(MappingNode parent, Object otherValue, String property) { - NodeTuple tuple = findNodeTuple(parent, property); - if (tuple == null) { - if (otherValue != null) { - StringBuilder serializedValue = serialize(property, otherValue); - boolean[] postIndent = new boolean[] { true }; - int position = positionToAppendAt(parent, postIndent); - if (postIndent[0]) { - postIndent(serializedValue, getDefaultOffset()); - } else { - preIndent(serializedValue, getDefaultOffset()); - } - return new ReplaceEdit(position, 0, serializedValue.toString()); - } - } else { - if (otherValue == null) { - /* - * Delete the tuple including the line break if possible - */ - int start = tuple.getKeyNode().getStartMark().getIndex(); - int end = tuple.getValueNode().getEndMark().getIndex(); - /* - * k1: v1 - * k-delete: v-delete - * ^ ^ - * start index end index - * k2: v2 - * - * Extend end index to position of k2 and leave start index where it was with correct indent - * - * However, if it' the last tuple in the map than just delete it and leave the line with the indent in the beginning for now. - */ - if (parent.getValue().get(parent.getValue().size() - 1) != tuple) { - for (; end > 0 && end < content.length() && Character.isWhitespace(content.charAt(end)); end++); - } - return new DeleteEdit(start, end - start); - } else { - /* - * Replace the current value (whether it's a scalr value or anything else without affecting the white space - */ - return new ReplaceEdit(tuple.getValueNode().getStartMark().getIndex(), tuple.getValueNode().getEndMark().getIndex() - tuple.getValueNode().getStartMark().getIndex(), String.valueOf(otherValue)); -// return createReplaceEditWithoutWhiteSpace(tuple.getValueNode().getStartMark().getIndex(), tuple.getValueNode().getEndMark().getIndex() - 1, -// String.valueOf(otherValue)); - } - } - return null; - } - - /** - * Calculates position to append entries to the map node. Also provides a - * hint on how to properly append entries. If entries are to be appended - * after the last entry in the map node then they need to be all - * pre-indented, and post-indented otherwise - * - * @param m the map node - * @param postIndent the post- or pre- indent calculated hint - * @return the index to append entries - */ - private int positionToAppendAt(MappingNode m, boolean[] postIndent) { - /* - * Check if there is a name attribute in the map node (case of application node) and make the end index of tha 'name: XXX' tuple as the index to append - */ - for (NodeTuple tuple : m.getValue()) { - if (tuple.getKeyNode() instanceof ScalarNode - && ApplicationManifestHandler.NAME_PROP.equals(((ScalarNode) tuple.getKeyNode()).getValue())) { - int index = tuple.getValueNode().getEndMark().getIndex(); - for (; index > 0 && index < content.length() && Character.isWhitespace(content.charAt(index)); index++) - ; - postIndent[0] = m.getValue().get(m.getValue().size() - 1) != tuple; - return index; - } - } - postIndent[0] = true; - return m.getStartMark().getIndex(); - } - - private TextEdit createEdit(MappingNode parent, List otherValue, String property, Class type) { - NodeTuple tuple = findNodeTuple(parent, property); - if (tuple == null) { - if (otherValue != null && !otherValue.isEmpty()) { - StringBuilder serializedValue = serialize(property, otherValue); -// postIndent(serializedValue, getDefaultOffset()); -// int position = positionToAppendAt(parent); - boolean[] postIndent = new boolean[] { true }; - int position = positionToAppendAt(parent, postIndent); - if (postIndent[0]) { - postIndent(serializedValue, getDefaultOffset()); - } else { - preIndent(serializedValue, getDefaultOffset()); - } - return new ReplaceEdit(position, 0, serializedValue.toString()); - } - } else { - if (otherValue == null || otherValue.isEmpty()) { - int start = tuple.getKeyNode().getStartMark().getIndex(); - int end = tuple.getValueNode().getEndMark().getIndex(); -// int index = parent.getValue().indexOf(tuple); -// if (!(index > 0 && parent.getValue().get(index - 1).getValueNode() instanceof CollectionNode)) { -// /* -// * If previous tuple is not a map or list then try to remove the preceding line break -// */ -// for (; start > 0 && Character.isWhitespace(content.charAt(start - 1)) && content.charAt(start - 1) != '\n'; start--); -// } - for (; end > 0 && end < content.length() && Character.isWhitespace(content.charAt(end)); end++); - - return new DeleteEdit(start, end - start); - } else { - Node sequence = tuple.getKeyNode(); - if (tuple.getValueNode() instanceof SequenceNode) { - SequenceNode sequenceValue = (SequenceNode) tuple.getValueNode(); - MultiTextEdit me = new MultiTextEdit(); - Set others = new LinkedHashSet<>(); - others.addAll(otherValue); - - /* - * Remember the ending position of the last entry that remains in the list - */ - int appendIndex = sequenceValue.getEndMark().getIndex(); - for (int index = 0; index < sequenceValue.getValue().size(); index++) { - Node n = sequenceValue.getValue().get(index); - T value = getValue(n, type); - if (others.contains(value)) { - // Entry exists, do nothing, just update the end position to append the missing entries - others.remove(value); - appendIndex = n.getEndMark().getIndex(); - } else { - /* - * skip "- " prefix for the start position - */ - int start = n.getStartMark().getIndex(); - for (; start > 0 && content.charAt(start) != '-' && content.charAt(start) != '\n'; start--); - int end = n.getEndMark().getIndex(); - - // If entry is object in the list don't remove the indent for the next entry in YAML (if there is a next YAML entry) - /* - * - e: entry-1 - * ^-start - * - e: entry-2 - * ^-end - */ - if (n instanceof MappingNode && root.getEndMark().getIndex() != end) { - if (parent.getEndMark().getIndex() == n.getEndMark().getIndex()) { - // last entry in the list but not the last yaml piece in the document - end -= (parent.getStartMark().getColumn() - appNode.getStartMark().getColumn()); - } else { - end -= sequenceValue.getStartMark().getColumn(); - } - } - /* - * "- entry" start=2, end=7, need to include '\n' in the deletion - */ - DeleteEdit deleteEdit = createDeleteEditIncludingLine(start, end); - appendIndex = deleteEdit.getOffset(); - me.addChild(deleteEdit); - } - } - /* - * TODO: verify that further appendIndex manipulations are necessary! - */ - /* - * Offset appendIndex to leave the line break for the previous entry in place. jump over spacing and line break. - */ - for (; appendIndex > 0 && appendIndex < content.length() && Character.isWhitespace(content.charAt(appendIndex)) && content.charAt(appendIndex - 1) != '\n'; appendIndex++); - /* - * Add a line break if append index is not starting right after line break. - */ - if (!others.isEmpty() && content.charAt(appendIndex - 1) != '\n') { - me.addChild(new ReplaceEdit(appendIndex, 0, System.lineSeparator())); - } - - /* - * Add missing entries - */ - for (T s : others) { - me.addChild(new ReplaceEdit(appendIndex, 0, serializeListEntry(s, sequenceValue.getStartMark().getColumn()).toString())); - } - return me.hasChildren() ? me : null; - } else { - /* - * Sequence is expected but was something else. Replace the - * whole tuple. Don't touch the whitespace when replacing - - * it looks good - */ - StringBuilder s = serialize(property, otherValue); - preIndent(s, sequence.getStartMark().getColumn()); - return createReplaceEditWithoutWhiteSpace(sequence.getStartMark().getIndex(), - tuple.getValueNode().getEndMark().getIndex() - 1, - s.toString().trim()); - } - } - } - return null; - } - - private TextEdit createEdit(MappingNode parent, Map otherValue, String property) { - NodeTuple tuple = findNodeTuple(parent, property); - if (tuple == null) { - /* - * No tuple found for the key - */ - if (otherValue != null && !otherValue.isEmpty()) { - /* - * If other value is something that can be serialized, serialize the key and other value and put in the YAML - */ - StringBuilder serializedValue = serialize(property, otherValue); -// postIndent(serializedValue, getDefaultOffset()); -// int position = positionToAppendAt(parent); - boolean[] postIndent = new boolean[] { true }; - int position = positionToAppendAt(parent, postIndent); - if (postIndent[0]) { - postIndent(serializedValue, getDefaultOffset()); - } else { - preIndent(serializedValue, getDefaultOffset()); - } - return new ReplaceEdit(position, 0, serializedValue.toString()); - } - } else { - /* - * Tuple with the string key is found - */ - if (otherValue == null || otherValue.isEmpty()) { - /* - * Delete the found tuple since other value is null or empty - */ - int start = tuple.getKeyNode().getStartMark().getIndex(); - int end = tuple.getValueNode().getEndMark().getIndex(); - return new DeleteEdit(start, end - start); -// return createDeleteEditIncludingLine(tuple.getKeyNode().getStartMark().getIndex(), tuple.getValueNode().getEndMark().getIndex()); - } else { - /* - * Tuple is found, so the key node is there, check the value node - */ - Node map = tuple.getKeyNode(); - if (tuple.getValueNode() instanceof MappingNode) { - /* - * Value node is a map node. Go over every entry in the map to calculate differences - */ - MappingNode mapValue = (MappingNode) tuple.getValueNode(); - MultiTextEdit e = new MultiTextEdit(); - Map leftOver = new LinkedHashMap<>(); - leftOver.putAll(otherValue); - int appendIndex = mapValue.getStartMark().getIndex(); - for (NodeTuple t : mapValue.getValue()) { - if (t.getKeyNode() instanceof ScalarNode && t.getValueNode() instanceof ScalarNode) { - ScalarNode key = (ScalarNode) t.getKeyNode(); - ScalarNode value = (ScalarNode) t.getValueNode(); - String newValue = leftOver.get(key.getValue()); - if (newValue == null) { - /* - * Delete the tuple if newValue is null. Delete including the line if necessary - */ - e.addChild(createDeleteEditIncludingLine(key.getStartMark().getIndex(), value.getEndMark().getIndex())); - } else if (!value.getValue().equals(newValue)) { - /* - * Key is there but value is different, so edit the value - */ - e.addChild(new ReplaceEdit(value.getStartMark().getIndex(), value.getEndMark().getIndex() - value.getStartMark().getIndex(), newValue)); - appendIndex = value.getEndMark().getIndex(); - } else { - appendIndex = value.getEndMark().getIndex(); - } - leftOver.remove(key.getValue()); - } - } - /* - * Offset appendIndex to leave the line break for the previous entry in place. jump over spacing and line break. - */ - for (; appendIndex > 0 && appendIndex < content.length() && Character.isWhitespace(content.charAt(appendIndex)) && content.charAt(appendIndex - 1) != '\n'; appendIndex++); - /* - * Add a line break if append index is not starting right after line break. - */ - if (!leftOver.isEmpty() && content.charAt(appendIndex - 1) != '\n') { - e.addChild(new ReplaceEdit(appendIndex, 0, System.lineSeparator())); - } - /* - * Add remaining unmatched entries - */ - for (Map.Entry entry : leftOver.entrySet()) { - StringBuilder serializedValue = serialize(entry.getKey(), entry.getValue()); - preIndent(serializedValue, mapValue.getStartMark().getColumn()); - e.addChild(new ReplaceEdit(appendIndex, 0, serializedValue.toString())); - } - return e.hasChildren() ? e : null; - } else { - /* - * Map is expected but was something else. Replace the - * whole tuple. Don't touch the whitespace when replacing - - * it looks good - */ - StringBuilder serializedValue = serialize(property, otherValue); - preIndent(serializedValue, map.getStartMark().getColumn()); - return createReplaceEditWithoutWhiteSpace(map.getStartMark().getIndex(), tuple.getValueNode().getEndMark().getIndex() - 1, serializedValue.toString().trim()); - } - } - } - return null; - } - - private StringBuilder serialize(String property, Object value) { - Map obj = new HashMap<>(); - obj.put(property, value); - return new StringBuilder(yaml.dump(obj)); - } - - private StringBuilder postIndent(StringBuilder s, int offset) { - char[] indent = new char[offset]; - for (int i = 0; i < offset; i++) { - indent[i] = ' '; - } - for (int i = 0; i < s.length(); ) { - if (s.charAt(i) == '\n') { - s.insert(i + 1, indent); - i += indent.length; - } - i++; - } - return s; - } - - private StringBuilder serializeListEntry(Object obj, int offset) { - StringBuilder s = new StringBuilder(yaml.dump(Collections.singletonList(obj))); - if (offset > 0) { - preIndent(s, offset); - } - return s; - } - - private StringBuilder preIndent(StringBuilder s, int offset) { - char[] indent = new char[offset]; - for (int i = 0; i < offset; i++) { - indent[i] = ' '; - } - int lineLength = 0; - for (int i = 0; i < s.length(); ) { - if (s.charAt(i) == '\n') { - if (lineLength > 0) { - s.insert(i - lineLength, indent); - i += indent.length; - lineLength = 0; - } - } else { - lineLength++; - } - i++; - } - if (lineLength > 0) { - s.insert(s.length() - lineLength, indent); - lineLength = 0; - } - return s; - } - - private DeleteEdit createDeleteEditIncludingLine(int start, int end) { - if (content != null) { - for (; start > 0 && Character.isWhitespace(content.charAt(start - 1)) && content.charAt(start - 1) != '\n'; start--); - for (; end > 0 && end < content.length() && Character.isWhitespace(content.charAt(end)) && content.charAt(end - 1) != '\n'; end++); - } - return new DeleteEdit(start, end - start); - } - - private ReplaceEdit createReplaceEditWithoutWhiteSpace(int start, int end, String text) { - for (; start < content.length() && Character.isWhitespace(content.charAt(start)); start++); - for (; end >= start && Character.isWhitespace(content.charAt(end)); end--); - return new ReplaceEdit(start, end - start + 1, text); - } - - private int getDefaultOffset() { - if (appNode == null) { - if (applicationsValueNode == null) { - return 0; - } else { - return applicationsValueNode.getStartMark().getColumn(); - } - } else { - return appNode.getStartMark().getColumn(); - } - } - - public List getRoutes() { - List> routes = getAbsoluteValue(ApplicationManifestHandler.ROUTES_PROP, List.class); - if (routes != null) { - return routes.stream() - .map(routeObj -> routeObj.get(ApplicationManifestHandler.ROUTE_PROP)) - .filter(o -> o instanceof String) - .map(o -> (String) o) - .collect(Collectors.toList()); - } - return null; - } - - @Override - @SuppressWarnings("unchecked") - public Set getUris() { - - List routes = getRoutes(); - if (routes != null) { - return ImmutableSet.copyOf(routes); - } else { - Boolean noRoute = getAbsoluteValue(ApplicationManifestHandler.NO_ROUTE_PROP, Boolean.class); - if (Boolean.TRUE.equals(noRoute)) { - return Collections.emptySet(); - } - - List domains = cloudData.getDomains(); - LinkedHashSet hostsSet = new LinkedHashSet<>(); - LinkedHashSet domainsSet = new LinkedHashSet<>(); - - /* - * Gather domains from app node from 'domain' and 'domains' attributes - */ - String domain = getAbsoluteValue(ApplicationManifestHandler.DOMAIN_PROP, String.class); - if (domain != null) { - domainsSet.add(domain); - } - List domainsList = getAbsoluteValue(ApplicationManifestHandler.DOMAINS_PROP, List.class); - if (domainsList != null) { - domainsSet.addAll(domainsList); - } - - /* - * Gather hosts from app node from 'host' and 'hosts' - * attributes. - */ - String host = getAbsoluteValue(ApplicationManifestHandler.SUB_DOMAIN_PROP, String.class); - if (host != null) { - hostsSet.add(host); - } - List hostsList = getAbsoluteValue(ApplicationManifestHandler.SUB_DOMAINS_PROP, List.class); - if (hostsList != null) { - for (Object o : hostsList) { - if (o instanceof String) { - hostsSet.add((String)o); - } - } - } - - /* - * If no host names found check for "random-route: true" and - * "no-hostname: true" otherwise take app name as the host name - */ - if (hostsSet.isEmpty()) { - Boolean randomRoute = getAbsoluteValue(ApplicationManifestHandler.RANDOM_ROUTE_PROP, Boolean.class); - if (Boolean.TRUE.equals(randomRoute)) { - hostsSet.add(ApplicationManifestHandler.RANDOM_VAR); - domainsSet.clear(); - domainsSet.add(cloudData.getDefaultDomain()); - } else { - Boolean noHostname = getAbsoluteValue(ApplicationManifestHandler.NO_HOSTNAME_PROP, Boolean.class); - if (!Boolean.TRUE.equals(noHostname)) { - hostsSet.add(getAppName()); - } - } - } - - /* - * Set a domain if they are still empty - */ - if (domainsSet.isEmpty()) { - domainsSet.add(cloudData.getDefaultDomain()); - } - - /* - * Compose URIs for application based on hosts and domains - */ - Set uris = new HashSet<>(); - for (String d : domainsSet) { - if (hostsSet.isEmpty()) { - uris.add(CFRoute.builder().domain(d).build().getRoute()); - } else { - for (String h : hostsSet) { - uris.add(CFRoute.builder().host(h).domain(d).build().getRoute()); - } - } - } - - return uris; - } - } - - @Override - public int getDiskQuota() { - String quotaStringValue = getAbsoluteValue(ApplicationManifestHandler.DISK_QUOTA_PROP, String.class); - if (quotaStringValue != null) { - try { - return ApplicationManifestHandler.convertMemory(quotaStringValue); - } catch (CoreException e) { - Log.log(e); - } - } - return DeploymentProperties.DEFAULT_MEMORY; - } - - public static V getPropertyValue(final Node n, final String key, Class parameter) { - Node node = YamlGraphDeploymentProperties.findValueNode(n, key); - return getValue(node, parameter); - } - - @SuppressWarnings("unchecked") - public static V getValue(Node node, Class parameter) { - return (V) new Constructor(parameter) { - @Override - public Object getSingleData(Class type) { - // Ensure that the stream contains a single document and construct it - if (node != null) { - if (type != null) { - node.setTag(new Tag(type)); - } else { - node.setTag(rootTag); - } - return constructObject(node); - } - return null; - } - }.getSingleData(parameter); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected V getAbsoluteValue(String key, Class parameter) { - V v = getPropertyValue(appNode, key, parameter); - if (Collection.class.isAssignableFrom(parameter)) { - if (root != appNode) { - V rootV = getPropertyValue(root, key, parameter); - if (rootV != null) { - if (v != null){ - ((Collection) rootV).addAll((Collection) v); - } - v = rootV; - } - } - } else if (Map.class.isAssignableFrom(parameter)) { - if (root != appNode) { - V rootV = getPropertyValue(root, key, parameter); - if (rootV != null) { - if (v != null){ - ((Map) rootV).putAll((Map) v); - } - v = rootV; - } - } - } else if (v == null) { - if (root != appNode) { - v = getPropertyValue(root, key, parameter); - } - } - return v; - } - - private static boolean isLegacyHostDomainManifestYaml(Node n) { - if (isLegacyHostDomainManifestYamlNode(n)) { - return true; - } else { - Node applicationsObj = findValueNode(n, ApplicationManifestHandler.APPLICATIONS_PROP); - if (applicationsObj instanceof SequenceNode) { - return ((SequenceNode) applicationsObj).getValue().stream() - .map(o -> (Node) o) - .filter(YamlGraphDeploymentProperties::isLegacyHostDomainManifestYamlNode) - .findFirst().isPresent(); - } - } - return false; - } - - private static boolean isLegacyHostDomainManifestYamlNode(Node node) { - return findValueNode(node, ApplicationManifestHandler.DOMAIN_PROP) != null - || findValueNode(node, ApplicationManifestHandler.SUB_DOMAIN_PROP) != null - || findValueNode(node, ApplicationManifestHandler.DOMAINS_PROP) != null - || findValueNode(node, ApplicationManifestHandler.SUB_DOMAINS_PROP) != null - || findValueNode(node, ApplicationManifestHandler.NO_HOSTNAME_PROP) != null; - } - - public String getRawHost() { - return getAbsoluteValue(ApplicationManifestHandler.SUB_DOMAIN_PROP, String.class); - } - public List getRawHosts() { - List hostsList = getAbsoluteValue(ApplicationManifestHandler.SUB_DOMAINS_PROP, List.class); - if (hostsList != null) { - List currentHosts = new ArrayList<>(); - for (Object o : hostsList) { - if (o instanceof String) { - currentHosts.add((String) o); - } - } - return ImmutableList.copyOf(currentHosts); - } - return null; - } - - public List getRawDomains() { - List hostsList = getAbsoluteValue(ApplicationManifestHandler.DOMAINS_PROP, List.class); - if (hostsList != null) { - List currentHosts = new ArrayList<>(); - for (Object o : hostsList) { - if (o instanceof String) { - currentHosts.add((String) o); - } - } - return ImmutableList.copyOf(currentHosts); - } - return null; - } - - public boolean getRawNoRoute() { - Boolean v = getAbsoluteValue(ApplicationManifestHandler.NO_ROUTE_PROP, Boolean.class); - return v==null ? false : v; - } - - public boolean getRawRandomRoute() { - Boolean v = getAbsoluteValue(ApplicationManifestHandler.RANDOM_ROUTE_PROP, Boolean.class); - return v==null ? false : v; - } - - public String getRawDomain() { - return getAbsoluteValue(ApplicationManifestHandler.DOMAIN_PROP, String.class); - } - - public boolean getRawNoHost() { - Boolean v = getAbsoluteValue(ApplicationManifestHandler.NO_HOSTNAME_PROP, Boolean.class); - return v==null ? false : v; - } - - @SuppressWarnings("unchecked") - @Override - public List getBuildpacks() { - List buildpacks = getAbsoluteValue(ApplicationManifestHandler.BUILDPACKS_PROP, List.class); - return buildpacks == null ? new ArrayList<>() : buildpacks; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CloudFoundryTargetWizardModel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CloudFoundryTargetWizardModel.java deleted file mode 100644 index f28af3fb3..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CloudFoundryTargetWizardModel.java +++ /dev/null @@ -1,473 +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.cf.dialogs; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.equinox.security.storage.StorageException; -import org.eclipse.jface.operation.IRunnableContext; -import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials.LoginMethod; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFExceptions; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.CloudFoundryClientFactory; -import org.springframework.ide.eclipse.boot.dash.cf.ops.Operation; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryTargetProperties; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springframework.ide.eclipse.boot.dash.model.WizardModelUserInteractions; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.CannotAccessPropertyException; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.TargetProperties; -import org.springframework.ide.eclipse.boot.util.Log; -import org.springsource.ide.eclipse.commons.livexp.core.CompositeValidator; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; -import org.springsource.ide.eclipse.commons.livexp.core.Validator; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -import com.google.common.collect.ImmutableSet; - -/** - * Cloud Foundry Target properties that uses {@link LiveExpression} and - * {@link Validator}. - */ -public class CloudFoundryTargetWizardModel { - - private RunTargetType runTargetType; - private BootDashModelContext context; - - private final LiveVariable url = new LiveVariable<>(); - private final LiveVariable space = new LiveVariable<>(); - private final LiveVariable selfsigned = new LiveVariable<>(false); - private final LiveVariable skipSslValidation = new LiveVariable<>(false); - private final LiveVariable method = new LiveVariable<>(LoginMethod.PASSWORD); - private final LiveVariable userName = new LiveVariable<>(); - private final LiveVariable password = new LiveVariable<>(); - private final LiveVariable storeCredentials = new LiveVariable<>(StoreCredentialsMode.STORE_NOTHING); - - private final LiveVariable spaceResolutionStatus = new LiveVariable<>(ValidationResult.OK); // has an error if resolution failed. - private final LiveVariable resolvedSpaces = new LiveVariable<>(); - - private String refreshToken = null; - - private final Validator credentialsValidator = new Validator() { - { - dependsOn(url); - dependsOn(userName); - dependsOn(method); - dependsOn(password); - } - - @Override - protected ValidationResult compute() { - if (isEmpty(userName.getValue()) && method.getValue()==LoginMethod.PASSWORD) { - return ValidationResult.info("Enter a username"); - } else if (isEmpty(url.getValue())) { - try { - new URL(url.getValue()); - return ValidationResult.info("Enter a target URL"); - } catch (MalformedURLException e) { - return ValidationResult.error(e.getMessage()); - } - } else if (method.getValue()==LoginMethod.PASSWORD) { - if (isEmpty(password.getValue())) { - return ValidationResult.info("Enter a password"); - } - } else if (method.getValue()==LoginMethod.TEMPORARY_CODE) { - if (isEmpty(password.getValue())) { - return ValidationResult.info("Enter a Temporary Access Code"); - } - } - return ValidationResult.OK; - } - - protected boolean isEmpty(String value) { - return value == null || value.trim().length() == 0; - } - }; - - private final Validator spaceValidator = new Validator() { - { - dependsOn(space); - } - @Override - protected ValidationResult compute() { - if (getSpaceName() == null || getOrganizationName() == null) { - return ValidationResult.info("Select a Cloud space"); - } - - if (space.getValue() != null) { - RunTarget existing = CloudFoundryTargetWizardModel.this.getExistingRunTarget(space.getValue()); - if (existing != null) { - return ValidationResult.error("A run target for that space already exists: '" + existing.getName() - + "'. Please select another space."); - } - } - return ValidationResult.OK; - } - }; - private Validator resolvedSpacesValidator = new Validator() { - { - dependsOn(spaceResolutionStatus); - dependsOn(resolvedSpaces); - } - @Override - protected ValidationResult compute() { - ValidationResult resolveStatus = spaceResolutionStatus.getValue(); - if (!resolveStatus.isOk()) { - return resolveStatus; - } - if (resolvedSpaces.getValue() == null || resolvedSpaces.getValue().getAllSpaces() == null) { - return ValidationResult.info("Select a space to validate the credentials."); - } - if (resolvedSpaces.getValue().getAllSpaces().isEmpty()) { - return ValidationResult.error( - "No spaces available to select. Please check that the credentials and target URL are correct, and spaces are defined in the target."); - } - return ValidationResult.OK; - } - }; - private Validator storeCredentialsValidator = PasswordDialogModel.makeStoreCredentialsValidator(method, storeCredentials); - private CompositeValidator allPropertiesValidator = new CompositeValidator(); - - private CloudFoundryClientFactory clientFactory; - private ImmutableSet existingTargets; - private WizardModelUserInteractions interactions; - - - public CloudFoundryTargetWizardModel(RunTargetType runTargetType, CloudFoundryClientFactory clientFactory, - ImmutableSet existingTargets, BootDashModelContext context) { - this(runTargetType, clientFactory, existingTargets, context, null); - } - - public CloudFoundryTargetWizardModel(RunTargetType runTargetType, CloudFoundryClientFactory clientFactory, - ImmutableSet existingTargets, BootDashModelContext context, WizardModelUserInteractions interactions) { - this.runTargetType = runTargetType; - this.context = context; - Assert.isNotNull(clientFactory, "clientFactory should not be null"); - this.interactions = interactions; - this.existingTargets = existingTargets == null ? ImmutableSet.of() : existingTargets; - this.clientFactory = clientFactory; - - // Aggregate of the credentials and space validators. - allPropertiesValidator.addChild(credentialsValidator); - allPropertiesValidator.addChild(storeCredentialsValidator); - allPropertiesValidator.addChild(resolvedSpacesValidator); - allPropertiesValidator.addChild(spaceValidator); - } - - public void setUrl(String url) { - this.url.setValue(url); - } - - public void setSelfsigned(boolean selfsigned) { - this.selfsigned.setValue(selfsigned); - } - - public void skipSslValidation(boolean skipSsl) { - this.skipSslValidation.setValue(skipSsl); - } - - public void setUsername(String userName) { - this.userName.setValue(userName); - } - - public void setPassword(String password) throws CannotAccessPropertyException { - this.password.setValue(password); - } - - public void setSpace(CFSpace space) { - this.space.setValue(space); - } - - public String getPassword() throws CannotAccessPropertyException { - return password.getValue(); - } - - public String getUrl() { - return url.getValue(); - } - - public String getUsername() { - return userName.getValue(); - } - - public void setStoreCredentials(StoreCredentialsMode store) { - storeCredentials.setValue(store); - } - - public StoreCredentialsMode getStoreCredentials() { - return storeCredentials.getValue(); - } - - public OrgsAndSpaces resolveSpaces(IRunnableContext context) { - try { - boolean toFetchSpaces = true; - OrgsAndSpaces spaces = getCloudSpaces(createTargetProperties(toFetchSpaces), context); - resolvedSpaces.setValue(spaces); - spaceResolutionStatus.setValue(ValidationResult.OK); - return resolvedSpaces.getValue(); - } catch (Exception e) { - if (CFExceptions.isAuthFailure(e) || CFExceptions.isSSLCertificateFailure(e)) { - //don't log, its expected if user just typed bad password, - //or didn't check ssl box when they should have. - } else { - Log.log(e); - } - resolvedSpaces.setValue(null); - spaceResolutionStatus.setValue(ValidationResult.error(ExceptionUtil.getMessage(e))); - return null; - } - } - - private OrgsAndSpaces getCloudSpaces(final CloudFoundryTargetProperties targetProperties, IRunnableContext context) - throws Exception { - - OrgsAndSpaces spaces = null; - - Operation> op = new Operation>( - "Connecting to the Cloud Foundry target. Please wait while the list of spaces is resolved...") { - @Override - protected List runOp(IProgressMonitor monitor) throws Exception, OperationCanceledException { - ClientRequests client = clientFactory.getClient(targetProperties); - try { - List spaces = client.getSpaces(); - String t = client.getRefreshToken(); - if (t!=null) { - refreshToken = t; - } - String effectiveUser = getUserName(client); - if (effectiveUser!=null) { - userName.setValue(effectiveUser); - } - return spaces; - } finally { - client.close(); - } - } - - private String getUserName(ClientRequests client) { - try { - return client.getUserName().block(); - } catch (Exception e) { - Log.log(e); - } - return null; - } - }; - - List actualSpaces = op.run(context, true); - if (actualSpaces != null && !actualSpaces.isEmpty()) { - spaces = new OrgsAndSpaces(actualSpaces); - } - - return spaces; - } - - /** - * Create target properties based on current input values in the wizard. - *

- * Note that there are two slightly different ways to produce these properties. - *

- * a) to create a intermediate client just to fetch orgs and spaces. - *

- * b) the final properties used to create the client after space is selected and the user - * clicks 'finish' button. - */ - private CloudFoundryTargetProperties createTargetProperties(boolean toFetchSpaces) throws CannotAccessPropertyException { - CloudFoundryTargetProperties targetProps = new CloudFoundryTargetProperties(null, runTargetType, context.injections); - if (!toFetchSpaces) { - //Take care: when fetching spaces the space may not be known yet, so neither is the id - String id = CloudFoundryTargetProperties.getId( - this.getUsername(), - this.getUrl(), - this.getOrganizationName(), - this.getSpaceName() - ); - targetProps.put(TargetProperties.RUN_TARGET_ID, id); - } - - targetProps.setUrl(url.getValue()); - targetProps.setSelfSigned(selfsigned.getValue()); - targetProps.setSkipSslValidation(skipSslValidation.getValue()); - - targetProps.setUserName(userName.getValue()); - if (toFetchSpaces) { - targetProps.setStoreCredentials(StoreCredentialsMode.STORE_NOTHING); - targetProps.setCredentials(CFCredentials.fromLogin(method.getValue(), password.getValue())); - } else { - //use credentials of a style that is consistent with the 'store mode'. - if (method.getValue()==LoginMethod.TEMPORARY_CODE && storeCredentials.getValue()==StoreCredentialsMode.STORE_PASSWORD) { - //The temporary token shouldn't be stored since its meaningless. Silently downgrade storemode: - storeCredentials.setValue(StoreCredentialsMode.STORE_NOTHING); - } - StoreCredentialsMode mode = storeCredentials.getValue(); - targetProps.setStoreCredentials(storeCredentials.getValue()); - switch (mode) { - case STORE_NOTHING: - case STORE_TOKEN: - Assert.isTrue(refreshToken!=null); - targetProps.setCredentials(CFCredentials.fromRefreshToken(refreshToken)); - break; - case STORE_PASSWORD: - targetProps.setCredentials(CFCredentials.fromPassword(password.getValue())); - break; - default: - throw new IllegalStateException("BUG: Missing switch case?"); - } - } - targetProps.setSpace(space.getValue()); - return targetProps; - } - - public OrgsAndSpaces getSpaces() { - return resolvedSpaces.getValue(); - } - - protected RunTarget getExistingRunTarget(CFSpace space) { - if (space != null) { - String targetId = CloudFoundryTargetProperties.getId(getUsername(), getUrl(), - space.getOrganization().getName(), space.getName()); - for (RunTarget target : existingTargets) { - if (targetId.equals(target.getId())) { - return target; - } - } - } - return null; - } - - public CloudFoundryRunTarget finish() throws Exception { - CloudFoundryTargetProperties targetProps = null; - try { - targetProps = createTargetProperties(/*toFetchSpaces*/false); - } catch (Exception e) { - final StorageException storageException = getStorageException(e); - // Allow run target to be created on storage exceptions as the run target can still be created and connected - if (storageException != null) { - Log.log(storageException); - if (interactions != null) { - String message = "Failed to store credentials in secure storage. Please check your secure storage preferences. Error: " - + storageException.getMessage(); - interactions.informationPopup("Secure Storage Error", message); - } - storeCredentials.setValue(StoreCredentialsMode.STORE_NOTHING); - targetProps = createTargetProperties(/*toFetchSpaces*/false); - } else { - throw e; - } - } - return (CloudFoundryRunTarget) runTargetType.createRunTarget(targetProps); - } - - public String getSpaceName() { - CFSpace space = this.space.getValue(); - if (space!=null) { - return space.getName(); - } - return null; - } - - public String getOrganizationName() { - CFSpace space = this.space.getValue(); - if (space!=null) { - return space.getOrganization().getName(); - } - return null; - } - - protected StorageException getStorageException(Exception e) { - if (e instanceof StorageException) { - return (StorageException) e; - } - if (e.getCause() instanceof StorageException) { - return (StorageException) e.getCause(); - } - return null; - } - - /** - * @return A 'complete' validator that reflects the validation state of all the inputs in this 'ui'. - */ - public LiveExpression getValidator() { - return allPropertiesValidator; - } - - public String getRefreshToken() { - return refreshToken; - } - - public LiveVariable getMethodVar() { - return method; - } - - public LiveVariable getUserNameVar() { - return userName; - } - - public LiveVariable getPasswordVar() { - return password; - } - - public LiveVariable getStoreVar() { - return storeCredentials; - } - - public LiveVariable getSkipSslVar() { - return skipSslValidation; - } - - public LiveVariable getUrlVar() { - return url; - } - - public LiveVariable getSpaceVar() { - return space; - } - - public LiveExpression getEnableSpacesUI() { - return credentialsValidator.apply((r) -> r.isOk()); - } - - public LiveExpression getEnableUserName() { - return method.apply((method) -> method==LoginMethod.PASSWORD); - } - - public LiveExpression getSpaceValidator() { - return spaceValidator; - } - - public LiveExpression getResolvedSpacesValidator() { - return resolvedSpacesValidator; - } - - public LiveExpression getCredentialsValidator() { - return credentialsValidator; - } - - public void setMethod(LoginMethod v) { - method.setValue(v); - } - - public Validator getStoreCredentialsValidator() { - return storeCredentialsValidator; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CloudFoundryTargetWizardPage.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CloudFoundryTargetWizardPage.java deleted file mode 100644 index cb1ec651c..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CloudFoundryTargetWizardPage.java +++ /dev/null @@ -1,173 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.dialogs; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; - -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials.LoginMethod; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springframework.ide.eclipse.editor.support.util.CollectionUtil; -import org.springsource.ide.eclipse.commons.livexp.core.CompositeValidator; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; -import org.springsource.ide.eclipse.commons.livexp.ui.CheckboxSection; -import org.springsource.ide.eclipse.commons.livexp.ui.ChooseOneSectionCombo; -import org.springsource.ide.eclipse.commons.livexp.ui.IPageWithSections; -import org.springsource.ide.eclipse.commons.livexp.ui.StringFieldSection; -import org.springsource.ide.eclipse.commons.livexp.ui.UIConstants; -import org.springsource.ide.eclipse.commons.livexp.ui.ValidatorSection; -import org.springsource.ide.eclipse.commons.livexp.ui.WizardPageSection; -import org.springsource.ide.eclipse.commons.livexp.ui.WizardPageWithSections; - -/** - * Creates a Cloud Foundry target by prompting user for credentials and Cloud - * Foundry target URL. - * - * - */ -public class CloudFoundryTargetWizardPage extends WizardPageWithSections { - - private CloudFoundryTargetWizardModel model; - - private class SelectSpaceSection extends WizardPageSection { - - private CompositeValidator spaceSectionValidator = new CompositeValidator(); - { - //Do these two really need to be exposed from the model as separate entities? - // I don't think they are really used separately? - // Keeping it like this for now as it sort of make sense. The ui here has two pieces - // one is a box showing a selected space. And the other a button to resolve spaces. - spaceSectionValidator.addChild(model.getResolvedSpacesValidator()); - spaceSectionValidator.addChild(model.getSpaceValidator()); - } - - public SelectSpaceSection(IPageWithSections owner) { - super(owner); - } - - @Override - public void createContents(Composite page) { - Composite buttonComposite = new Composite(page, SWT.NONE); - GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonComposite); - GridLayout layout = GridLayoutFactory.fillDefaults().numColumns(3).margins(0,2).create(); - buttonComposite.setLayout(layout); - - Label label = new Label(buttonComposite, SWT.NONE); - label.setText("Space:"); - GridDataFactory.fillDefaults() - .hint(UIConstants.fieldLabelWidthHint(label), SWT.DEFAULT) - .align(SWT.BEGINNING, SWT.CENTER) - .applyTo(label); - - Text spaceValueText = new Text(buttonComposite, SWT.BORDER); - spaceValueText.setEnabled(false); - spaceValueText.setBackground(buttonComposite.getBackground()); - GridDataFactory.fillDefaults().grab(true, false).applyTo(spaceValueText); - model.getSpaceVar().addListener((exp, value) -> { - if (spaceValueText != null && !spaceValueText.isDisposed()) { - spaceValueText.setText(value != null ? value.getName() : ""); - } - }); - - Button selectSpaceButton = new Button(buttonComposite, SWT.PUSH); - selectSpaceButton.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); - selectSpaceButton.setText("Select Space..."); - selectSpaceButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - - // Fetch an updated list of orgs and spaces in a cancellable - // operation (i.e. the operation - // can be cancelled in the wizard's progress bar) - model.resolveSpaces(getWizard().getContainer()); - OrgsAndSpaces spaces = model.getSpaces(); - if (spaces != null && CollectionUtil.hasElements(spaces.getAllSpaces())) { - OrgsAndSpacesWizard spacesWizard = new OrgsAndSpacesWizard(model); - WizardDialog dialog = new WizardDialog(getShell(), spacesWizard); - dialog.open(); - } - } - }); - - //Enable the "Select Space" button once credentials are complete. - model.getCredentialsValidator().addListener((exp, value) -> { - if (selectSpaceButton != null && !selectSpaceButton.isDisposed()) { - selectSpaceButton.setEnabled(value.isOk()); - } - }); - } - - @Override - public LiveExpression getValidator() { - return spaceSectionValidator; - } - - } - - - private CloudFoundryRunTarget runTarget = null; - - public CloudFoundryTargetWizardPage(CloudFoundryTargetWizardModel model) { - super("page1", "Add a Cloud Foundry Target", BootDashActivator.getImageDescriptor("icons/wizban_cloudfoundry.png")); - this.model = model; - setDescription("Enter credentials and a Cloud Foundry target URL."); - } - - @Override - protected List createSections() { - List sections = new ArrayList<>(); - sections.add(new ChooseOneSectionCombo<>(this, "Method:", model.getMethodVar(), EnumSet.allOf(LoginMethod.class))); - //TODO: hide password or passcode field depending on the method. - sections.add(new StringFieldSection(this, "Email:", model.getUserNameVar()) - .setEnabler(model.getEnableUserName())); - - sections.add(new StringFieldSection(this, "Password:", model.getPasswordVar()).setPassword(true)); - sections.add(UpdatePasswordDialog.storeCredentialsSection(this, model.getStoreVar(), model.getStoreCredentialsValidator())); - sections.add(new StringFieldSection(this, "Url:", model.getUrlVar())); - sections.add(new ValidatorSection(model.getCredentialsValidator(), this)); - sections.add(new SelectSpaceSection(this)); - sections.add(new CheckboxSection(this, model.getSkipSslVar(), "Skip SSL Validation")); - return sections; - } - - /** - * Creates a run target ONCE. - * @return created run target. Returns cached target if already created. - */ - public CloudFoundryRunTarget createRunTarget() { - // Cache to avoid creating run target multiple times in the same wizard session - if (runTarget == null) { - try { - runTarget = model.finish(); - } catch (Exception e) { - setErrorMessage(e.getMessage()); - } - } - return runTarget; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CustomizeAppsManagerURLDialog.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CustomizeAppsManagerURLDialog.java deleted file mode 100644 index 005dc355b..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CustomizeAppsManagerURLDialog.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.dialogs; - -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.swt.widgets.Shell; -import org.springsource.ide.eclipse.commons.livexp.ui.ButtonSection; -import org.springsource.ide.eclipse.commons.livexp.ui.DialogWithSections; -import org.springsource.ide.eclipse.commons.livexp.ui.StringFieldSection; -import org.springsource.ide.eclipse.commons.livexp.ui.WizardPageSection; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableList.Builder; - -/** - * @author Martin Lippert - */ -public class CustomizeAppsManagerURLDialog extends DialogWithSections { - - private CustomizeAppsManagerURLDialogModel model; - - public CustomizeAppsManagerURLDialog(CustomizeAppsManagerURLDialogModel model, Shell shell) { - super("Customize Host URL of Apps Manager", model, shell); - this.model = model; - } - - @Override - protected List createSections() throws CoreException { - Builder sections = ImmutableList.builder(); - sections.add(new StringFieldSection(this, model.host).tooltip(model.getHelpText())); - sections.add(new ButtonSection(this, "Restore Defaults", model.restoreDefaultsHandler)); - return sections.build(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CustomizeAppsManagerURLDialogModel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CustomizeAppsManagerURLDialogModel.java deleted file mode 100644 index 85a32ca88..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/CustomizeAppsManagerURLDialogModel.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.dialogs; - -import java.util.concurrent.Callable; - -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springsource.ide.eclipse.commons.livexp.core.StringFieldModel; -import org.springsource.ide.eclipse.commons.livexp.ui.OkButtonHandler; - -/** - * @author Martin Lippert - */ -public class CustomizeAppsManagerURLDialogModel implements OkButtonHandler { - - public final StringFieldModel host = new StringFieldModel("Apps Manager", ""); - private final CloudFoundryBootDashModel cloudFoundrySection; - - public CustomizeAppsManagerURLDialogModel(CloudFoundryBootDashModel cloudFoundrySection) { - this.cloudFoundrySection = cloudFoundrySection; - host.getVariable().setValue(this.cloudFoundrySection.getRunTarget().getAppsManagerHost()); - } - - public Callable restoreDefaultsHandler = new Callable() { - public Void call() throws Exception { - host.getVariable().setValue(getDefaultValue()); - return null; - } - }; - - @Override - public void performOk() throws Exception { - cloudFoundrySection.getRunTarget().setAppsManagerHost(host.getValue()); - cloudFoundrySection.notifyModelStateChanged(); - } - - public String getHelpText() { - return "no help available"; - } - - public String getDefaultValue() { - return cloudFoundrySection.getRunTarget().getAppsManagerHostDefault(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/DeploymentPropertiesDialog.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/DeploymentPropertiesDialog.java deleted file mode 100644 index 59483f88a..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/DeploymentPropertiesDialog.java +++ /dev/null @@ -1,705 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 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.cf.dialogs; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -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.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jface.dialogs.DialogSettings; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.text.source.SourceViewer; -import org.eclipse.jface.text.source.projection.ProjectionViewer; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.ITreeSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Sash; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IWorkbenchCommandConstants; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.IHandlerActivation; -import org.eclipse.ui.handlers.IHandlerService; -import org.eclipse.ui.model.BaseWorkbenchContentProvider; -import org.eclipse.ui.model.WorkbenchLabelProvider; -import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialogModel.ManifestType; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.UIValueListener; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; -import org.springsource.ide.eclipse.commons.livexp.core.ValueListener; -import org.springsource.ide.eclipse.commons.livexp.ui.util.SwtConnect; -import org.springsource.ide.eclipse.commons.livexp.util.Log; - -/** - * Cloud Foundry Application deployment properties dialog. Allows user to select - * manifest YAML file or enter deployment manifest YAML manually. - * - * @author Alex Boyko - * - */ -public class DeploymentPropertiesDialog extends TitleAreaDialog { - - public static final String CONTEXT_DEPLOYMENT_PROPERTIES_DIALOG = "deployment-properties-dialog"; - - final static private String DIALOG_LIST_HEIGHT_SETTING = "ManifestFileDialog.listHeight"; //$NON-NLS-1$ - final static private String YML_EXTENSION = "yml"; //$NON-NLS-1$ - final static private String[] FILE_FILTER_NAMES = new String[] {"Manifest YAML files - *manifest*.yml", "YAML files - *.yml", "All files - *.*"}; - - - private static abstract class DeepFileFilter extends ViewerFilter { - - @Override - public boolean select(Viewer viewer, Object parent, Object element) { - if (element instanceof IResource && !((IResource)element).isDerived()) { - if (element instanceof IFile) { - return acceptFile((IFile)element); - } - if (element instanceof IContainer) { - try { - IContainer container = (IContainer) element; - for (IResource resource : container.members()) { - boolean select = select(viewer, container, resource); - if (select) { - return true; - } - } - } catch (CoreException e) { - // ignore - } - } - } - return false; - } - - abstract protected boolean acceptFile(IFile file); - - } - - final static private ViewerFilter YAML_FILE_FILTER = new DeepFileFilter() { - @Override - protected boolean acceptFile(IFile file) { - return YML_EXTENSION.equals(file.getFileExtension()); - } - }; - final static private ViewerFilter MANIFEST_YAML_FILE_FILTER = new DeepFileFilter() { - @Override - protected boolean acceptFile(IFile file) { - return file.getName().toLowerCase().contains("manifest") && YML_EXTENSION.equals(file.getFileExtension()); - } - }; - final static private ViewerFilter ALL_FILES = new ViewerFilter() { - @Override - public boolean select(Viewer viewer, Object parent, Object element) { - return (element instanceof IResource) && !((IResource)element).isDerived(); - } - }; - final static private ViewerFilter[][] RESOURCE_FILTERS = new ViewerFilter[][] { - {MANIFEST_YAML_FILE_FILTER}, - {YAML_FILE_FILTER}, - {ALL_FILES} - }; - - final static private int DEFAULT_WORKSPACE_GROUP_HEIGHT = 200; - - private Label fileLabel; - private Sash resizeSash; - private TreeViewer workspaceViewer; - private Button refreshButton; - private Button buttonFileManifest; - private Button buttonManualManifest; - private Group fileGroup; - private Group yamlGroup; - private Composite fileYamlComposite; - private Composite manualYamlComposite; - private Combo fileFilterCombo; - private IHandlerService service; - private List activations; - private EditorActionHandler[] handlers = new EditorActionHandler[] { - new EditorActionHandler(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, SourceViewer.CONTENTASSIST_PROPOSALS), - new EditorActionHandler(IWorkbenchCommandConstants.EDIT_UNDO, SourceViewer.UNDO), - new EditorActionHandler(IWorkbenchCommandConstants.EDIT_REDO, SourceViewer.REDO), - }; - - private ISelectionChangedListener selectionListener = new ISelectionChangedListener() { - @Override - public void selectionChanged(final SelectionChangedEvent e) { - IResource resource = (IResource) getStructuredSelection(workspaceViewer).getFirstElement(); - model.setSelectedManifest(resource); - } - }; - - final private DeploymentPropertiesDialogModel model; - private Button buttonEnableJmx; - - public DeploymentPropertiesDialog(Shell parentShell, DeploymentPropertiesDialogModel model) { - super(parentShell); - this.model = model; - this.service = (IHandlerService) PlatformUI.getWorkbench().getAdapter(IHandlerService.class); - this.activations = new ArrayList<>(handlers.length); - } - - @Override - protected Control createDialogArea(Composite parent) { - setTitle("Select Deployment Manifest for project '" + model.getProjectName() + "'"); - Composite container = (Composite) super.createDialogArea(parent); - final Composite composite = new Composite(container, parent.getStyle()); - composite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create()); - composite.setLayout(new GridLayout()); - - createModeSwitchGroup(composite); - - createFileGroup(composite); - - createResizeSash(composite); - - createYamlContentsGroup(composite); - - if (model.supportsSsh) { - createJmxSshOptionsGroup(composite); - } - - activateHandlers(); - - model.type.addListener(new ValueListener() { - @Override - public void gotValue(LiveExpression exp, ManifestType type) { - GridData gridData; - boolean isFile = type == ManifestType.FILE; - buttonFileManifest.setSelection(isFile); - buttonManualManifest.setSelection(!isFile); - - refreshButton.setEnabled(isFile && !workspaceViewer.getSelection().isEmpty()); - workspaceViewer.getControl().setEnabled(isFile); - fileLabel.setEnabled(isFile); - - gridData = GridDataFactory.copyData((GridData) fileGroup.getLayoutData()); - gridData.exclude = !isFile; - fileGroup.setVisible(isFile); - fileGroup.setLayoutData(gridData); - gridData = GridDataFactory.copyData((GridData) resizeSash.getLayoutData()); - gridData.exclude = !isFile; - resizeSash.setVisible(isFile); - resizeSash.setLayoutData(gridData); - fileGroup.getParent().layout(); - - fileYamlComposite.setVisible(isFile); - gridData = GridDataFactory.copyData((GridData) fileYamlComposite.getLayoutData()); - gridData.exclude = !isFile; - fileYamlComposite.setLayoutData(gridData); - manualYamlComposite.setVisible(!isFile); - gridData = GridDataFactory.copyData((GridData) manualYamlComposite.getLayoutData()); - gridData.exclude = isFile; - manualYamlComposite.setLayoutData(gridData); - yamlGroup.layout(); - yamlGroup.getParent().layout(); - } - }); - - model.getValidator().addListener(new UIValueListener() { - @Override - protected void uiGotValue(LiveExpression exp, ValidationResult value) { - ValidationResult result = exp.getValue(); - if (getButton(IDialogConstants.OK_ID) != null) { - getButton(IDialogConstants.OK_ID).setEnabled(result.status != IStatus.ERROR); - } - setMessage(result.msg, result.getMessageProviderStatus()); - } - }); - - parent.pack(true); - - /* - * Reveal the selected manifest file in the workspace viewer now when - * controls are created and laid out - */ - if (!workspaceViewer.getSelection().isEmpty()) { - workspaceViewer.setSelection(workspaceViewer.getSelection(), true); - } - return container; - } - - private void createJmxSshOptionsGroup(Composite composite) { - Group group = new Group(composite, SWT.NONE); - group.setText("JMX Ssh Tunnel"); - group.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); - group.setLayout(new GridLayout(2, true)); - - buttonEnableJmx = new Button(group, SWT.CHECK); - buttonEnableJmx.setText("Enable"); - buttonEnableJmx.setToolTipText("Activate JMX on the deployed app and create an SSH tunnel to it so it can be accessed locally."); - - SwtConnect.checkbox(buttonEnableJmx, model.enableJmxSshTunnel); - } - - private void createModeSwitchGroup(Composite composite) { - Group typeGroup = new Group(composite, SWT.NONE); - typeGroup.setText("Manifest Type"); - typeGroup.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); - typeGroup.setLayout(new GridLayout(2, true)); - - buttonFileManifest = new Button(typeGroup, SWT.RADIO); - buttonFileManifest.setText("File"); - buttonFileManifest.setSelection(model.isFileManifestType()); - buttonFileManifest.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (buttonFileManifest.getSelection()) { - model.setManifestType(ManifestType.FILE); - } - } - }); - buttonFileManifest.setLayoutData(GridDataFactory.fillDefaults().create()); - - buttonManualManifest = new Button(typeGroup, SWT.RADIO); - buttonManualManifest.setText("Manual"); - buttonManualManifest.setSelection(model.isManualManifestType()); - buttonManualManifest.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (buttonManualManifest.getSelection()) { - model.setManifestType(ManifestType.MANUAL); - } - } - }); - buttonManualManifest.setLayoutData(GridDataFactory.fillDefaults().create()); - } - - private void createFileGroup(Composite composite) { - fileGroup = new Group(composite, SWT.NONE); - fileGroup.setText("Workspace File"); - fileGroup.setLayout(new GridLayout(2, false)); - int height = DEFAULT_WORKSPACE_GROUP_HEIGHT; - try { - height = getDialogBoundsSettings().getInt(DIALOG_LIST_HEIGHT_SETTING); - } catch (NumberFormatException e) { - // ignore exception - } - fileGroup.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).hint(SWT.DEFAULT, height).create()); - - workspaceViewer = new TreeViewer(fileGroup); - workspaceViewer.setContentProvider(new BaseWorkbenchContentProvider() { - - @Override - public Object[] getChildren(Object element) { - Object[] children = super.getChildren(element); - if (element instanceof IFolder) { - IFolder folder = (IFolder) element; - if (folder.getParent() instanceof IProject) { - if (".settings".equals(folder.getName())) { - List filtered = new ArrayList<>(); - for (Object child : children) { - if (child instanceof IFile) { - // Skip the temporary manifest file for manual mode - IFile f = (IFile) child; - if (DeploymentPropertiesDialogModel.DUMMY_MANUAL_MANIFEST_YML.equals(f.getName()) - || DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML.equals(f.getName())) { - continue; - } - } - filtered.add(child); - } - children = filtered.toArray(new Object[filtered.size()]); - } - } - } - if (element instanceof IProject) { - IJavaProject javaProject = JavaCore.create((IProject)element); - if (javaProject != null) { - List filtered = new ArrayList<>(); - for (Object child : children) { - // Filter out obvious output folders - if (child instanceof IFolder) { - IFolder folder = (IFolder) child; - if ("target".equals(folder.getName()) || "bin".equals(folder.getName())) { - continue; - } - } - filtered.add(child); - } - children = filtered.toArray(new Object[filtered.size()]); - } - } - return children; - } - - }); - workspaceViewer.setLabelProvider(new WorkbenchLabelProvider()); - workspaceViewer.setInput(ResourcesPlugin.getWorkspace().getRoot()); - workspaceViewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create()); - - /* - * Do not set the selection based on manifest file changes outside of UI. Bad. SWT doesn't like it. - */ - if (model.getSelectedManifest() != null) { - workspaceViewer.setSelection(new StructuredSelection(new Object[] { model.getSelectedManifest() }), true); - } - - workspaceViewer.addSelectionChangedListener(selectionListener); - - Composite fileButtonsComposite = new Composite(fileGroup, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.horizontalSpacing = 0; - layout.verticalSpacing = 0; - fileButtonsComposite.setLayout(layout); - fileButtonsComposite.setLayoutData(GridDataFactory.fillDefaults().create()); - - refreshButton = new Button(fileButtonsComposite, SWT.PUSH); - refreshButton.setImage(BootDashActivator.getDefault().getImageRegistry().get(BootDashActivator.REFRESH_ICON)); - refreshButton.setText("Refresh"); - refreshButton.setEnabled(false); - refreshButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - refreshManifests(); - } - }); - refreshButton.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); - - fileFilterCombo = new Combo(fileGroup, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); - fileFilterCombo.setItems(FILE_FILTER_NAMES); - int selectionIndex = 0; - - IResource manifestFile = model.getSelectedManifest(); - if (manifestFile != null) { - selectionIndex = RESOURCE_FILTERS.length - 1; - for (int i = 0; i < RESOURCE_FILTERS.length; i++) { - boolean accept = true; - for (ViewerFilter filter : RESOURCE_FILTERS[i]) { - accept = filter.select(null, null, manifestFile); - if (!accept) { - break; - } - } - if (accept) { - selectionIndex = i; - break; - } - } - } - workspaceViewer.setFilters(RESOURCE_FILTERS[selectionIndex]); - fileFilterCombo.select(selectionIndex); - fileFilterCombo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - // Remove selection listener to set selection from current pathModel value - workspaceViewer.removeSelectionChangedListener(selectionListener); - workspaceViewer.setFilters(RESOURCE_FILTERS[fileFilterCombo.getSelectionIndex()]); - // Add the selection listener back after the initial value has been set - workspaceViewer.addSelectionChangedListener(selectionListener); - } - }); - } - - private void createResizeSash(Composite composite) { - resizeSash = new Sash(composite, SWT.HORIZONTAL); - resizeSash.setLayoutData(GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 4).grab(true, false).create()); - resizeSash.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - GridData listLayoutData = (GridData) fileGroup.getLayoutData(); - int newHeight = listLayoutData.heightHint + e.y - resizeSash.getBounds().y; - if (newHeight < listLayoutData.minimumHeight) { - newHeight = listLayoutData.minimumHeight; - e.doit = false; - } - listLayoutData.heightHint = newHeight; - fileGroup.setLayoutData(listLayoutData); - fileGroup.getParent().layout(); - } - }); - } - - private void createYamlContentsGroup(Composite composite) { - yamlGroup = new Group(composite, SWT.NONE); - yamlGroup.setText("YAML Content"); - yamlGroup.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create()); - yamlGroup.setLayout(new GridLayout()); - - fileYamlComposite = new Composite(yamlGroup, SWT.NONE); - fileYamlComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create()); - GridLayout layout = new GridLayout(3, false); - layout.marginWidth = 0; - fileYamlComposite.setLayout(layout); - - fileLabel = new Label(fileYamlComposite, SWT.WRAP); - fileLabel.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).span(3, SWT.DEFAULT).create()); - - model.getFileLabel().addListener(new UIValueListener() { - @Override - protected void uiGotValue(LiveExpression exp, String value) { - if (!fileLabel.isDisposed()) { - fileLabel.setText(exp.getValue()); - } - } - }); - - model.getFileYamlEditor().setContext(CONTEXT_DEPLOYMENT_PROPERTIES_DIALOG); - try { - model.getFileYamlEditor().createControl(fileYamlComposite); - } catch (CoreException e) { - Log.log(e); - } - model.getFileYamlEditor().getViewer().getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 200).create()); - model.fileYamlEditorControlCreated(); - - - manualYamlComposite = new Composite(yamlGroup, SWT.NONE); - manualYamlComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create()); - layout = new GridLayout(); - layout.marginWidth = 0; - manualYamlComposite.setLayout(layout); - - Label manualYamlDescriptionLabel = new Label(manualYamlComposite, SWT.WRAP); - manualYamlDescriptionLabel.setText(model.isManualManifestReadOnly() ? "Preview of the contents of the auto-generated deployment manifest:" : "Edit deployment manifest contents:"); - manualYamlDescriptionLabel.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); - - - model.getManualYamlEditor().setContext(CONTEXT_DEPLOYMENT_PROPERTIES_DIALOG); - try { - model.getManualYamlEditor().createControl(manualYamlComposite); - } catch (CoreException e) { - Log.log(e); - } - model.getManualYamlEditor().getViewer().getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 200).create()); - ProjectionViewer manualYamlViewer = model.getManualYamlEditor().getViewer(); - if (model.isManualManifestReadOnly()) { - manualYamlViewer.setEditable(false); - manualYamlViewer.getTextWidget().setCaret(null); - manualYamlViewer.getTextWidget().setCursor(getShell().getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); - } - model.manualYamlEditorControlCreated(); - - /* - * Set the proper Font on the YAML viewers - */ - model.getFileYamlEditor().getViewer().getTextWidget().setFont(JFaceResources.getTextFont()); - manualYamlViewer.getTextWidget().setFont(JFaceResources.getTextFont()); - } - - private void activateHandlers() { - if (service != null) { - for (EditorActionHandler handler : handlers) { - activations.add(service.activateHandler(handler.getActionId(), handler)); - } - } - } - - private void deactivateHandlers() { - if (service != null) { - for (IHandlerActivation activation : activations) { - service.deactivateHandler(activation); - } - activations.clear(); - } - } - - private void refreshManifests() { - IResource selectedResource = (IResource) ((IStructuredSelection) workspaceViewer.getSelection()).getFirstElement(); - final IResource resourceToRefresh = selectedResource instanceof IFile ? selectedResource.getParent() : selectedResource; - Job job = new Job("Refreshing resources for '" + resourceToRefresh.getName() + "'") { - @Override - protected IStatus run(IProgressMonitor monitor) { - IStatus status = Status.OK_STATUS; - try { - resourceToRefresh.refreshLocal(IResource.DEPTH_INFINITE, monitor); - } catch (CoreException e) { - status = e.getStatus(); - } - getParentShell().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - // Remove selection listener to set selection from current pathModel value - workspaceViewer.removeSelectionChangedListener(selectionListener); - workspaceViewer.refresh(resourceToRefresh); - // Add the selection listener back after the initial value has been set - workspaceViewer.addSelectionChangedListener(selectionListener); - } - }); - return status; - } - }; - job.setRule(resourceToRefresh); - job.schedule(); - } - - @Override - protected boolean isResizable() { - return true; - } - - @Override - protected IDialogSettings getDialogBoundsSettings() { - return DialogSettings.getOrCreateSection(BootDashActivator.getDefault().getDialogSettings(), "ManifestFileDialog"); - } - - @Override - public boolean close() { - if (getReturnCode() == IDialogConstants.CANCEL_ID) { - model.cancelPressed(); - } else { - if (!model.okPressed()) { - return false; - } - } - getDialogBoundsSettings().put(DIALOG_LIST_HEIGHT_SETTING, ((GridData)fileGroup.getLayoutData()).heightHint); - boolean close = super.close(); - dispose(); - return close; - } - - protected void dispose() { - /* - * Deactivate handlers for key bindings - */ - deactivateHandlers(); - - model.dispose(); - } - - // TODO: this should be replaced with TreeViewer.getStructuredSelection once we drop support for Eclipse 4.4 - // the TreeViewer.getStructuredSelection() API got introduced in Eclipse 4.5 - private ITreeSelection getStructuredSelection(TreeViewer treeViewer) { - ISelection selection = treeViewer.getSelection(); - if (selection instanceof ITreeSelection) { - return (ITreeSelection) selection; - } - throw new ClassCastException("AbstractTreeViewer should return an instance of ITreeSelection from its getSelection() method."); //$NON-NLS-1$ - } - - @Override - protected int getDialogBoundsStrategy() { - return DIALOG_PERSISTSIZE; - } - - @Override - protected Point getInitialSize() { - Point size = super.getInitialSize(); - /* - * If manual mode is selected fileGroup is missing and not accounted in - * the size of the dialog shell. Add its height here manually if dialog - * size was not persisted previously - */ - GridData fileGroupLayoutData = (GridData)fileGroup.getLayoutData(); - if (fileGroupLayoutData.exclude) { - try { - /* - * Hack: check if dialog width/height was persisted. If - * persisted then no need to calculate dialog size - */ - getDialogBoundsSettings().getInt("DIALOG_WIDTH"); - } catch (NumberFormatException e) { - /* - * Exception is thrown if dialog width/height cannot be read - * from storage - */ - size.y += fileGroupLayoutData.heightHint; - } - } - return size; - } - - private class EditorActionHandler extends AbstractHandler { - - private String actionId; - private int operationId; - - public EditorActionHandler(String actionId, int operationId) { - super(); - this.actionId = actionId; - this.operationId = operationId; - } - - public String getActionId() { - return actionId; - } - - @Override - public Object execute(ExecutionEvent arg0) throws ExecutionException { - ProjectionViewer manualYamlViewer = model.getManualYamlEditor().getViewer(); - ProjectionViewer fileYamlViewer = model.getFileYamlEditor().getViewer(); - if (manualYamlViewer.isEditable() && manualYamlViewer.getControl().isVisible() - && manualYamlViewer.getTextWidget().isFocusControl()) { - manualYamlViewer.doOperation(operationId); - } else if (fileYamlViewer.isEditable() && fileYamlViewer.getControl().isVisible() - && fileYamlViewer.getTextWidget().isFocusControl()) { - fileYamlViewer.doOperation(operationId); - } - return null; - } - } - - public static IFile findManifestYamlFile(IProject project) { - if (project == null) { - return null; - } - IFile file = project.getFile("manifest.yml"); - if (file.exists()) { - return file; - } - IFile yamlFile = null; - try { - for (IResource r : project.members()) { - if (r instanceof IFile) { - file = (IFile) r; - if (MANIFEST_YAML_FILE_FILTER.select(null, project, file)) { - return file; - } else if (YAML_FILE_FILTER.select(null, project, file)) { - yamlFile = file; - } - } - } - } catch (CoreException e) { - // ignore - } - return yamlFile; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/DeploymentPropertiesDialogModel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/DeploymentPropertiesDialogModel.java deleted file mode 100644 index d0e2308c0..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/DeploymentPropertiesDialogModel.java +++ /dev/null @@ -1,973 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 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.cf.dialogs; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.jdt.internal.ui.JavaPlugin; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.source.Annotation; -import org.eclipse.jface.text.source.AnnotationModelEvent; -import org.eclipse.jface.text.source.IAnnotationModel; -import org.eclipse.jface.text.source.IAnnotationModelListener; -import org.eclipse.jface.text.source.IAnnotationModelListenerExtension; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IPropertyListener; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.internal.genericeditor.ExtensionBasedTextViewerConfiguration; -import org.eclipse.ui.part.FileEditorInput; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.AppNameAnnotation; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.AppNameAnnotationModel; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.AppNameAnnotationSupport; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.ApplicationManifestHandler; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudData; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.launch.properties.EmbeddedEditor; -import org.springsource.ide.eclipse.commons.livexp.core.AbstractDisposable; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; -import org.springsource.ide.eclipse.commons.livexp.core.Validator; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; -import org.springsource.ide.eclipse.commons.livexp.util.Log; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.DumperOptions.FlowStyle; -import org.yaml.snakeyaml.constructor.SafeConstructor; -import org.yaml.snakeyaml.representer.Representer; -import org.yaml.snakeyaml.Yaml; - -@SuppressWarnings("restriction") -public class DeploymentPropertiesDialogModel extends AbstractDisposable { - - public static final String LSP_ERROR_ANNOTATION_TYPE = "org.eclipse.ui.workbench.texteditor.error"; - - public static final String DUMMY_FILE_MANIFEST_YML = ".file-manifest.yml"; - public static final String DUMMY_MANUAL_MANIFEST_YML = ".manual-manifest.yml"; - public static final String UNKNOWN_DEPLOYMENT_MANIFEST_TYPE_MUST_BE_EITHER_FILE_OR_MANUAL = "Unknown deployment manifest type. Must be either 'File' or 'Manual'."; - public static final String NO_SUPPORT_TO_DETERMINE_APP_NAMES = "Support for determining application names is unavailable"; - public static final String MANIFEST_DOES_NOT_CONTAIN_DEPLOYMENT_PROPERTIES_FOR_APPLICATION_WITH_NAME = "Manifest does not contain deployment properties for application with name ''{0}''."; - public static final String APPLICATION_NAME_NOT_SELECTED = "Application name not selected"; - public static final String MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED = "Manifest does not have any application defined."; - public static final String ENTER_DEPLOYMENT_MANIFEST_YAML_MANUALLY = "Enter deployment manifest YAML manually."; - public static final String CURRENT_GENERATED_DEPLOYMENT_MANIFEST = "Current generated deployment manifest."; - public static final String CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM = "Choose an existing deployment manifest YAML file from the local file system."; - public static final String DEPLOYMENT_MANIFEST_FILE_NOT_SELECTED = "Deployment manifest file not selected."; - public static final String MANIFEST_YAML_ERRORS = "Deployment manifest YAML has errors."; - - public static enum ManifestType { - FILE, - MANUAL - } - - private UserInteractions ui; - - private abstract class AbstractSubModel extends AbstractDisposable { - - EmbeddedEditor editor; - - AppNameAnnotationSupport appNameAnnotationSupport; - - final LiveVariable editorControlCreated; - - final LiveVariable selectedFile; - - final LiveExpression editorInput; - - LiveExpression appNameAnnotationModel; - - LiveExpression resourceAnnotationModel; - - LiveExpression> applicationNames; - - LiveExpression errorsInYaml; - - LiveExpression selectedAppName; - - /** - * When dialog closed and viewer disposed live expression would still keep the document which will be used to detrmine DeploymentProperties - */ - final LiveExpression document; - - protected IFile getFile() { - IResource r = selectedFile.getValue(); - return r instanceof IFile ? (IFile) r : null; - } - - protected void saveOrDiscardIfNeeded() { - FileEditorInput input = editorInput.getValue(); - if (input != null) { - saveOrDiscardIfNeeded(input); - } - } - - protected void saveOrDiscardIfNeeded(FileEditorInput file) { - if (editor.isDirty()) { - if (ui.confirmOperation("Changes Detected", "Manifest file '" + file.getFile().getFullPath().toOSString() - + "' has been changed. Do you want to save changes or discard them?", new String[] {"Save", "Don't Save"}, 0) == 0) { - editor.doSave(new NullProgressMonitor()); - } - } - } - - abstract String getManifestContents(); - - /** - * Return manifest from which contents are takes as an {@link IFile} - * Return null if manifest content doesn't come from a file - * @return - */ - abstract IFile getManifest(); - - CloudApplicationDeploymentProperties getDeploymentProperties() throws Exception { - CloudApplicationDeploymentProperties deploymentProperties = toDeploymentProperties(cloudData, - getManifestContents(), project, - deployedApp == null ? selectedAppName.getValue() : getDeployedAppName()); - if (deploymentProperties != null) { - deploymentProperties.setManifestFile(getManifest()); - } - return deploymentProperties; - } - - protected AbstractSubModel(String fixedAppName) { - IPreferenceStore preferenceStore = JavaPlugin.getDefault().getCombinedPreferenceStore(); - this.editor = new EmbeddedEditor(editor -> new ExtensionBasedTextViewerConfiguration(editor, preferenceStore), preferenceStore, false, true); - - editorControlCreated = new LiveVariable<>(false); - - selectedFile = new LiveVariable<>(); - - editorControlCreated.addListener((exp, value) -> { - if (appNameAnnotationSupport == null && value != null && value.booleanValue()) { - appNameAnnotationSupport = new AppNameAnnotationSupport(editor.getViewer(), - editor.getAnnotationAccess(), editor.getSharedColors(), fixedAppName); - } - }); - - editorInput = new LiveExpression() { - - { - dependsOn(selectedFile); - } - - @Override - protected FileEditorInput compute() { - if (editor != null) { - IFile file = getFile(); - FileEditorInput currentInput = getValue(); - boolean changed = currentInput == null || !currentInput.getFile().equals(file); - if (changed) { - if (currentInput != null) { - saveOrDiscardIfNeeded(currentInput); - } - try { - if (file != null) { - FileEditorInput input = new FileEditorInput(file); - editor.setInput(input); - return input; - } else { - editor.setInput(null); - return null; - } - } catch (CoreException e) { - Log.log(e); - } - } - } - return null; - } - - }; - - appNameAnnotationModel = new LiveExpression() { - { - dependsOn(editorControlCreated); - dependsOn(editorInput); - } - - @Override - protected AppNameAnnotationModel compute() { - if (editor != null && editor.getViewer() != null) { - return AppNameAnnotationSupport.getAppNameAnnotationModel(editor.getViewer()); - } - return null; - } - - }; - - resourceAnnotationModel = new LiveExpression() { - - { - dependsOn(editorControlCreated); - dependsOn(editorInput); - } - - @Override - protected IAnnotationModel compute() { - if (editor != null && editor.getViewer() != null) { - return editor.getViewer().getAnnotationModel(); - } - return null; - } - - }; - - applicationNames = new LiveExpression>() { - - private AppNameAnnotationModel attachedTo = null; - private AnnotationModelListener listener = new AnnotationModelListener() { - @Override - public void modelChanged(AnnotationModelEvent event) { - refresh(); - } - }; - - { - dependsOn(appNameAnnotationModel); - } - - @Override - protected List compute() { - AppNameAnnotationModel annotationModel = appNameAnnotationModel.getValue(); - if (annotationModel != null) { - attachListener(annotationModel); - List applicationNames = new ArrayList<>(); - for (Iterator itr = annotationModel.getAnnotationIterator(); itr.hasNext();) { - Annotation next = itr.next(); - if (next instanceof AppNameAnnotation) { - AppNameAnnotation a = (AppNameAnnotation) next; - applicationNames.add(a.getText()); - } - } - return applicationNames; - } - return Collections.emptyList(); - } - - synchronized private void attachListener(AppNameAnnotationModel annotationModel) { - if (attachedTo == annotationModel) { - return; - } - if (attachedTo != null) { - attachedTo.removeAnnotationModelListener(listener); - } - if (annotationModel != null) { - annotationModel.addAnnotationModelListener(listener); - } - attachedTo = annotationModel; - } - - }; - - errorsInYaml = new LiveExpression() { - - private IAnnotationModel attachedTo = null; - private AnnotationModelListener listener = new AnnotationModelListener() { - @Override - public void modelChanged(AnnotationModelEvent event) { - refresh(); - } - }; - - { - dependsOn(resourceAnnotationModel); - } - - { - onDispose((d) -> { - if (attachedTo != null) { - attachedTo.removeAnnotationModelListener(listener); - } - }); - } - - @Override - protected Boolean compute() { - IAnnotationModel annotationModel = resourceAnnotationModel.getValue(); - if (annotationModel != null) { - attachListener(annotationModel); - for (Iterator itr = annotationModel.getAnnotationIterator(); itr.hasNext();) { - Annotation next = itr.next(); - if (LSP_ERROR_ANNOTATION_TYPE.equals(next.getType())) { - return Boolean.TRUE; - } - } - } - return Boolean.FALSE; - } - - synchronized private void attachListener(IAnnotationModel annotationModel) { - if (attachedTo == annotationModel) { - return; - } - if (attachedTo != null) { - attachedTo.removeAnnotationModelListener(listener); - } - if (annotationModel != null) { - annotationModel.addAnnotationModelListener(listener); - } - attachedTo = annotationModel; - } - }; - - selectedAppName = new LiveExpression() { - - private AppNameAnnotationModel attachedTo = null; - private AnnotationModelListener listener = new AnnotationModelListener() { - @Override - public void modelChanged(AnnotationModelEvent event) { - refresh(); - } - }; - - { - dependsOn(appNameAnnotationModel); - } - - { - onDispose((d) -> { - if (attachedTo != null) { - attachedTo.removeAnnotationModelListener(listener); - } - }); - } - - @Override - protected String compute() { - AppNameAnnotationModel annotationModel = appNameAnnotationModel.getValue(); - if (annotationModel != null) { - attachListener(annotationModel); - AppNameAnnotation a = annotationModel.getSelectedAppAnnotation(); - if (a != null) { - return a.getText(); - } - } - return null; - } - - synchronized private void attachListener(AppNameAnnotationModel annotationModel) { - if (attachedTo == annotationModel) { - return; - } - if (attachedTo != null) { - attachedTo.removeAnnotationModelListener(listener); - } - if (annotationModel != null) { - annotationModel.addAnnotationModelListener(listener); - } - attachedTo = annotationModel; - } - - }; - - document = new LiveExpression(new Document("")) { - { - dependsOn(editorInput); - dependsOn(editorControlCreated); - } - - @Override - protected IDocument compute() { - IDocument doc = editor == null || editor.getViewer() == null ? null : editor.getViewer().getDocument(); - return doc; - } - }; - - onDispose((d) -> { - appNameAnnotationSupport.dispose(); - editorControlCreated.dispose(); - editorInput.dispose(); - applicationNames.dispose(); - appNameAnnotationModel.dispose(); - errorsInYaml.dispose(); - resourceAnnotationModel.dispose(); - selectedAppName.dispose(); - document.dispose(); - editor.dispose(); - }); - } - - } - - public class FileDeploymentPropertiesDialogModel extends AbstractSubModel { - - final private LiveExpression fileLabel = new LiveExpression() { - { - dependsOn(editorInput); - } - - @Override - protected String compute() { - FileEditorInput input = editorInput.getValue(); - if (input != null) { - return editorInput.getValue().getFile().getFullPath().toOSString() + (editor.isDirty() ? "*" : ""); - } - return ""; - } - - }; - - private final IPropertyListener editorListener = (Object source, int propId) -> { - if (propId == IEditorPart.PROP_DIRTY) { - fileLabel.refresh(); - } - }; - - Validator validator = new Validator() { - - { - dependsOn(editorInput); - dependsOn(appNameAnnotationModel); - dependsOn(errorsInYaml); - dependsOn(applicationNames); - dependsOn(selectedAppName); - } - - @Override - protected ValidationResult compute() { - ValidationResult result = ValidationResult.OK; - - if (editorInput.getValue() == null) { - result = ValidationResult.error(DEPLOYMENT_MANIFEST_FILE_NOT_SELECTED); - } - - if (result.isOk()) { - AppNameAnnotationModel appNamesModel = appNameAnnotationModel.getValue(); - if (appNamesModel == null) { - result = ValidationResult.error(NO_SUPPORT_TO_DETERMINE_APP_NAMES); - } - if (result.isOk()) { - String appName = getDeployedAppName(); - if (applicationNames.getValue().isEmpty()) { - result = ValidationResult.error(MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED); - } else { - if (errorsInYaml.getValue().booleanValue()) { - result = ValidationResult.error(MANIFEST_YAML_ERRORS); - } else { - String selectedAnnotation = selectedAppName.getValue(); - if (appName == null) { - if (selectedAnnotation == null) { - result = ValidationResult.error(APPLICATION_NAME_NOT_SELECTED); - } - } else { - if (selectedAnnotation == null || !appName.equals(selectedAnnotation)) { - result = ValidationResult.error(MessageFormat.format( - MANIFEST_DOES_NOT_CONTAIN_DEPLOYMENT_PROPERTIES_FOR_APPLICATION_WITH_NAME, - appName)); - } - } - } - } - } - } - - if (result.isOk()) { - result = ValidationResult.info(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM); - } - - return result; - } - - }; - - private IFile tempFile; - - { - onDispose((d) -> { - if (tempFile != null && tempFile.exists()) { - try { - tempFile.delete(true, new NullProgressMonitor()); - } catch (CoreException e) { - Log.log(e); - } - } - editor.removePropertyListener(editorListener); - validator.dispose(); - fileLabel.dispose(); - }); - } - - FileDeploymentPropertiesDialogModel(String fixedAppName) { - super(fixedAppName); - editor.addPropertyListener(editorListener); - } - - public void init(IFile tempFile) { - this.tempFile = tempFile; - if (getManifest() == null) { - // No manifest file? Generate dumb empty manifest YAML to get proper Manifest LS - // based reconciler, CA etc - try { - generateTempManifestFile(tempFile, ""); - editor.init(null, new FileEditorInput(tempFile)); - } catch (CoreException e) { - Log.log(e); - } - } - } - - public IAnnotationModel getAnnotationModel() { - return editor.getViewer().getAnnotationModel(); - } - - @Override - String getManifestContents() { - return document.getValue().get(); - } - - @Override - IFile getManifest() { - return getFile(); - } - - void reopenSameFile() { - document.refresh(); - } - - } - - public class ManualDeploymentPropertiesDialogModel extends AbstractSubModel { - - private IFile tempFile; - - private boolean readOnly; - - Validator validator = new Validator() { - - { - dependsOn(appNameAnnotationModel); - dependsOn(errorsInYaml); - dependsOn(applicationNames); - dependsOn(selectedAppName); - } - - @Override - protected ValidationResult compute() { - ValidationResult result = ValidationResult.OK; - - AppNameAnnotationModel appNamesModel = appNameAnnotationModel.getValue(); - if (appNamesModel == null) { - result = ValidationResult.error(NO_SUPPORT_TO_DETERMINE_APP_NAMES); - } - if (result.isOk()) { - String appName = getDeployedAppName(); - if (applicationNames.getValue().isEmpty()) { - result = ValidationResult.error(MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED); - } else { - if (errorsInYaml.getValue().booleanValue()) { - result = ValidationResult.error(MANIFEST_YAML_ERRORS); - } else { - String selectedAnnotation = selectedAppName.getValue(); - if (appName == null) { - if (selectedAnnotation == null) { - result = ValidationResult.error(APPLICATION_NAME_NOT_SELECTED); - } - } else { - if (selectedAnnotation == null || !appName.equals(selectedAnnotation)) { - result = ValidationResult.error(MessageFormat.format( - MANIFEST_DOES_NOT_CONTAIN_DEPLOYMENT_PROPERTIES_FOR_APPLICATION_WITH_NAME, - appName)); - } - } - } - } - } - - if (result.isOk()) { - result = ValidationResult.info(readOnly ? CURRENT_GENERATED_DEPLOYMENT_MANIFEST : ENTER_DEPLOYMENT_MANIFEST_YAML_MANUALLY); - } - - return result; - } - }; - - { - onDispose((d) -> { - validator.dispose(); - try { - if (tempFile != null) { - if (tempFile.exists()) { - tempFile.delete(true, new NullProgressMonitor()); - } - tempFile = null; - } - } catch (CoreException e) { - e.printStackTrace(); - } - }); - } - - - ManualDeploymentPropertiesDialogModel(String fixedAppName, boolean readOnly) { - super(fixedAppName); - this.readOnly = readOnly; - } - - public void init(IFile tempFile) { - this.tempFile = tempFile; - try { - generateTempManifestFile(tempFile, generateDefaultContent()); - } catch (CoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - try { - editor.init(null, new FileEditorInput(tempFile)); - selectedFile.setValue(tempFile); - } catch (PartInitException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public void setText(String s) { - if (readOnly) { - throw new IllegalStateException("The model is read-only!"); - } - IDocument doc = document.getValue(); - if (doc != null) { - doc.set(s); - } - } - - public String getText() { - IDocument doc = document.getValue(); - return doc == null ? null : doc.get(); - } - - public IAnnotationModel getAnnotationModel() { - return editor.getViewer().getAnnotationModel(); - } - - @Override - String getManifestContents() { - return getText(); - } - - @Override - IFile getManifest() { - return null; - } - - } - - private abstract class AnnotationModelListener implements IAnnotationModelListener, IAnnotationModelListenerExtension { - - @Override - public void modelChanged(IAnnotationModel model) { - // Leave empty. AnnotationModelEvent method is the one that will be called - } - - @Override - abstract public void modelChanged(AnnotationModelEvent event); - - } - - - final public LiveVariable type = new LiveVariable<>(); - final public LiveVariable enableJmxSshTunnel = new LiveVariable<>(); - - final private CFApplication deployedApp; - - final private CloudData cloudData; - - final IProject project; - - final private FileDeploymentPropertiesDialogModel fileModel; - - final private ManualDeploymentPropertiesDialogModel manualModel; - - private boolean isCancelled = false; - - final private Validator validator; - - final public boolean supportsSsh; - - public DeploymentPropertiesDialogModel(UserInteractions ui, CloudData cloudData, IProject project, CFApplication deployedApp, boolean supportsSsh) { - super(); - this.supportsSsh = supportsSsh; - this.ui = ui; - this.deployedApp = deployedApp; - this.cloudData = cloudData; - this.project = project; - this.manualModel = new ManualDeploymentPropertiesDialogModel(getDeployedAppName(), deployedApp != null); - this.fileModel = new FileDeploymentPropertiesDialogModel(getDeployedAppName()); - - this.validator = new Validator() { - - { - dependsOn(type); - dependsOn(fileModel.validator); - dependsOn(manualModel.validator); - } - - @Override - protected ValidationResult compute() { - if (isFileManifestType()) { - return fileModel.validator.getValue(); - } else if (isManualManifestType()) { - return manualModel.validator.getValue(); - } else { - return ValidationResult.error(UNKNOWN_DEPLOYMENT_MANIFEST_TYPE_MUST_BE_EITHER_FILE_OR_MANUAL); - } - } - - }; - - onDispose((d) -> { - fileModel.dispose(); - manualModel.dispose(); - }); - - } - - public void initFileModel() { - fileModel.init(project.getFolder(".settings").getFile(DUMMY_FILE_MANIFEST_YML)); - } - - public void initManualModel() { - manualModel.init(project.getFolder(".settings").getFile(DUMMY_MANUAL_MANIFEST_YML)); - } - - public CloudApplicationDeploymentProperties getDeploymentProperties() throws Exception { - if (isCancelled) { - throw new OperationCanceledException(); - } - if (type.getValue() == null) { - return null; - } - CloudApplicationDeploymentProperties props = null; - switch (type.getValue()) { - case FILE: - props = fileModel.getDeploymentProperties(); - break; - case MANUAL: - props = manualModel.getDeploymentProperties(); - break; - default: - } - if (props!=null) { - Boolean enableJmx = enableJmxSshTunnel.getValue(); - props.setEnableJmxSshTunnel(enableJmx!=null && enableJmx); - } - return props; - } - - public void cancelPressed() { - fileModel.saveOrDiscardIfNeeded(); - isCancelled = true; -// try { -// fileModel.editor.setInput(null); -// manualModel.editor.setInput(null); -// } catch (CoreException e) { -// Log.log(e); -// } - } - - public boolean okPressed() { - fileModel.saveOrDiscardIfNeeded(); - isCancelled = false; - try { - CloudApplicationDeploymentProperties deploymentProperties = getDeploymentProperties(); -// fileModel.editor.setInput(null); -// manualModel.editor.setInput(null); - return deploymentProperties != null; - } catch (Exception e) { - fileModel.reopenSameFile(); - ui.errorPopup("Invalid YAML content", ExceptionUtil.getMessage(e)); - return false; - } - } - - public void setSelectedManifest(IResource manifest) { - fileModel.selectedFile.setValue(manifest); - } - - public void setManualManifest(String manifestText) { - manualModel.setText(manifestText); - } - - public void setManifestType(ManifestType type) { - this.type.setValue(type); - } - - public String getProjectName() { - return project.getName(); - } - - public IProject getProject() { - return project; - } - - public boolean isFileManifestType() { - return type.getValue() == ManifestType.FILE; - } - - public boolean isManualManifestType() { - return type.getValue() == ManifestType.MANUAL; - } - - public IResource getSelectedManifest() { - return fileModel.selectedFile.getValue(); - } - - public String getDeployedAppName() { - return deployedApp == null ? null : deployedApp.getName(); - } - - public EmbeddedEditor getFileYamlEditor() { - return fileModel.editor; - } - - public EmbeddedEditor getManualYamlEditor() { - return manualModel.editor; - } - - public IDocument getManualDocument() { - return manualModel.document.getValue(); - } - - public boolean isManualManifestReadOnly() { - return deployedApp!=null; - } - - public IDocument getFileDocument() { - return fileModel.document.getValue(); - } - - public LiveExpression getFileEditorInput() { - return fileModel.editorInput; - } - - public LiveExpression getFileLabel() { - return fileModel.fileLabel; - } - - private CFApplication getDeployedApp() { - return deployedApp; - } - - public boolean isCanceled() { - return isCancelled; - } - - public Validator getValidator() { - return validator; - } - - public LiveExpression getManualAppNameAnnotationModel() { - return manualModel.appNameAnnotationModel; - } - - public LiveExpression getFileAppNameAnnotationModel() { - return fileModel.appNameAnnotationModel; - } - - public void fileYamlEditorControlCreated() { - fileModel.editorControlCreated.setValue(true); - } - - public void manualYamlEditorControlCreated() { - manualModel.editorControlCreated.setValue(true); - } - - public IAnnotationModel getManualResourceAnnotationModel() { - return manualModel.resourceAnnotationModel.getValue(); - } - - public IAnnotationModel getFileResourceAnnotationModel() { - return fileModel.resourceAnnotationModel.getValue(); - } - - public String getFileSelectedAppName() { - return fileModel.selectedAppName.getValue(); - } - - public String getManualSelectedAppName() { - return manualModel.selectedAppName.getValue(); - } - - private String generateDefaultContent() { - CloudApplicationDeploymentProperties props = CloudApplicationDeploymentProperties.getFor(project, cloudData, - getDeployedApp()); - Map yaml = ApplicationManifestHandler.toYaml(props, cloudData); - DumperOptions options = new DumperOptions(); - options.setExplicitStart(true); - options.setCanonical(false); - options.setPrettyFlow(true); - options.setDefaultFlowStyle(FlowStyle.BLOCK); - return new Yaml(new SafeConstructor(), new Representer(options), options).dump(yaml); - } - - - private static IFile generateTempManifestFile(IFile manifestFile, String content) throws CoreException { - if (manifestFile.exists()) { - manifestFile.setContents(new ByteArrayInputStream(content.getBytes()), true, false, new NullProgressMonitor()); - } else { - if (!manifestFile.getParent().exists()) { - ((IFolder)manifestFile.getParent()).create(true, true, new NullProgressMonitor()); - } - manifestFile.create(new ByteArrayInputStream(content.getBytes()), true, new NullProgressMonitor()); - } - return manifestFile; - } - - public static CloudApplicationDeploymentProperties toDeploymentProperties(CloudData cloudData, String yaml, IProject project, String applicationName) throws Exception { - List propsList = new ApplicationManifestHandler(project, cloudData, null) { - @Override - protected InputStream getInputStream() throws Exception { - return new ByteArrayInputStream(yaml.getBytes()); - } - }.load(new NullProgressMonitor()); - /* - * If "Select Manifest..." action is invoked appName is not null, - * but we should allow for any manifest file selected for now. Hence - * set the applicationName var to null in that case - */ - CloudApplicationDeploymentProperties deploymentProperties = null; - if (applicationName == null) { - deploymentProperties = propsList.get(0); - } else { - for (CloudApplicationDeploymentProperties p : propsList) { - if (applicationName.equals(p.getAppName())) { - deploymentProperties = p; - break; - } - } - } - return deploymentProperties; - } - - public CloudApplicationDeploymentProperties getDeploymentProperties(String yaml, String appName) throws Exception { - if (yaml == null) { - yaml = generateDefaultContent(); - } - return toDeploymentProperties(cloudData, yaml, project, appName); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/OrgsAndSpaces.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/OrgsAndSpaces.java deleted file mode 100644 index 6b0c4df15..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/OrgsAndSpaces.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.dialogs; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.CoreException; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFOrganization; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; - -/** - * Hierarchical representation of existing orgs and spaces in a Cloud Foundry - * target. - * - */ -public class OrgsAndSpaces { - - private final List originalSpaces; - private Map> orgIDtoSpaces; - private Map orgIDtoOrg; - - /** - * - * @param spaces - * a flat list of all spaces for a given set of credentials and - * server URL. Should not be empty or null. - * @throws CoreException - * if given cloud server does not support orgs and spaces - */ - public OrgsAndSpaces(List spaces) { - this.originalSpaces = spaces; - setValues(); - } - - public CFSpace getSpace(String orgName, String spaceName) { - List oSpaces = orgIDtoSpaces.get(orgName); - if (oSpaces != null) { - for (CFSpace clSpace : oSpaces) { - if (clSpace.getName().equals(spaceName)) { - return clSpace; - } - } - } - return null; - } - - public List getOrgs() { - - Collection orgList = orgIDtoOrg.values(); - return new ArrayList(orgList); - } - - protected void setValues() { - orgIDtoSpaces = new HashMap>(); - orgIDtoOrg = new HashMap(); - - for (CFSpace clSpace : originalSpaces) { - CFOrganization org = clSpace.getOrganization(); - List spaces = orgIDtoSpaces.get(org.getName()); - if (spaces == null) { - spaces = new ArrayList(); - orgIDtoSpaces.put(org.getName(), spaces); - orgIDtoOrg.put(org.getName(), org); - } - - spaces.add(clSpace); - } - } - - /** - * @param orgName - * @return - */ - public List getOrgSpaces(String orgName) { - return orgIDtoSpaces.get(orgName); - } - - /** - * @return all spaces available for the given account. Never null, although - * may be empty if no spaces are resolved. - */ - public List getAllSpaces() { - return originalSpaces != null ? new ArrayList(originalSpaces) : new ArrayList(0); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/OrgsAndSpacesWizard.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/OrgsAndSpacesWizard.java deleted file mode 100644 index ee55f6171..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/OrgsAndSpacesWizard.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.dialogs; - -import org.eclipse.jface.wizard.Wizard; - -/** - * Creates a new server instance from a selected space in an organization and - * spaces viewer in the wizard. It only creates the server instance if another - * server instance to that space does not exist. - */ -public class OrgsAndSpacesWizard extends Wizard { - - private OrgsAndSpacesWizardPage cloudSpacePage; - - private CloudFoundryTargetWizardModel properties; - - public OrgsAndSpacesWizard( - CloudFoundryTargetWizardModel targetProperties) { - cloudSpacePage = new OrgsAndSpacesWizardPage(targetProperties); - this.properties = targetProperties; - setWindowTitle("Select space for: " + targetProperties.getUrl()); - setNeedsProgressMonitor(true); - } - - @Override - public void addPages() { - cloudSpacePage.setWizard(this); - addPage(cloudSpacePage); - } - - @Override - public boolean performFinish() { - return properties.getSpaceName() != null && properties.getOrganizationName() != null; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/OrgsAndSpacesWizardPage.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/OrgsAndSpacesWizardPage.java deleted file mode 100644 index ea868908b..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/OrgsAndSpacesWizardPage.java +++ /dev/null @@ -1,273 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.dialogs; - -import java.util.List; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerSorter; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeItem; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFEntity; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFOrganization; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; -import org.springsource.ide.eclipse.commons.livexp.core.ValueListener; - -/** - * Wizard page to allow users to select a target cloud space when cloning an - * existing server. - */ -class OrgsAndSpacesWizardPage extends WizardPage implements ValueListener { - - protected TreeViewer orgsSpacesViewer; - - private final CloudFoundryTargetWizardModel targetProperties; - - private final OrgsAndSpaces spaces; - - private boolean canFinish = false; - - OrgsAndSpacesWizardPage(CloudFoundryTargetWizardModel targetWizardModel) { - super("Select an Org and Space"); - setTitle("Select an Org and Space"); - setDescription("Select a space in " + targetWizardModel.getUrl()); - this.setImageDescriptor(BootDashActivator.getImageDescriptor("icons/wizban_cloudfoundry.png")); - this.targetProperties = targetWizardModel; - this.spaces = targetWizardModel.getSpaces(); - targetWizardModel.getValidator().addListener(this); - } - - @Override - public void dispose() { - this.targetProperties.getValidator().removeListener(this); - super.dispose(); - } - - @Override - public boolean isPageComplete() { - return canFinish && targetProperties.getSpaceName() != null && targetProperties.getOrganizationName() != null; - } - - @Override - public void createControl(Composite parent) { - Composite mainComposite = new Composite(parent, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(mainComposite); - GridDataFactory.fillDefaults().grab(true, true).applyTo(mainComposite); - - Label orgLabel = new Label(mainComposite, SWT.NONE); - GridDataFactory.fillDefaults().grab(false, false).applyTo(orgLabel); - orgLabel.setText("Orgs:"); - - Tree orgTable = new Tree(mainComposite, SWT.BORDER | SWT.SINGLE); - - GridDataFactory.fillDefaults().grab(true, true).applyTo(orgTable); - - orgsSpacesViewer = new TreeViewer(orgTable); - - orgsSpacesViewer.setContentProvider(new TableContentProvider()); - orgsSpacesViewer.setLabelProvider(new SpacesLabelProvider()); - orgsSpacesViewer.setSorter(new SpacesSorter()); - - orgsSpacesViewer.addSelectionChangedListener(new ISelectionChangedListener() { - - public void selectionChanged(SelectionChangedEvent event) { - refresh(); - } - }); - - setControl(mainComposite); - - setInput(); - } - - public void setInput() { - List orgInput = spaces.getOrgs(); - - CFOrganization[] organizationInput = orgInput.toArray(new CFOrganization[orgInput.size()]); - orgsSpacesViewer.setInput(organizationInput); - - // Expand all first, so that child elements can be selected - orgsSpacesViewer.setExpandedElements(organizationInput); - - setInitialSelectionInViewer(); - } - - protected void setInitialSelectionInViewer() { - - CFSpace selectedSpace = spaces.getAllSpaces().get(0); - - if (selectedSpace != null) { - setSpaceInProperties(selectedSpace); - setSelectionInViewer(selectedSpace); - } - } - - protected void setSelectionInViewer(CFSpace selectedSpace) { - // Now set the cloud space in the tree - Tree tree = orgsSpacesViewer.getTree(); - TreeItem[] orgItems = tree.getItems(); - if (orgItems != null) { - TreeItem orgItem = null; - - // Find the tree item corresponding to the cloud space's - // org - for (TreeItem item : orgItems) { - Object treeObj = item.getData(); - if (treeObj instanceof CFOrganization - && ((CFOrganization) treeObj).getName().equals(selectedSpace.getOrganization().getName())) { - orgItem = item; - break; - - } - } - - if (orgItem != null) { - TreeItem[] children = orgItem.getItems(); - if (children != null) { - for (TreeItem childItem : children) { - Object treeObj = childItem.getData(); - if (treeObj instanceof CFSpace - && ((CFSpace) treeObj).getName().equals(selectedSpace.getName())) { - tree.select(childItem); - break; - } - } - } - } - } - } - - protected void refresh() { - if (orgsSpacesViewer != null) { - - Tree tree = orgsSpacesViewer.getTree(); - TreeItem[] selectedItems = tree.getSelection(); - if (selectedItems != null && selectedItems.length > 0) { - // It's a single selection tree, so only get the first selection - Object selectedObj = selectedItems[0].getData(); - setSpaceInProperties(selectedObj instanceof CFSpace ? (CFSpace) selectedObj : null); - } - } - refreshWizardUI(); - } - - protected void setSpaceInProperties(CFSpace selectedSpace) { - targetProperties.setSpace(selectedSpace); - } - - private void refreshWizardUI() { - if (getWizard() != null && getWizard().getContainer() != null) { - setPageComplete(targetProperties.getSpaceName() != null && targetProperties.getOrganizationName() != null); - - getWizard().getContainer().updateButtons(); - } - } - - static class SpacesSorter extends ViewerSorter { - - public SpacesSorter() { - - } - - public int compare(Viewer viewer, Object e1, Object e2) { - if (e1 instanceof CFEntity && e2 instanceof CFEntity) { - String name1 = ((CFEntity) e1).getName(); - String name2 = ((CFEntity) e2).getName(); - return name1.compareTo(name2); - } - - return super.compare(viewer, e1, e2); - } - - } - - class TableContentProvider implements ITreeContentProvider { - private Object[] elements; - - public TableContentProvider() { - } - - public void dispose() { - } - - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof CFOrganization) { - List children = spaces.getOrgSpaces(((CFOrganization) parentElement).getName()); - if (children != null) { - return children.toArray(new CFSpace[children.size()]); - } - } - return null; - } - - public Object[] getElements(Object inputElement) { - return elements; - } - - public Object getParent(Object element) { - return null; - } - - public boolean hasChildren(Object element) { - return false; - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (newInput instanceof Object[]) { - elements = (Object[]) newInput; - } - } - } - - static class SpacesLabelProvider extends LabelProvider { - - public SpacesLabelProvider() { - - } - - public String getText(Object element) { - if (element instanceof CFEntity) { - CFEntity cloudEntity = (CFEntity) element; - return cloudEntity.getName(); - } - return super.getText(element); - } - } - - @Override - public void gotValue(LiveExpression exp, ValidationResult value) { - value = exp.getValue(); - setErrorMessage(null); - canFinish = true; - if (value.status == IStatus.ERROR) { - setErrorMessage(value.msg); - canFinish = false; - } else { - setMessage(value.msg, value.status); - } - refreshWizardUI(); - } -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/PasswordDialogModel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/PasswordDialogModel.java deleted file mode 100644 index b1bec70d4..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/PasswordDialogModel.java +++ /dev/null @@ -1,232 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 2018 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.cf.dialogs; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.CloudFoundryClientFactory; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials.LoginMethod; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryTargetProperties; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; -import org.springsource.ide.eclipse.commons.livexp.core.Validator; -import org.springsource.ide.eclipse.commons.livexp.ui.OkButtonHandler; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -import reactor.core.publisher.Mono; - -/** - * Password dialog model. Provides ability to specify password and whether it - * needs to be stored. - * - * @author Alex Boyko - * @author Kris De Volder - */ -public class PasswordDialogModel implements OkButtonHandler { - - private static final ValidationResult REQUEST_VALIDATION_MESSAGE = ValidationResult.info( - "Click the 'Validate' button to verify the credentials."); - - private static final ValidationResult VALIDATION_IN_PROGRESS_MESSAGE = ValidationResult.info( - "Please wait. Contacting CF to verify the credentials..." - ); - - private CloudFoundryTargetProperties currentParams; - private CloudFoundryClientFactory clientFactory; - - private final LiveVariable refreshToken = new LiveVariable<>(); //This is set when credentials are succesfully validated. - private final LiveVariable needValidationRequest = new LiveVariable<>(true); - - private LiveVariable credentialsValidationResult; - final private LiveVariable fMethod; - final private LiveVariable fPasswordVar; - final private LiveVariable fStoreVar; - private boolean okButtonPressed = false; - private Validator passwordValidator; - private LiveExpression storeValidator; - - private void credentialsChangedHandler(LiveExpression exp, T value) { - needValidationRequest.setValue(true); - } - - public PasswordDialogModel(CloudFoundryClientFactory cfFactory, CloudFoundryTargetProperties currentParams, StoreCredentialsMode storeMode) { - super(); - this.clientFactory = cfFactory; - this.currentParams = currentParams; - fPasswordVar = new LiveVariable<>(""); - fStoreVar = new LiveVariable<>(storeMode); - fMethod = new LiveVariable<>(LoginMethod.PASSWORD); - storeValidator = makeStoreCredentialsValidator(getMethodVar(), fStoreVar); - credentialsValidationResult = new LiveVariable<>(REQUEST_VALIDATION_MESSAGE); - fMethod.addListener(this::credentialsChangedHandler); - fPasswordVar.addListener(this::credentialsChangedHandler); - } - - public String getUser() { - return currentParams.getUsername(); - } - - public String getTargetId() { - return CloudFoundryTargetProperties.getId(currentParams); - } - - public LiveVariable getPasswordVar() { - return fPasswordVar; - } - - public LiveVariable getStoreVar() { - return fStoreVar; - } - - public boolean isOk() { - return okButtonPressed; - } - - @Override - public void performOk() throws Exception { - okButtonPressed = true; - } - - public LiveExpression getPasswordValidator() { - if (passwordValidator==null) { - passwordValidator = new Validator() { - { - dependsOn(fPasswordVar); - dependsOn(needValidationRequest); - dependsOn(credentialsValidationResult); - } - @Override - protected ValidationResult compute() { - String pw = fPasswordVar.getValue(); - if (!StringUtil.hasText(pw)) { - return ValidationResult.error("Password can not be empty"); - } - if (needValidationRequest.getValue()) { - return REQUEST_VALIDATION_MESSAGE; - } - return credentialsValidationResult.getValue(); - } - }; - } - return passwordValidator; - } - - public LiveExpression getStoreValidator() { - return storeValidator; - } - - /** - * Determines the 'effective' StoreCredentialsMode. This may be different - * from what the user explicitly chose. If the user choice is 'invalid' - * we ignore it (with a warning) and replace it with STORE_NOTHING. - */ - public StoreCredentialsMode getEffectiveStoreMode() { - if (storeValidator.getValue().isOk()) { - return fStoreVar.getValue(); - } - return StoreCredentialsMode.STORE_NOTHING; - } - - public static Validator makeStoreCredentialsValidator(LiveExpression method, LiveExpression storeCredentials ) { - return new Validator() { - { - dependsOn(method); - dependsOn(storeCredentials); - } - - @Override - protected ValidationResult compute() { - if ( - method.getValue()==CFCredentials.LoginMethod.TEMPORARY_CODE && - storeCredentials.getValue()==StoreCredentialsMode.STORE_PASSWORD - ) { - return ValidationResult.warning("'Store Password' is useless for a 'Temporary Code'. This option will be ignored!"); - } - return ValidationResult.OK; - } - }; - } - - /** - * Validates credentials currently entered in the dialog fields, and update - * other dialog model elements in the process (validation result / status and - * refreshToken needed to produce effective credential object. - */ - public Mono validateCredentials() { - return validateCredentialsHelper(CFCredentials.fromLogin(this.fMethod.getValue(), this.fPasswordVar.getValue())) - .doOnSubscribe((e) -> { - needValidationRequest.setValue(false); - refreshToken.setValue(null); - credentialsValidationResult.setValue(VALIDATION_IN_PROGRESS_MESSAGE); - }) - .onErrorResume((e) -> Mono.just(ValidationResult.error(ExceptionUtil.getMessage(e)))) - .doOnNext((result) -> { - credentialsValidationResult.setValue(result); - }); - } - - /** - * Validates a given credential object and returns a validation result (asynchornously). - */ - private Mono validateCredentialsHelper(CFCredentials creds) { - - return Mono.defer(() -> { - if (!StringUtil.hasText(creds.getSecret())) { - //Don't bother verifying empty passwords. - return Mono.just(REQUEST_VALIDATION_MESSAGE); - } - CFClientParams params = new CFClientParams( - currentParams.getUrl(), - currentParams.getUsername(), - creds, - currentParams.isSelfsigned(), - null, null, - currentParams.skipSslValidation() - ); - ClientRequests client = clientFactory.getClient(params); - return client.getUserName() - .flatMap(actualUserName -> { - refreshToken.setValue(client.getRefreshToken()); - if (!currentParams.getUsername().equals(actualUserName)) { - return Mono.just(ValidationResult.error("The credentials belong to a different user!")); - } - return Mono.just(ValidationResult.OK); - }) - .doFinally(signal -> client.dispose()); - }); - } - - public LiveVariable getMethodVar() { - return fMethod; - } - - public CFCredentials getCredentials() { - String refreshToken = this.refreshToken.getValue(); - if (refreshToken==null) { - throw new IllegalStateException("Credentials must be validated before retrieving them from the model"); - } - //Produce credential object consistent with store credentials mode - StoreCredentialsMode storeMode = getEffectiveStoreMode(); - switch (storeMode) { - case STORE_NOTHING: - case STORE_TOKEN: - return CFCredentials.fromRefreshToken(refreshToken); - case STORE_PASSWORD: - return CFCredentials.fromPassword(fPasswordVar.getValue()); - default: - throw new IllegalStateException("Bug! Missing case?"); - } - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/RunTargetWizard.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/RunTargetWizard.java deleted file mode 100644 index 0863c89ea..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/RunTargetWizard.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.dialogs; - -import org.eclipse.jface.wizard.Wizard; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; - -/** - * Creates a run target - * - */ -public class RunTargetWizard extends Wizard { - - private CloudFoundryTargetWizardPage page; - private CloudFoundryTargetWizardModel model; - - public RunTargetWizard(CloudFoundryTargetWizardModel model) { - this.model = model; - - setWindowTitle("Add a Run Target"); - - setNeedsProgressMonitor(true); - } - - @Override - public void addPages() { - // TODO: Turn into framework and load pages based on an initial page - // that shows different target types. - // Right it is hardcoded to load the Cloud Foundry target page. - - page = new CloudFoundryTargetWizardPage(model); - addPage(page); - } - - @Override - public boolean performFinish() { - return getRunTarget() != null; - } - - public CloudFoundryRunTarget getRunTarget() { - return page != null ? page.createRunTarget() : null; - } - - @Override - public boolean needsProgressMonitor() { - return true; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/StoreCredentialsMode.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/StoreCredentialsMode.java deleted file mode 100644 index d1d9f47a2..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/StoreCredentialsMode.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.dialogs; - -import java.util.EnumSet; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.equinox.security.storage.StorageException; -import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; -import org.springframework.ide.eclipse.boot.dash.model.SecuredCredentialsStore; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.CannotAccessPropertyException; -import org.springframework.ide.eclipse.boot.util.Log; -import org.springsource.ide.eclipse.commons.core.pstore.IPropertyStore; -import org.springsource.ide.eclipse.commons.livexp.ui.Ilabelable; - -public enum StoreCredentialsMode implements Ilabelable { - - STORE_PASSWORD { - @Override - public String getLabel() { - return "Store Password"; - } - - @Override - public CFCredentials loadCredentials(BootDashModelContext context, RunTargetType type, String runTargetId) throws CannotAccessPropertyException { - try { - String password = context.getSecuredCredentialsStore().getCredentials(secureStoreScopeKey(type.getName(), runTargetId)); - if (password!=null) { - return CFCredentials.fromPassword(password); - } - return null; - } catch (StorageException e) { - throw new CannotAccessPropertyException("Failed to load credentials", e); - } - } - - @Override - protected void basicSaveCredentials(BootDashModelContext context, RunTargetType type, String runTargetId, CFCredentials credentials) throws CannotAccessPropertyException { - try { - String storedString = credentials.getSecret(); - context.getSecuredCredentialsStore().setCredentials(secureStoreScopeKey(type.getName(), runTargetId), storedString); - } catch (StorageException e) { - throw new CannotAccessPropertyException("Failed to save credentials", e); - } - } - - @Override - protected void eraseCredentials(BootDashModelContext context, RunTargetType type, String runTargetId) { - try { - SecuredCredentialsStore store = context.getSecuredCredentialsStore(); - //Be careful and avoid annoying password popup just to erase data in a locked secure store. - if (store.isUnlocked()) { - store.setCredentials(secureStoreScopeKey(type.getName(), runTargetId), null); - } - } catch (StorageException e) { - Log.log(e); - } - } - - private String secureStoreScopeKey(String targetTypeName, String targetId) { - return targetTypeName+":"+targetId; - } - }, - - STORE_TOKEN { - @Override - public String getLabel() { - return "Store OAuth Token"; - } - - private String privateStoreKey(String targetType, String targetId) { - return targetType+":"+targetId + ":token"; - } - - @Override - public CFCredentials loadCredentials(BootDashModelContext context, RunTargetType type, String runTargetId) { - String token = context.getPrivatePropertyStore().get(privateStoreKey(type.getName(), runTargetId)); - if (token!=null) { - return CFCredentials.fromRefreshToken(token); - } - return null; - } - - @Override - public void basicSaveCredentials(BootDashModelContext context, RunTargetType type, String runTargetId, CFCredentials credentials) throws CannotAccessPropertyException { - try { - String storedString = credentials.getSecret(); - context.getPrivatePropertyStore().put(privateStoreKey(type.getName(), runTargetId), storedString); - } catch (Exception e) { - throw new CannotAccessPropertyException("Failed to save credentials", e); - } - } - - @Override - protected void eraseCredentials(BootDashModelContext context, RunTargetType type, String runTargetId) { - try { - IPropertyStore store = context.getPrivatePropertyStore(); - store.put(privateStoreKey(type.getName(), runTargetId), null); - } catch (Exception e) { - Log.log(e); - } - } - }, - - STORE_NOTHING { - @Override - public String getLabel() { - return "Do NOT Store"; - } - - @Override - public CFCredentials loadCredentials(BootDashModelContext context, RunTargetType type, String runTargetId) { - return null; - } - - @Override - protected void basicSaveCredentials(BootDashModelContext context, RunTargetType type, String runTargetId, CFCredentials credentials) { - //nothing to do - } - - @Override - protected void eraseCredentials(BootDashModelContext context, RunTargetType type, String runTargetId) { - //nothing to do - } - }; - - public abstract CFCredentials loadCredentials(BootDashModelContext context, RunTargetType type, String runTargetId) throws CannotAccessPropertyException; - protected abstract void eraseCredentials(BootDashModelContext context, RunTargetType type, String runTargetId); - protected abstract void basicSaveCredentials(BootDashModelContext context, RunTargetType type, String runTargetId, CFCredentials credentials) throws CannotAccessPropertyException; - - public final void saveCredentials(BootDashModelContext context, RunTargetType type, String runTargetId, CFCredentials credentials) throws CannotAccessPropertyException { - for (StoreCredentialsMode mode : EnumSet.allOf(StoreCredentialsMode.class)) { - if (mode==this) { - mode.basicSaveCredentials(context, type, runTargetId, credentials); - } else { - mode.eraseCredentials(context, type, runTargetId); - } - } - } -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/UpdatePasswordDialog.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/UpdatePasswordDialog.java deleted file mode 100644 index 6989a9baf..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/dialogs/UpdatePasswordDialog.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - * - * Original from org.cloudfoundry.ide.eclipse.server.ui.internal - * and implemented under: - * - * Copyright (c) 2012, 2014 Pivotal Software, Inc. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Apache License, - * Version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.dialogs; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.Status; -import org.eclipse.swt.widgets.Shell; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials.LoginMethod; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.core.SelectionModel; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; -import org.springsource.ide.eclipse.commons.livexp.ui.ButtonSection; -import org.springsource.ide.eclipse.commons.livexp.ui.ChooseOneSectionCombo; -import org.springsource.ide.eclipse.commons.livexp.ui.CommentSection; -import org.springsource.ide.eclipse.commons.livexp.ui.DialogWithSections; -import org.springsource.ide.eclipse.commons.livexp.ui.IPageWithSections; -import org.springsource.ide.eclipse.commons.livexp.ui.StringFieldSection; -import org.springsource.ide.eclipse.commons.livexp.ui.WizardPageSection; - -import reactor.core.scheduler.Schedulers; - -/** - * Dialog for setting the password and "store password" flag. - * - * @author Terry Denney - * @author Alex Boyko - * @author Kris De Volder - */ -public class UpdatePasswordDialog extends DialogWithSections { - - private static final StoreCredentialsMode[] storeCredentialChoices = EnumSet.allOf(StoreCredentialsMode.class) - .toArray(new StoreCredentialsMode[0]); - - private PasswordDialogModel model; - - public UpdatePasswordDialog(Shell parentShell, PasswordDialogModel model) { - super("Update Credentials", model, parentShell); - this.model = model; - disableOkButtonAt(Status.INFO); - } - - @Override - protected List createSections() throws CoreException { - List sections = new ArrayList<>(); - - sections.add(new CommentSection(this, - "The password/code must match your existing target credentials in " + model.getTargetId() + ".")); - - sections.add(new ChooseOneSectionCombo<>(this, "Method:", model.getMethodVar(), EnumSet.allOf(LoginMethod.class))); - sections.add(new StringFieldSection(this, "Password:", model.getPasswordVar(), model.getPasswordValidator()).setPassword(true)); - sections.add(storeCredentialsSection(this, model.getStoreVar(), model.getStoreValidator())); - sections.add(new ButtonSection(this, "Validate", () -> { - model.validateCredentials().subscribeOn(Schedulers.elastic()).subscribe(); - })); - - return sections; - } - - public static ChooseOneSectionCombo storeCredentialsSection(IPageWithSections owner, - LiveVariable storeCreds, - LiveExpression validator - ) { - return new ChooseOneSectionCombo<>(owner, "Remember:", new SelectionModel<>(storeCreds, validator), storeCredentialChoices); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/BootDashCfColumns.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/BootDashCfColumns.java deleted file mode 100644 index e08e7fb64..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/BootDashCfColumns.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel; - -import org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn; - -public class BootDashCfColumns { - public static final BootDashColumn JMX_SSH_TUNNEL = new BootDashColumn("JMX_SSH_TUNNEL"); -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/CloudFoundryRemoteBootAppsDataContributor.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/CloudFoundryRemoteBootAppsDataContributor.java deleted file mode 100644 index e45ce4606..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/CloudFoundryRemoteBootAppsDataContributor.java +++ /dev/null @@ -1,31 +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.cf.jmxtunnel; - -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder; -import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.RemoteAppData; -import org.springsource.ide.eclipse.commons.livexp.core.ObservableSet; - -public class CloudFoundryRemoteBootAppsDataContributor implements RemoteBootAppsDataHolder.Contributor { - - private SimpleDIContext context; - - public CloudFoundryRemoteBootAppsDataContributor(SimpleDIContext context) { - this.context = context; - } - - @Override - public ObservableSet getRemoteApps() { - return context.getBean(JmxSshTunnelManager.class).getUrls(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/JmxSshTunnelManager.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/JmxSshTunnelManager.java deleted file mode 100644 index 116062d54..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/JmxSshTunnelManager.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 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.cf.jmxtunnel; - -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; - -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshTunnel; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springsource.ide.eclipse.commons.livexp.core.AsyncLiveExpression.AsyncMode; -import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.RemoteAppData; -import org.springsource.ide.eclipse.commons.livexp.core.ObservableSet; -import org.springsource.ide.eclipse.commons.livexp.ui.Disposable; - -import com.google.common.collect.ImmutableSet; - -/** - * An instance of this class keeps track of open ssh tunnels for JMX connections to - * remote hosts. It is capable of producing a (Live)Set of JMX urls for all the - * open tunnels. - */ -public class JmxSshTunnelManager { - - private Map tunnels = new HashMap<>(); - - private ObservableSet jmxUrls = ObservableSet.builder() - .refresh(AsyncMode.ASYNC) - .compute(this::collectUrls) - .build(); - - private synchronized ImmutableSet collectUrls() { - ImmutableSet.Builder builder = ImmutableSet.builder(); - for (Entry entry : tunnels.entrySet()) { - SshTunnel tunnel = entry.getKey(); - CloudAppDashElement app = entry.getValue(); - int port = tunnel.getLocalPort(); - if (port>0) { - RemoteAppData data = new RemoteAppData(); - data.setJmxurl(JmxSupport.getJmxUrl(port)); - data.setHost(app.getLiveHost()); - data.setKeepChecking(false); - UUID guid = app.getAppGuid(); - if (guid!=null) { - data.setProcessId(guid.toString()); - } - builder.add(data); - } - } - return builder.build(); - } - - public void add(SshTunnel sshTunnel, CloudAppDashElement app) { - sshTunnel.onDispose(this::handleTunnelClosed); - tunnels.put(sshTunnel, app); - jmxUrls.refresh(); - app.getJmxSshTunnelStatus().refresh(); - } - - private void handleTunnelClosed(Disposable disposed) { - CloudAppDashElement owner = tunnels.remove(disposed); - owner.getJmxSshTunnelStatus().refresh(); - jmxUrls.refresh(); - } - - public ObservableSet getUrls() { - return jmxUrls; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/JmxSupport.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/JmxSupport.java deleted file mode 100644 index 299d70e5e..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/jmxtunnel/JmxSupport.java +++ /dev/null @@ -1,186 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 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.cf.jmxtunnel; - -import java.util.Map; - -import org.springframework.ide.eclipse.boot.dash.cf.client.SshClientSupport; -import org.springframework.ide.eclipse.boot.dash.cf.client.SshHost; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshTunnel; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshTunnelFactory; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.model.RunState; -import org.springframework.ide.eclipse.boot.launch.util.PortFinder; -import org.springsource.ide.eclipse.commons.livexp.core.AsyncLiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; -import org.springsource.ide.eclipse.commons.livexp.util.Log; - -/** - * Helper class providing functionality to connect to JMX on a remote spring boot app - * running on CF, using ssh tunneling. - *

- * The main responsiblity of this class is to manage tunnel life-cycle based on the - * app's state. (I.e. ensure tunnel is created when app started and tunnel is closed - * when app stopped or deleted). - * - * @author Kris De Volder - */ -public class JmxSupport { - - private static final String JAVA_OPTS = "JAVA_OPTS"; - - private static final String JMX_OPTION_PAT = - "-D(com\\.sun\\.management\\.jmxremote|java\\.rmi\\.server|spring\\.jmx)\\.[a-z\\.]*=\\S*\\s*"; - - private static final String JMX_ARGS(int port) { - return "-Dcom.sun.management.jmxremote.ssl=false " + - "-Dcom.sun.management.jmxremote.authenticate=false " + - "-Dcom.sun.management.jmxremote.port="+port+" " + - "-Dcom.sun.management.jmxremote.rmi.port="+port+" " + - "-Djava.rmi.server.hostname=localhost " + - "-Dcom.sun.management.jmxremote.local.only=false "+ - "-Dspring.jmx.enabled=true"; - } - - private CloudAppDashElement app; - private LiveExpression tunnelPort; - - private SshTunnel sshTunnel; - private boolean disposed; - - private JmxSshTunnelManager tunnels; - private SshTunnelFactory tunnelFactory; - - public JmxSupport(CloudAppDashElement cde, JmxSshTunnelManager tunnels, SshTunnelFactory tunnelFactory) { - this.tunnelFactory = tunnelFactory; - this.app = cde; - this.tunnels = tunnels; - this.tunnelPort = new AsyncLiveExpression(null, "Update SSH JMX Tunnel for "+app.getName()) { - { - dependsOn(app.getBaseRunStateExp()); - } - - @Override - protected Integer compute() { - RunState runState = app.getBaseRunStateExp().getValue(); - if (runState == RunState.RUNNING || runState == RunState.DEBUGGING) { - if (app.getEnableJmxSshTunnel()) { - return app.getCfJmxPort(); - } - } - return -1; - } - }; - - this.tunnelPort.addListener((exp, v) -> { - Integer port = exp.getValue(); - if (port!=null && port>0) { - ensureTunnel(port); - } else { - closeTunnel(false); - } - }); - cde.onDispose(d -> closeTunnel(true)); - } - - private synchronized void ensureTunnel(Integer port) { - if (sshTunnel==null && !disposed) { - createSshTunnel(port); - } - } - - private synchronized void closeTunnel(boolean disposed) { - this.disposed = this.disposed || disposed; - if (sshTunnel!=null) { - sshTunnel.close(); - sshTunnel = null; - } - } - - public int getPort() { - int port = app.getCfJmxPort(); - if (port<=0) { - try { - //TODO: should we work harder at allocating a unique port accross all remote and local - // apps? Right now there is a small chance that two apps will get the same port. - port = PortFinder.findFreePort(); - app.setCfJmxPort(port); - } catch (Exception e) { - Log.log(e); - } - } - return port; - } - - public void setupEnvVars(Map env) { - int port = getPort(); - if (port>0) { - String javaOpts = env.get(JAVA_OPTS); - if (javaOpts!=null) { - //Erase old vars - javaOpts = javaOpts.replaceAll(JMX_OPTION_PAT, "").trim(); - } else { - javaOpts = ""; - } - String jmxArgs = JMX_ARGS(port); - if ("".equals(javaOpts)) { - // no other java opts yet - javaOpts = jmxArgs; - } else { - javaOpts = javaOpts + " " +jmxArgs; - } - env.put(JAVA_OPTS, javaOpts); - } - } - - private void createSshTunnel(Integer port) { - if (port!=null && port>0) { - try { - app.log("Fetching JMX SSH tunnel parameters..."); - SshClientSupport sshInfo = app.getTarget().getSshClientSupport(); - SshHost sshHost = sshInfo.getSshHost(); - String sshUser = sshInfo.getSshUser(app.getAppGuid(), 0); - String sshCode = sshInfo.getSshCode(); - int remotePort = port; - - app.log("JMX SSH tunnel parameters:"); - app.log(" host: "+sshHost); - app.log(" user: "+sshUser); - app.log(" code: "+sshCode); - app.log(" remote port: "+remotePort); - - //2: create tunnel - app.log("Creating JMX SSH tunnel..."); - this.sshTunnel = tunnelFactory.create(sshHost, sshUser, sshCode, remotePort, app, remotePort); - String jmxUrl = getJmxUrl(remotePort); - app.log("JMX SSH tunnel URL = "+jmxUrl); - tunnels.add(sshTunnel, app); - } catch (Exception e) { - app.setError(e); - app.log(ExceptionUtil.getMessage(e)); - Log.log(e); - } - } - } - - public static String getJmxUrl(Integer port) { - if (port!=null && port>0) { - return "service:jmx:rmi://localhost:"+port+"/jndi/rmi://localhost:"+port+"/jmxrmi"; - } - return null; - } - - public boolean isTunnelActive() { - SshTunnel sshTunnel = this.sshTunnel; - return sshTunnel != null && !sshTunnel.isDisposed(); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/labels/BootDashCfLabels.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/labels/BootDashCfLabels.java deleted file mode 100644 index b5cc488ce..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/labels/BootDashCfLabels.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.springframework.ide.eclipse.boot.dash.cf.labels; - -import static org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.BootDashCfColumns.JMX_SSH_TUNNEL; -import static org.springframework.ide.eclipse.boot.dash.labels.BootDashLabels.MUTED_TEXT_DECORATION_COLOR_THEME; -import static org.springframework.ide.eclipse.boot.dash.labels.BootDashLabels.TEXT_DECORATION_COLOR_THEME; - -import org.eclipse.jface.viewers.StyledString; -import org.eclipse.swt.graphics.Color; -import org.eclipse.ui.PlatformUI; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.JmxSshTunnelStatus; -import org.springframework.ide.eclipse.boot.dash.labels.BootDashLabels; -import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; -import org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn; -import org.springsource.ide.eclipse.commons.livexp.ui.Stylers; - -import com.google.common.collect.ImmutableSet; - -public class BootDashCfLabels { - - public static final BootDashLabels.Contribution jmxDecoration = new BootDashLabels.Contribution(ImmutableSet.of(JMX_SSH_TUNNEL)) { - @Override public StyledString getStyledText(Stylers stylers, BootDashElement element, BootDashColumn col) { - if (element instanceof CloudAppDashElement) { - CloudAppDashElement cfApp = (CloudAppDashElement) element; - JmxSshTunnelStatus tunnelState = cfApp.getJmxSshTunnelStatus().getValue(); - if (tunnelState!=JmxSshTunnelStatus.DISABLED) { - Color activeColor = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().get(TEXT_DECORATION_COLOR_THEME); - Color notActiveColor = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().get(MUTED_TEXT_DECORATION_COLOR_THEME); - return new StyledString("jmx", tunnelState==JmxSshTunnelStatus.ACTIVE ? stylers.color(activeColor) : stylers.color(notActiveColor)); - } - return new StyledString(); - } - return null; - } - - }; - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/ApplicationRunningStateTracker.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/ApplicationRunningStateTracker.java deleted file mode 100644 index 2279e0824..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/ApplicationRunningStateTracker.java +++ /dev/null @@ -1,190 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.model; - -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFAppState; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFInstanceState; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFInstanceStats; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.DefaultClientRequestsV2; -import org.springframework.ide.eclipse.boot.dash.console.LogType; -import org.springframework.ide.eclipse.boot.dash.model.RunState; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -public class ApplicationRunningStateTracker { - // Give time for Diego-enabled apps with health check that may take a while to start - // Users can always manually stop the element if it is taking too long to check the run state of the element - public static final long APP_START_TIMEOUT = DefaultClientRequestsV2.APP_START_TIMEOUT.toMillis(); - - public static final long WAIT_TIME = 1000; - - private final ClientRequests requests; - - private final String appName; - - private final CloudFoundryBootDashModel model; - - private final long timeout; - - private final CancelationToken cancelationToken; - - private final CloudAppDashElement element; - - - public ApplicationRunningStateTracker(CancelationToken cancelationToken, CloudAppDashElement app) { - this.model = app.getBootDashModel(); - this.requests = model.getClient(); - this.appName = app.getName(); - this.timeout = APP_START_TIMEOUT; - this.cancelationToken = cancelationToken; - this.element = app; - } - - protected void checkTerminate(IProgressMonitor monitor) - throws OperationCanceledException { - this.element.checkTerminationRequested(cancelationToken, monitor); - } - - /** - * Polls cloudfoundry until element has succeeded or failed to start. Sending updates to console - * and return the final run state. - */ - public RunState startTracking(IProgressMonitor monitor) throws Exception, OperationCanceledException { - - // fetch an updated Cloud Application that reflects changes that - // were - // performed on it. Make sure the element element reference is updated - // as - // run state of the element depends on the element being up to date. - // Wait for application to be started - RunState runState = RunState.UNKNOWN; - - long currentTime = System.currentTimeMillis(); - long roughEstimateFetchStatsms = 5000; - - long totalTime = currentTime + timeout; - String checkingMessage = "Checking if the application is running"; - - int estimatedAttempts = (int) (timeout / (WAIT_TIME + roughEstimateFetchStatsms)); - - monitor.beginTask(checkingMessage, estimatedAttempts); - - model.getElementConsoleManager().writeToConsole(element, checkingMessage + ". Please wait...", - LogType.STDOUT); - - CFApplicationDetail app = requests.getApplication(appName); - - if (app == null) { - throw new OperationCanceledException(); - } - - // Get the guid, as it is more efficient for lookup - //UUID appGuid = element.getGuid(); - - while (runState != RunState.RUNNING && runState != RunState.FLAPPING && runState != RunState.CRASHED - && currentTime < totalTime) { - int timeLeft = (int) ((totalTime - currentTime) / 1000); - - // Don't log this. Only update the monitor - monitor.setTaskName(checkingMessage + ". Time left before timeout: " + timeLeft + 's'); - - checkTerminate(monitor); - - monitor.worked(1); - - runState = getRunState(app.getInstanceDetails()); - try { - Thread.sleep(WAIT_TIME); - } catch (InterruptedException e) { - - } - - app = requests.getApplication(app.getName()); - // App no longer exists - if (app == null) { - throw new OperationCanceledException(); - } - - currentTime = System.currentTimeMillis(); - } - - if (runState != RunState.RUNNING) { - String warning = "Timed out waiting for application - " + appName - + " to start. Please wait and manually refresh the target, or check if the application logs show any errors."; - model.getElementConsoleManager().writeToConsole(this.element, warning, LogType.STDERROR); - throw ExceptionUtil.coreException(warning); - - } else { - model.getElementConsoleManager().writeToConsole(this.element, "Application appears to have started - " + appName, - LogType.STDOUT); - } - return runState; - } - - public static RunState getRunState(CFInstanceState instanceState) { - RunState runState = null; - if (instanceState != null) { - switch (instanceState) { - case RUNNING: - runState = RunState.RUNNING; - break; - case CRASHED: - runState = RunState.CRASHED; - break; - case FLAPPING: - runState = RunState.FLAPPING; - break; - case STARTING: - runState = RunState.STARTING; - break; - case DOWN: - runState = RunState.INACTIVE; - break; - default: - runState = RunState.UNKNOWN; - break; - } - } - - return runState; - } - - public static RunState getRunState(CFApplication app, List instances) { - - RunState runState = RunState.UNKNOWN; - // if element desired state is "Stopped", return inactive - if ((instances == null || instances.isEmpty()) - && app.getState() == CFAppState.STOPPED) { - runState = RunState.INACTIVE; - } else { - runState = getRunState(instances); - } - return runState; - } - - private static RunState getRunState(List stats) { - RunState runState = RunState.UNKNOWN; - if (stats!=null && !stats.isEmpty()) { - for (CFInstanceStats stat : stats) { - RunState instanceState = getRunState(stat.getState()); - runState = instanceState != null ? runState.merge(instanceState) : null; - } - } - return runState; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudAppDashElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudAppDashElement.java deleted file mode 100644 index de46accd7..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudAppDashElement.java +++ /dev/null @@ -1,946 +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.cf.model; - -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchManager; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.Image; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.api.Deletable; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFInstanceStats; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.HealthChecks; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFPushArguments; -import org.springframework.ide.eclipse.boot.dash.cf.debug.DebugSupport; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshTunnelFactory; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.JmxSshTunnelManager; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.JmxSupport; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement.CloudAppIdentity; -import org.springframework.ide.eclipse.boot.dash.cf.ops.CloudApplicationOperation; -import org.springframework.ide.eclipse.boot.dash.cf.ops.Operation; -import org.springframework.ide.eclipse.boot.dash.cf.ops.RemoteDevClientStartOperation; -import org.springframework.ide.eclipse.boot.dash.cf.ops.SetHealthCheckOperation; -import org.springframework.ide.eclipse.boot.dash.cf.routes.ParsedUri; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.JmxSshTunnelStatus; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.OperationTracker; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.OperationTracker.Task; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.console.ApplicationLogConsole; -import org.springframework.ide.eclipse.boot.dash.console.LegacyLogSource; -import org.springframework.ide.eclipse.boot.dash.console.LogType; -import org.springframework.ide.eclipse.boot.dash.devtools.DevtoolsUtil; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveDataCapableElement; -import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveDataConnectionManagementActions.ExecuteCommandAction; -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.BootDashViewModel; -import org.springframework.ide.eclipse.boot.dash.model.RunState; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; -import org.springframework.ide.eclipse.boot.dash.util.LogSink; -import org.springframework.ide.eclipse.boot.dash.util.Utils; -import org.springframework.ide.eclipse.boot.dash.views.BootDashModelConsoleManager; -import org.springsource.ide.eclipse.commons.core.pstore.IPropertyStore; -import org.springsource.ide.eclipse.commons.core.pstore.PropertyStoreApi; -import org.springsource.ide.eclipse.commons.core.pstore.PropertyStores; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; -import org.springsource.ide.eclipse.commons.livexp.util.Log; - -import reactor.core.Disposable; - -/** - * A handle to a Cloud application. NOTE: This element should NOT hold Cloud - * application state as it may be discarded and created multiple times for the - * same app for any reason. - *

- * Cloud application state should always be resolved from external sources - */ -public class CloudAppDashElement extends CloudDashElement implements BootDashElement, Deletable, LogSink, LiveDataCapableElement, LegacyLogSource { - - private static final boolean DEBUG = - (""+Platform.getLocation()).contains("kdvolder"); -// (""+Platform.getLocation()).contains("bamboo"); - - private static void debug(String string) { - if (DEBUG) { - System.out.println(string); - } - } - - static final private String DEPLOYMENT_MANIFEST_FILE_PATH = "deploymentManifestFilePath"; //$NON-NLS-1$ - private static final String PROJECT_NAME = "PROJECT_NAME"; - private static final String CF_JMX_PORT = "CF_JMX_PORT"; - private static final String CF_JMX_ENABLED = "CF_JMX_ENABLED"; - - private CancelationTokens cancelationTokens; - - private final CloudFoundryBootDashModel cloudModel; - private PropertyStoreApi persistentProperties; - - private final LiveVariable error = new LiveVariable<>(); - private final OperationTracker startOperationTracker = new OperationTracker(()-> this.getName(),error); - - private final LiveVariable appData = new LiveVariable<>(); - private final LiveVariable> instanceData = new LiveVariable<>(); - private final LiveExpression baseRunState = new LiveExpression() { - - { - dependsOn(appData); - dependsOn(instanceData); - dependsOn(startOperationTracker.inProgress); - dependsOn(error); - } - - @Override - protected RunState compute() { - debug("Compute baseRunState for "+CloudAppDashElement.this+" ..."); - if (error.getValue()!=null) { - debug("error.getValue() => "+error.getValue()); - debug("baseRunState for "+CloudAppDashElement.this+" => UNKNOWN"); - return RunState.UNKNOWN; - } - if (startOperationTracker.inProgress.getValue()>0) { - debug("startOperationTracker.inProgress.getValue() => "+startOperationTracker.inProgress.getValue()); - debug("baseRunState for "+CloudAppDashElement.this+" => STARTING"); - return RunState.STARTING; - } - CFApplication app = appData.getValue(); - debug("appData => "+app); - List instances = instanceData.getValue(); - debug("instances.size() => "+(instances==null?null:instances.size())); - if (instances!=null && app!=null) { - RunState rs = ApplicationRunningStateTracker.getRunState(app, instances); - debug("baseRunState from instances => "+rs); - return rs; - } - debug("baseRunState for "+CloudAppDashElement.this+" => UNKNOWN"); - return RunState.UNKNOWN; - } - }; - - /** - * Used as a temporary override of health-check info fetched from CF. This is cleared when element gets 'proper' - * data fetched from CF. This exists so that we can implement 'setHealthCheck' which is called to update - * model state after changing the health-check value individually. It makes sense in that case to only update - * this one bit of the model state rather than refresh all the data from CF. - */ - private final LiveVariable healthCheckOverride = new LiveVariable<>(); - private JmxSupport jmxSupport; - private LiveExpression jmxSshTunnelStatus = new LiveExpression() { - - //This liveexp is refreshed calls to its 'refresh' method - // - from jmxSshTunnelManager whenever a tunnel is created or disposed. - // - from setEnableJmxSshTunnel method. - - @Override - protected JmxSshTunnelStatus compute() { - if (getEnableJmxSshTunnel()) { - return jmxSupport!=null && jmxSupport.isTunnelActive() - ? JmxSshTunnelStatus.ACTIVE - : JmxSshTunnelStatus.INACTIVE; - } else { - return JmxSshTunnelStatus.DISABLED; - } - } - }; - private LiveExpression activeJmxUrl = new LiveExpression() { - { - dependsOn(jmxSshTunnelStatus); - } - - @Override - protected String compute() { - JmxSshTunnelStatus status = jmxSshTunnelStatus.getValue(); - if (status==JmxSshTunnelStatus.ACTIVE) { - return JmxSupport.getJmxUrl(jmxSupport.getPort()); - } - return null; - } - }; - - { - appData.addListener((e, v) -> { - healthCheckOverride.setValue(null); - }); - } - - protected void showConsole() { - try { - getBootDashModel().getElementConsoleManager().showConsole(this); - } catch (Exception e) { - Log.log(e); - } - } - - protected void resetAndShowConsole() { - try { - getBootDashModel().getElementConsoleManager().resetConsole(this); - getBootDashModel().getElementConsoleManager().showConsole(this); - } catch (Exception e) { - Log.log(e); - } - } - - public CloudAppDashElement(CloudFoundryBootDashModel model, String appName, IPropertyStore modelStore) { - super(model, new CloudAppIdentity(appName, model.getRunTarget())); - this.cancelationTokens = new CancelationTokens(); - this.cloudModel = model; - IPropertyStore backingStore = PropertyStores.createSubStore("A"+getName(), modelStore); - this.persistentProperties = PropertyStores.createApi(backingStore); - addElementNotifier(baseRunState); - addElementNotifier(appData); - addElementNotifier(healthCheckOverride); - addElementNotifier(jmxSshTunnelStatus); - this.addDisposableChild(baseRunState); - getJmxSupport(); //Must force creation of jmxSupport object, if applicable, otherwise it's runstate listener will not be - // active to start JmxSshTunnel. See bug: https://www.pivotaltracker.com/story/show/159376406 - jmxSshTunnelStatus.refresh(); - } - - @Override - public CloudFoundryBootDashModel getBootDashModel() { - return (CloudFoundryBootDashModel) super.getBootDashModel(); - } - - public void stopAsync() throws Exception { - cancelOperations(); - String appName = getName(); - getBootDashModel().runAsynch("Stopping application " + appName, appName, (IProgressMonitor monitor) -> { - stop(createCancelationToken(), monitor); - }, ui()); - } - - @Override - public void stop() throws Exception { - cancelOperations(); - stop(createCancelationToken(), new NullProgressMonitor()); - } - - public void stop(CancelationToken cancelationToken, IProgressMonitor monitor) throws Exception { - checkTerminationRequested(cancelationToken, monitor); - getClient().stopApplication(getName()); - refresh(); - } - - @Override - public void restart(RunState runningOrDebugging, UserInteractions ui) throws Exception { - Job job = new Job("Restarting " + getName()) { - @Override - protected IStatus run(IProgressMonitor _monitor) { - CancelationToken cancelationToken = cancelationTokens.create(); - try { - startOperationTracker.whileExecuting(ui, cancelationToken, _monitor, () -> { - cancelationTokens.cancelAllBefore(cancelationToken); - //Caution! It is important that canceling older tokens is done *inside* the 'whileExecuting'. - //Otherwise currently executing operations will exit before the restart operation is registered - //as 'in progress' which causes a brief flash in the runstate where it incorrectly registers as - // 'running' while it should be registering as 'starting'. - //See: https://www.pivotaltracker.com/story/show/159639098/comments/193569587 - cloudModel.runSynch("Restarting, goal state: " + runningOrDebugging, getName(), (IProgressMonitor monitor) -> { - if (getProject() != null) { - // Let push and debug resolve deployment properties - CloudApplicationDeploymentProperties deploymentProperties = null; - pushAndDebug(deploymentProperties, runningOrDebugging, ui, cancelationToken, monitor); - } else { - restartOnly(ui, cancelationToken, monitor); - } - }, ui); - }); - } catch (Exception e) { - Log.log(e); - } - return Status.OK_STATUS; - } - }; - job.setSystem(true); - job.schedule(); - } - - public DebugSupport getDebugSupport() { - //In the future we may need to choose between multiple strategies here. - return getBootDashModel().getDebugSupport(); - } - - public BootDashViewModel getViewModel() { - return getBootDashModel().getViewModel(); - } - - public void restartWithRemoteClient(UserInteractions ui, CancelationToken cancelationToken) { - String opName = "Restart Remote DevTools Client for application '" + getName() + "'"; - getBootDashModel().runAsynch(opName, getName(), (IProgressMonitor monitor) -> { - doRestartWithRemoteClient(RunState.RUNNING, ui, cancelationToken, monitor); - }, ui); - } - - protected void doRestartWithRemoteClient(RunState runningOrDebugging, UserInteractions ui, CancelationToken cancelationToken, IProgressMonitor monitor) - throws Exception { - - CloudFoundryBootDashModel model = getBootDashModel(); - Map envVars = model.getRunTarget().getClient().getApplicationEnvironment(getName()); - - if (getProject() == null) { - ExceptionUtil.coreException(new Status(IStatus.ERROR, BootDashActivator.PLUGIN_ID, - "Local project not associated to CF app '" + getName() + "'")); - } - - new SetHealthCheckOperation(this, HealthChecks.HC_PROCESS, ui, /* confirmChange */true, cancelationToken) - .run(monitor); - - if (!DevtoolsUtil.isEnvVarSetupForRemoteClient(envVars, DevtoolsUtil.getSecret(getProject()))) { - // Let the push and debug operation resolve default properties - CloudApplicationDeploymentProperties deploymentProperties = null; - - pushAndDebug(deploymentProperties , runningOrDebugging, ui, cancelationToken, monitor); - /* - * Restart and push op resets console anyway, no need to reset it - * again - */ - } else if (getRunState() == RunState.INACTIVE) { - restartOnly(ui, cancelationToken, monitor); - } - - new RemoteDevClientStartOperation(model, getName(), runningOrDebugging, cancelationToken).run(monitor); - } - - - public void restartOnly(UserInteractions ui, CancelationToken cancelationToken, IProgressMonitor monitor) throws Exception { - whileStarting(ui, cancelationToken, monitor, () -> { - if (!getClient().applicationExists(getName())) { - throw ExceptionUtil.coreException( - "Unable to start the application. Application does not exist anymore in Cloud Foundry: " - + getName()); - } - - checkTerminationRequested(cancelationToken, monitor); - - log("Starting application: " + getName()); - getClient().restartApplication(getName(), CancelationTokens.merge(cancelationToken, monitor)); - - new ApplicationRunningStateTracker(cancelationToken, this).startTracking(monitor); - - CFApplicationDetail updatedInstances = getClient().getApplication(getName()); - setDetailedData(updatedInstances); - }); - } - - public void restartOnlyAsynch(UserInteractions ui, CancelationToken cancelationToken) { - String opName = "Restarting application " + getName(); - getBootDashModel().runAsynch(opName, getName(), (IProgressMonitor monitor) -> { - restartOnly(ui, cancelationToken, monitor); - }, ui); - } - - public void pushAndDebug(CloudApplicationDeploymentProperties deploymentProperties, RunState runningOrDebugging, - UserInteractions ui, CancelationToken cancelationToken, IProgressMonitor monitor) throws Exception { - String opName = "Starting application '" + getName() + "' in " - + (runningOrDebugging == RunState.DEBUGGING ? "DEBUG" : "RUN") + " mode"; - DebugSupport debugSupport = getDebugSupport(); - - if (runningOrDebugging == RunState.DEBUGGING) { - - if (debugSupport != null && debugSupport.isSupported(this)) { - Operation debugOp = debugSupport.createOperation(this, opName, ui, cancelationToken); - - push(deploymentProperties, runningOrDebugging, debugSupport, cancelationToken, ui, monitor); - debugOp.run(monitor); - } else { - String title = "Debugging is not supported for '" + getName() + "'"; - String msg = debugSupport.getNotSupportedMessage(this); - if (msg == null) { - msg = title; - } - ui.errorPopup(title, msg); - throw ExceptionUtil.coreException(msg); - } - } else { - push(deploymentProperties, runningOrDebugging, debugSupport, cancelationToken, ui, monitor); - } - } - - @Override - public void openConfig(UserInteractions ui) { - - } - - @Override - public String getName() { - return delegate.getAppName(); - } - - /** - * Returns the project associated with this element or null. If includeNonExistingProjects is - * true, then the project is returned even it no longer exists. - */ - public IProject getProject(boolean includeNonExistingProjects) { - String name = getPersistentProperties().get(PROJECT_NAME); - if (name!=null) { - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name); - if (includeNonExistingProjects || project.exists()) { - return project; - } - } - return null; - } - - /** - * Returns the remote jmx port that should/will be used when deploying this - * app to CF (so that we can SSH tunnel to that port to attach to JMX on the remote app). - */ - public int getCfJmxPort() { - return getPersistentProperties().get(CF_JMX_PORT, -1); - } - - public void setCfJmxPort(int port) throws Exception { - getPersistentProperties().put(CF_JMX_PORT, port>0 ? ""+port : null); - } - - public LiveExpression getJmxSshTunnelStatus() { - return jmxSshTunnelStatus; - } - - public boolean getEnableJmxSshTunnel() { - return getPersistentProperties().get(CF_JMX_ENABLED, false); - } - - public void setEnableJmxSshTunnel(boolean enable) throws Exception { - boolean old = getEnableJmxSshTunnel(); - getPersistentProperties().put(CF_JMX_ENABLED, enable); - jmxSshTunnelStatus.refresh(); - } - - - /** - * Returns the project associated with this element or null. The project returned is - * guaranteed to exist. - */ - @Override - public IProject getProject() { - return getProject(false); - } - - /** - * Set the project 'binding' for this element. - * @return true if the element was changed by this operation. - */ - public boolean setProject(IProject project) { - try { - PropertyStoreApi props = getPersistentProperties(); - String oldValue = props.get(PROJECT_NAME); - String newValue = project==null?null:project.getName(); - if (!Objects.equals(oldValue, newValue)) { - props.put(PROJECT_NAME, newValue); - return true; - } - return false; - } catch (Exception e) { - Log.log(e); - return false; - } - } - - @Override - public RunState getRunState() { - RunState state = baseRunState.getValue(); - if (state == RunState.RUNNING) { - DebugSupport debugSupport = getDebugSupport(); - if (debugSupport.isDebuggerAttached(CloudAppDashElement.this)) { -// if (DevtoolsUtil.isDevClientAttached(this, ILaunchManager.DEBUG_MODE)) { - state = RunState.DEBUGGING; - } - } - return state; - } - - /** - * This method is mostly meant just for test purposes. The 'baseRunState' is really - * part of how this class internally computes runstate. Clients should have no business - * using it separate from the runtstate. - */ - public LiveExpression getBaseRunStateExp() { - return baseRunState; - } - - @Override - public int getLivePort() { - return 443; - } - - @Override - public String getLiveHost() { - CFApplication app = getSummaryData(); - if (app != null) { - List uris = app.getUris(); - if (uris != null) { - for (String _uri : uris) { - if (StringUtil.hasText(_uri)) { - ParsedUri uri = new ParsedUri(_uri); - return uri.getHostAndDomain(); - } - } - } - } - return null; - } - - @Override - public String getUrl() { - CFApplication app = getSummaryData(); - if (app != null) { - List uris = app.getUris(); - if (uris != null) { - for (String uri : uris) { - if (StringUtil.hasText(uri)) { - return Utils.pathJoin("https://"+uri, getDefaultRequestMappingPath()); - } - } - } - } - return null; - } - - public Integer getMemory() { - CFApplication app = getSummaryData(); - if (app != null) { - return app.getMemory(); - } - return null; - } - - public String getHealthCheckHttpEndpoint() { - CFApplication app = getSummaryData(); - if (app != null) { - return app.getHealthCheckHttpEndpoint(); - } - return null; - } - - public CFApplication getSummaryData() { - return appData.getValue(); - } - - @Override - public ILaunchConfiguration getActiveConfig() { - return null; - } - - @Override - public int getActualInstances() { - CFApplication data = getSummaryData(); - return data != null ? data.getRunningInstances() : 0; - } - - @Override - public int getDesiredInstances() { - CFApplication data = getSummaryData(); - return data != null ? data.getInstances() : 0; - } - - public String getHealthCheck() { - String hc = healthCheckOverride.getValue(); - if (hc!=null) { - return hc; - } - CFApplication data = getSummaryData(); - return data!=null ? data.getHealthCheckType() : DeploymentProperties.DEFAULT_HEALTH_CHECK_TYPE; - } - - /** - * Changes the cached health-check value for this model element. Note that this - * doesnt *not* change the real value of the health-check. - */ - public void setHealthCheck(String hc) { - this.healthCheckOverride.setValue(hc); - } - - - public UUID getAppGuid() { - CFApplication app = getSummaryData(); - if (app!=null) { - return app.getGuid(); - } - return null; - } - - @Override - public PropertyStoreApi getPersistentProperties() { - return persistentProperties; - } - - static class CloudAppIdentity { - - private final String appName; - private final RunTarget runTarget; - - @Override - public String toString() { - return appName + "@" + runTarget; - }; - - CloudAppIdentity(String appName, RunTarget runTarget) { - this.appName = appName; - this.runTarget = runTarget; - } - - public String getAppName() { - return this.appName; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((appName == null) ? 0 : appName.hashCode()); - result = prime * result + ((runTarget == null) ? 0 : runTarget.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; - CloudAppIdentity other = (CloudAppIdentity) obj; - if (appName == null) { - if (other.appName != null) - return false; - } else if (!appName.equals(other.appName)) - return false; - if (runTarget == null) { - if (other.runTarget != null) - return false; - } else if (!runTarget.equals(other.runTarget)) - return false; - return true; - } - - } - - @Override - public void log(String message) { - log(message, LogType.STDOUT); - } - - public void log(String message, LogType logType) { - try { - getBootDashModel().getElementConsoleManager().writeToConsole(this, message, logType); - } catch (Exception e) { - Log.log(e); - } - } - - @Override - public BootDashModel getParent() { - return getBootDashModel(); - } - - @Override - protected LiveExpression getActuatorUrl() { - return activeJmxUrl; - } - - public IFile getDeploymentManifestFile() { - String text = getPersistentProperties().get(DEPLOYMENT_MANIFEST_FILE_PATH); - try { - return text == null ? null : ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(text)); - } catch (IllegalArgumentException e) { - Log.log(e); - return null; - } - } - - public void setDeploymentManifestFile(IFile file) { - try { - if (file == null) { - getPersistentProperties().put(DEPLOYMENT_MANIFEST_FILE_PATH, (String) null); - } else { - getPersistentProperties().put(DEPLOYMENT_MANIFEST_FILE_PATH, file.getFullPath().toString()); - } - } catch (Exception e) { - Log.log(e); - } - } - - public void setDetailedData(CFApplicationDetail appDetails) { - if (appDetails!=null) { - this.appData.setValue(appDetails); - this.instanceData.setValue(appDetails.getInstanceDetails()); - } else { - this.appData.setValue(null); - this.instanceData.setValue(null); - } - } - - public List getInstanceData() { - return this.instanceData.getValue(); - } - - public void setError(Throwable t) { - error.setValue(t); - } - - @Override - public CancelationToken createCancelationToken() { - return cancelationTokens.create(); - } - - @Override - public void cancelOperations() { - cancelationTokens.cancelAll(); - } - - /** - * Print a message to the console associated with this application. - */ - public void print(String msg) { - print(msg, LogType.STDOUT); - } - - /** - * Print a message to the console associated with this application. - */ - public void printError(String string) { - print(string, LogType.STDERROR); - } - - /** - * Print a message to the console associated with this application. - */ - public void print(String msg, LogType type) { - try { - BootDashModelConsoleManager consoles = getBootDashModel().getElementConsoleManager(); - consoles.writeToConsole(this, msg+"\n", type); - } catch (Exception e) { - Log.log(e); - } - } - - /** - * Attempt to refresh the data associated with this app in the model. Returns the - * refreshed element if this was succesful, null if the element was deleted (because during the - * refresh we discovered it not longer exists) and if something failed trying to refresh the element. - */ - public CloudAppDashElement refresh() throws Exception { - debug("Refreshing element: "+this.getName()); - CFApplicationDetail data = getClient().getApplication(getName()); - if (data==null) { - //Looks like element no longer exist in CF so remove it from the model - CloudFoundryBootDashModel model = getBootDashModel(); - model.removeApplication(getName()); - return null; - } - getBootDashModel().updateApplication(data); - return this; - } - - @Override - public CloudFoundryRunTarget getTarget() { - return (CloudFoundryRunTarget) super.getTarget(); - } - - private ClientRequests getClient() { - return getTarget().getClient(); - } - - public void push(CloudApplicationDeploymentProperties deploymentProperties, RunState runningOrDebugging, - DebugSupport debugSupport, CancelationToken cancelationToken, UserInteractions ui, IProgressMonitor monitor) - throws Exception { - - boolean isDebugging = runningOrDebugging == RunState.DEBUGGING; - whileStarting(ui, cancelationToken, monitor, () -> { - // Refresh app data and check that the application (still) exists in - // Cloud Foundry - // This also ensures that the 'diff change dialog' will pick up on - // the latest changes. - // TODO: should this refresh be moved closer to the where we - // actually compute the diff? - CloudAppDashElement updatedApp = this.refresh(); - if (updatedApp == null) { - ExceptionUtil.coreException(new Status(IStatus.ERROR, BootDashActivator.PLUGIN_ID, - "No Cloud Application found for '" + getName() + "'")); - } - IProject project = getProject(); - if (project == null) { - ExceptionUtil.coreException(new Status(IStatus.ERROR, BootDashActivator.PLUGIN_ID, - "Local project not associated to CF app '" + getName() + "'")); - } - - checkTerminationRequested(cancelationToken, monitor); - - CloudApplicationDeploymentProperties properties = deploymentProperties == null - ? getBootDashModel().resolveDeploymentProperties(updatedApp, ui, monitor) : deploymentProperties; - - // Update JAVA_OPTS env variable with Remote DevTools Client secret - DevtoolsUtil.setupEnvVarsForRemoteClient(properties.getEnvironmentVariables(), - DevtoolsUtil.getSecret(project)); - JmxSupport jmxSupport = getJmxSupport(); - if (jmxSupport!=null) { - jmxSupport.setupEnvVars(properties.getEnvironmentVariables()); - } - if (debugSupport != null) { - if (isDebugging) { - debugSupport.setupEnvVars(properties.getEnvironmentVariables()); - } else { - debugSupport.clearEnvVars(properties.getEnvironmentVariables()); - } - } - - checkTerminationRequested(cancelationToken, monitor); - - CFPushArguments pushArgs = properties.toPushArguments(getBootDashModel().getCloudDomains(monitor)); - - getClient().push(pushArgs, CancelationTokens.merge(cancelationToken, monitor)); - - log("Application pushed to Cloud Foundry: " + getName()); - }); - } - - public void whileStarting(UserInteractions ui, CancelationToken cancelationToken, IProgressMonitor monitor, Task task) throws Exception { - resetAndShowConsole(); - startOperationTracker.whileExecuting(ui, cancelationToken, monitor, task); - refresh(); - } - - public void checkTerminationRequested(CancelationToken cancelationToken, IProgressMonitor mon) - throws OperationCanceledException { - if (mon != null && mon.isCanceled() || cancelationToken != null && cancelationToken.isCanceled()) { - throw new OperationCanceledException(); - } - } - - @Override - public void delete() { - CloudFoundryBootDashModel model = getBootDashModel(); - CloudAppDashElement cloudElement = this; - cloudElement.cancelOperations(); - CancelationToken cancelToken = cloudElement.createCancelationToken(); - CloudApplicationOperation operation = new CloudApplicationOperation("Deleting: " + cloudElement.getName(), model, - cloudElement.getName(), cancelToken) { - - @Override - protected void doCloudOp(IProgressMonitor monitor) throws Exception, OperationCanceledException { - // Delete from CF first. Do it outside of synch block to avoid - // deadlock - model.getRunTarget().getClient().deleteApplication(appName); - model.getElementConsoleManager().terminateConsole(cloudElement); - model.removeApplication(cloudElement.getName()); - cloudElement.setProject(null); - } - }; - - // Allow deletions to occur concurrently with any other application - // operation - operation.setSchedulingRule(null); - getBootDashModel().runAsynch(operation, ui()); - } - - private UserInteractions ui() { - return injections().getBean(UserInteractions.class); - } - - @Override - public EnumSet supportedGoalStates() { - return CloudFoundryRunTarget.RUN_GOAL_STATES; - } - - public synchronized JmxSupport getJmxSupport() { - if (jmxSupport == null && getProject()!=null && getEnableJmxSshTunnel()) { - this.jmxSupport = new JmxSupport(this, - injections().getBean(JmxSshTunnelManager.class), - injections().getBean(SshTunnelFactory.class) - ); - } - return jmxSupport; - } - - private SimpleDIContext injections() { - return this.getViewModel().getContext().injections; - } - - public String getJmxUrl() { - int port = getCfJmxPort(); - if (port>0) { - return JmxSupport.getJmxUrl(port); - } - return null; - } - - @Override - public ImageDescriptor getRunStateImageDecoration() { - if (this.getTarget() != null && this.getRunState() == RunState.RUNNING) { - if (DevtoolsUtil.isDevClientAttached(this, ILaunchManager.RUN_MODE)) { - return BootDashActivator.getDefault().getImageRegistry().getDescriptor(BootDashActivator.DT_ICON_ID); - } - } - return null; - } - - @Override - public boolean matchesLiveProcessCommand(ExecuteCommandAction action) { - UUID appGuid = getAppGuid(); - return appGuid!=null && appGuid.toString().equals(action.getProcessId()); - } - - @Override - public Image getPropertiesTitleIconImage() { - return BootDashActivator.getDefault().getImageRegistry().get(BootDashActivator.CLOUD_ICON); - } - - @Override - public Disposable connectLog(ApplicationLogConsole logConsole) { - if (logConsole.getLogStreamingToken() == null) { - try { - ClientRequests client = getClient(); - return client.streamLogs(getName(), logConsole); - } catch (Exception e) { - logConsole.writeApplicationLog("Failed to stream contents from "+getTarget().getDisplayName()+" due to: " + e.getMessage(), - LogType.STDERROR); - } - } - return null; - } - - @Override - public String getProtocol() { - return "https"; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudDashApplications.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudDashApplications.java deleted file mode 100644 index fad0dc9ee..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudDashApplications.java +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.model; - -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -import org.springframework.ide.eclipse.boot.dash.livexp.DisposingFactory; -import org.springsource.ide.eclipse.commons.livexp.core.AsyncLiveExpression.AsyncMode; -import org.springsource.ide.eclipse.commons.livexp.core.AbstractDisposable; -import org.springsource.ide.eclipse.commons.livexp.core.LiveSetVariable; -import org.springsource.ide.eclipse.commons.livexp.core.ObservableSet; - -import com.google.common.base.Function; -import com.google.common.collect.ImmutableSet; - -/** - * An instance of this class is responsible for managing a list of {@link CloudAppDashElement}. This means: - *

- *

    - *
  • calling 'dispose' on any no longer needed elements. - *
  • ensuring that only a single object exists to represent an element with a given identity. - *
  • creating the elements as needed. - *
- * - * @author Kris De Volder - * @author Nieraj Singh - */ -public class CloudDashApplications extends AbstractDisposable { - - private static final boolean DEBUG = false; -// ("" + Platform.getLocation()).contains("bamboo") -// || ("" + Platform.getLocation()).contains("kdvolder"); - - private static void debug(String string) { - if (DEBUG) { - System.out.println(string); - } - } - - private final LiveSetVariable appNames = new LiveSetVariable<>(AsyncMode.SYNC); - private final ObservableSet applications; - private final DisposingFactory factory; - - public CloudDashApplications(final CloudFoundryBootDashModel model) { - factory = new DisposingFactory(appNames) { - @Override - protected CloudAppDashElement create(String appName) { - return new CloudAppDashElement(model, appName, model.getPropertyStore()); - } - }; - applications = org.springsource.ide.eclipse.commons.livexp.core.LiveSets.map(appNames, AsyncMode.SYNC, AsyncMode.ASYNC, new Function() { - @Override - public CloudAppDashElement apply(String appName) { - return factory.createOrGet(appName); - } - }); - addDisposableChild(factory); - addDisposableChild(applications); - if (DEBUG) { - applications.addListener((e, v) -> { - debug("applications change event!"); - debug(" event values = "+getNames(v)); - debug(" current values = "+getNames(applications.getValues())); - }); - } - } - - private List getNames(ImmutableSet v) { - return v.stream().map(CloudAppDashElement::getName).collect(Collectors.toList()); - } - - public void setAppNames(Collection names) { - appNames.replaceAll(names); - } - - public ObservableSet getApplications() { - return applications; - } - - public ImmutableSet getApplicationValues() { - return applications.getValues(); - } - - public CloudAppDashElement getApplication(String appName) { - return factory.createOrGet(appName); - } - - public CloudAppDashElement addApplication(String name) { - appNames.add(name); - return factory.createOrGet(name); - } - - public void removeApplication(String name) { - appNames.remove(name); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudDashElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudDashElement.java deleted file mode 100644 index db66a6343..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudDashElement.java +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017, 2019 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.cf.model; - -import java.util.List; - -import org.springframework.ide.eclipse.beans.ui.live.model.LiveBeansModel; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.Failable; -import org.springframework.ide.eclipse.boot.dash.model.MissingLiveInfoMessages; -import org.springframework.ide.eclipse.boot.dash.model.WrappingBootDashElement; -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.springsource.ide.eclipse.commons.livexp.core.AsyncLiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; - -import com.google.common.collect.ImmutableList; - -public abstract class CloudDashElement extends WrappingBootDashElement { - - public CloudDashElement(BootDashModel bootDashModel, T delegate) { - super(bootDashModel, delegate); - } - - private LiveExpression>> liveRequestMappings; - private LiveExpression> liveBeans; - private LiveExpression> liveEnv; - - @Override - public Failable> getLiveRequestMappings() { - synchronized (this) { - if (liveRequestMappings==null) { - final LiveExpression actuatorUrl = getActuatorUrl(); - liveRequestMappings = new AsyncLiveExpression>>(Failable.error(MissingLiveInfoMessages.NOT_YET_COMPUTED), "Fetch request mappings for '"+getName()+"'") { - @Override - protected Failable> compute() { - String target = actuatorUrl.getValue(); - if (target!=null) { - ActuatorClient client = JMXActuatorClient.forUrl(getTypeLookup(), () -> target); - List list = client.getRequestMappings(); - if (list!=null) { - return Failable.of(ImmutableList.copyOf(client.getRequestMappings())); - } - } - return Failable.error(getBootDashModel().getRunTarget().getType().getMissingLiveInfoMessages().getMissingInfoMessage(getName(), "mappings")); - } - - }; - liveRequestMappings.dependsOn(actuatorUrl); - addElementState(liveRequestMappings); - addDisposableChild(liveRequestMappings); - } - } - return liveRequestMappings.getValue(); - } - - @Override - public Failable getLiveBeans() { - synchronized (this) { - if (liveBeans == null) { - final LiveExpression actuatorUrl = getActuatorUrl(); - liveBeans = new AsyncLiveExpression>(Failable.error(MissingLiveInfoMessages.NOT_YET_COMPUTED), "Fetch beans for '"+getName()+"'") { - @Override - protected Failable compute() { - String target = actuatorUrl.getValue(); - if (target != null) { - ActuatorClient client = JMXActuatorClient.forUrl(getTypeLookup(), () -> target); - LiveBeansModel beans = client.getBeans(); - if (beans != null) { - return Failable.of(beans); - } - } - return Failable.error(getBootDashModel().getRunTarget().getType().getMissingLiveInfoMessages().getMissingInfoMessage(getName(), "beans")); - } - - }; - liveBeans.dependsOn(actuatorUrl); - addElementState(liveBeans); - addDisposableChild(liveBeans); - } - } - return liveBeans.getValue(); - } - - @Override - public Failable getLiveEnv() { - synchronized (this) { - if (liveEnv == null) { - final LiveExpression actuatorUrl = getActuatorUrl(); - liveEnv = new AsyncLiveExpression>(Failable.error(MissingLiveInfoMessages.NOT_YET_COMPUTED), "Fetch env for '"+getName()+"'") { - @Override - protected Failable compute() { - String target = actuatorUrl.getValue(); - if (target != null) { - ActuatorClient client = JMXActuatorClient.forUrl(getTypeLookup(), () -> target); - LiveEnvModel env = client.getEnv(); - if (env != null) { - return Failable.of(env); - } - } - return Failable.error(getBootDashModel().getRunTarget().getType().getMissingLiveInfoMessages().getMissingInfoMessage(getName(), "env")); - } - - }; - liveEnv.dependsOn(actuatorUrl); - addElementState(liveEnv); - addDisposableChild(liveEnv); - } - } - return liveEnv.getValue(); - } - - protected LiveExpression getActuatorUrl() { - return LiveExpression.constant(null); - } - - @Override - public CloudFoundryRunTarget getTarget() { - return (CloudFoundryRunTarget) super.getTarget(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudDashElementFactory.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudDashElementFactory.java deleted file mode 100644 index 2684a765e..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudDashElementFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.model; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFServiceInstance; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; -import org.springsource.ide.eclipse.commons.core.pstore.IPropertyStore; - -public class CloudDashElementFactory { - - private final IPropertyStore modelStore; - - private final CloudFoundryBootDashModel model; - - public CloudDashElementFactory(BootDashModelContext context, IPropertyStore modelStore, - CloudFoundryBootDashModel model) { - this.modelStore = modelStore; - this.model = model; - } - - public CloudServiceInstanceDashElement createService(CFServiceInstance service) { - return new CloudServiceInstanceDashElement(model, service, modelStore); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudFoundryBootDashModel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudFoundryBootDashModel.java deleted file mode 100644 index 950713b48..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudFoundryBootDashModel.java +++ /dev/null @@ -1,883 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2021 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.cf.model; - -import org.springsource.ide.eclipse.commons.livexp.core.LiveSets; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicInteger; - -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.CompareEditorInput; -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.core.filebuffers.FileBuffers; -import org.eclipse.core.filebuffers.ITextFileBuffer; -import org.eclipse.core.filebuffers.LocationKind; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.text.edits.MalformedTreeException; -import org.eclipse.text.edits.MultiTextEdit; -import org.eclipse.text.edits.ReplaceEdit; -import org.eclipse.text.edits.TextEdit; -import org.osgi.framework.Version; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.api.Deletable; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.ReactorUtils; -import org.springframework.ide.eclipse.boot.dash.cf.debug.DebugStrategyManager; -import org.springframework.ide.eclipse.boot.dash.cf.debug.DebugSupport; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.ApplicationManifestHandler; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudData; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.UnsupportedPushProperties; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.YamlGraphDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialog; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialogModel.ManifestType; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.StoreCredentialsMode; -import org.springframework.ide.eclipse.boot.dash.cf.ops.JobBody; -import org.springframework.ide.eclipse.boot.dash.cf.ops.Operation; -import org.springframework.ide.eclipse.boot.dash.cf.ops.OperationsExecution; -import org.springframework.ide.eclipse.boot.dash.cf.ops.ProjectsDeployer; -import org.springframework.ide.eclipse.boot.dash.cf.ops.ServicesRefreshOperation; -import org.springframework.ide.eclipse.boot.dash.cf.ops.TargetApplicationsRefreshOperation; -import org.springframework.ide.eclipse.boot.dash.cf.packaging.CloudApplicationArchiverStrategies; -import org.springframework.ide.eclipse.boot.dash.cf.packaging.CloudApplicationArchiverStrategy; -import org.springframework.ide.eclipse.boot.dash.cf.packaging.ICloudApplicationArchiver; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.cf.ui.CfUserInteractions; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.RemoteBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.YamlFileInput; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.YamlInput; -import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel; -import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel.Result; -import org.springframework.ide.eclipse.boot.dash.model.AsyncDeletable; -import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -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.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.CannotAccessPropertyException; -import org.springsource.ide.eclipse.commons.frameworks.core.util.IOUtil; -import org.springsource.ide.eclipse.commons.frameworks.core.util.JobUtil; -import org.springsource.ide.eclipse.commons.livexp.core.AsyncLiveExpression.AsyncMode; -import org.springsource.ide.eclipse.commons.livexp.core.LiveSetVariable; -import org.springsource.ide.eclipse.commons.livexp.core.ObservableSet; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; -import org.springsource.ide.eclipse.commons.livexp.util.Log; -import org.springsource.ide.eclipse.commons.livexp.util.OldValueDisposer; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; -import org.yaml.snakeyaml.representer.Representer; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -public class CloudFoundryBootDashModel extends RemoteBootDashModel { - - private DebugStrategyManager cfDebugStrategies; - - public static final String APP_TO_PROJECT_MAPPING = "projectToAppMapping"; - - private static final Comparator ELEMENT_COMPARATOR = new Comparator() { - @Override - public int compare(BootDashElement o1, BootDashElement o2) { - int cat1 = getCategory(o1); - int cat2 = getCategory(o2); - if (cat1!=cat2) { - return cat1 - cat2; - } else { - return o1.getName().compareTo(o2.getName()); - } - } - - private int getCategory(BootDashElement o1) { - if (o1 instanceof CloudAppDashElement) { - return 1; - } else if (o1 instanceof CloudServiceInstanceDashElement) { - return 2; - } else { - //Not really possible but anyhow... - return 999; - } - } - }; - - private CloudDashElementFactory elementFactory; - - private UnsupportedPushProperties unsupportedPushProperties; - - private final LiveSetVariable services = new LiveSetVariable<>(AsyncMode.SYNC); - private final CloudDashApplications applications = new CloudDashApplications(this); - private final ObservableSet allElements = LiveSets.union(applications.getApplications(), services); - - private void checkApiVersion() { - this.refreshTracker.callAsync("Checking API version...", () -> { - ClientRequests client = getClient(); - if (client!=null) { - Version server = client.getApiVersion(); - Version supported = client.getSupportedApiVersion(); - if (server.compareTo(supported)<0) { - throw ExceptionUtil.coreException(IStatus.WARNING, "Client supports API version "+server+ - " and is connected to server with API version "+supported+". "+ - "Things may not work as expected."); - } - } - return null; - }); - } - - final private IResourceChangeListener resourceChangeListener = new IResourceChangeListener() { - @Override - public void resourceChanged(IResourceChangeEvent event) { - try { - if (event.getDelta() == null && event.getSource() != ResourcesPlugin.getWorkspace()) { - return; - } - /* - * Collect data on renamed and removed projects - */ - Map renamedFrom = new HashMap<>(); - Map renamedTo = new HashMap<>(); - List removedProjects = new ArrayList<>(); - for (IResourceDelta delta : event.getDelta().getAffectedChildren(IResourceDelta.CHANGED | IResourceDelta.ADDED | IResourceDelta.REMOVED)) { - IResource resource = delta.getResource(); - if (resource instanceof IProject) { - IProject project = (IProject) resource; - if (delta.getKind() == IResourceDelta.REMOVED) { - if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) { - renamedFrom.put(delta.getMovedToPath(), project); - } else { - removedProjects.add(project); - } - } else if (delta.getKind() == IResourceDelta.ADDED && (delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) { - renamedTo.put(project.getFullPath(), project); - } - - } - } - - /* - * Update CF app cache and collect apps that have local project - * updated - */ - List appsToRefresh = new ArrayList<>(); - for (IProject project : removedProjects) { - CloudAppDashElement app = getApplication(project); - if (app!=null && app.setProject(null)) { - appsToRefresh.add(app); - } - } - for (Map.Entry entry : renamedFrom.entrySet()) { - IPath path = entry.getKey(); - IProject oldProject = entry.getValue(); - IProject newProject = renamedTo.get(path); - if (oldProject != null) { - CloudAppDashElement app = getApplication(oldProject); - if (app!=null && app.setProject(newProject)) { - appsToRefresh.add(app); - } - } - } - - /* - * Update BDEs - */ - for (CloudAppDashElement app : appsToRefresh) { - notifyElementChanged(app, "resourceChanged"); - } - } catch (Exception e) { - Log.log(e); - } - } - }; - - @Override - public RefreshState getRefreshState() { - return refreshTracker.refreshState.getValue(); - } - - private OldValueDisposer refreshTokenDisposer = new OldValueDisposer<>(this); - - /** - * This tracks the number of activeRefreshTokenListeners. It is used for debugging and testing purposes only. (To - * observe whether the listeners are properly disposed). - */ - public final AtomicInteger activeRefreshTokenListeners = new AtomicInteger(); - - public CloudFoundryBootDashModel(CloudFoundryRunTarget target, BootDashModelContext context, BootDashViewModel parent) { - super(target, parent); - cfDebugStrategies = new DebugStrategyManager(injections().getBeans(DebugSupport.class), getViewModel()); - this.elementFactory = new CloudDashElementFactory(context, target.getPropertyStore(), this); - - this.unsupportedPushProperties = new UnsupportedPushProperties(); - addDisposableChild(target.getClientExp().onChange((exp,v) -> { - - // https://github.com/spring-projects/sts4/issues/688 - // Errors occurring during refresh frequently open a pop-up - // dialogue that could be annoying to users. - // Since the errors are already logged and shown in the CF - // target, there is no need to also open the dialogue. - // To supress opening this dialogue, pass a null "UI", - // as the error handler in the refresh mechanism will not - // open a dialogue if there is no UI - UserInteractions ui = null; - this.refresh(ui); - - ClientRequests client = exp.getValue(); - if (client!=null && this.getRunTarget().getTargetProperties().getStoreCredentials()==StoreCredentialsMode.STORE_TOKEN) { - activeRefreshTokenListeners.incrementAndGet(); - refreshTokenDisposer.setValue(client.getRefreshTokens().doOnNext(refreshToken -> { - try { - this.getRunTarget().getTargetProperties().setCredentials(CFCredentials.fromRefreshToken(refreshToken)); - } catch (CannotAccessPropertyException e) { - Log.log(e); - } - }) - .doOnTerminate(activeRefreshTokenListeners::decrementAndGet) - .subscribe()); - } - checkApiVersion(); - })); - ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener, IResourceChangeEvent.POST_CHANGE); -// try { -// if (getRunTarget().getTargetProperties().get(CloudFoundryTargetProperties.DISCONNECTED) == null -// && (getRunTarget().getTargetProperties().isStoreCredentials() || getRunTarget().getTargetProperties().getCredentials() != null)) { -// // If CF target was connected previously and either password is stored or not stored but non-null then connect automatically -// Log.async(this.connect(ConnectMode.AUTOMATIC)); -// } -// } catch (CannotAccessPropertyException e1) { -// // TODO Auto-generated catch block -// e1.printStackTrace(); -// } - } - - @Override - public ObservableSet getElements() { - return allElements; - } - - @Override - public void dispose() { - if (cfDebugStrategies!=null) { - cfDebugStrategies.dispose(); - } - applications.dispose(); - ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener); - super.dispose(); - } - - @Override - public void refresh(UserInteractions ui) { - runAsynch(new TargetApplicationsRefreshOperation(this, ui), ui); - runAsynch(new ServicesRefreshOperation(this), ui); - } - - @Override - public Comparator getElementComparator() { - return ELEMENT_COMPARATOR; - } - - @Override - public CloudFoundryRunTarget getRunTarget() { - return (CloudFoundryRunTarget) super.getRunTarget(); - } - - @Override - public boolean canBeAdded(List sources) { - if (sources != null && !sources.isEmpty() && getRunTarget().isConnected()) { - for (Object obj : sources) { - // IMPORTANT: to avoid drag/drop into the SAME target, be - // sure - // all sources are from a different target - if (getProject(obj) == null || !isFromDifferentTarget(obj)) { - return false; - } - } - return true; - } - - return false; - } - - protected boolean isFromDifferentTarget(Object dropSource) { - if (dropSource instanceof BootDashElement) { - return ((BootDashElement) dropSource).getBootDashModel() != this; - } - - // If not a boot element that is being dropped, it is an element - // external to the boot dash view (e.g. project from project explorer) - return true; - } - - @Override - public void performDeployment( - final Set projectsToDeploy, - RunState runOrDebug - ) throws Exception { - DebugSupport debugSuppport = getDebugSupport(); - runAsynch(new ProjectsDeployer(CloudFoundryBootDashModel.this, ui(), projectsToDeploy, runOrDebug, debugSuppport), - ui()); - } - - public CloudAppDashElement addElement(CFApplicationDetail appDetail, IProject project) throws Exception { - CloudAppDashElement addedElement = null; - boolean changed = false; - synchronized (this) { - addedElement = applications.addApplication(appDetail.getName()); - addedElement.setDetailedData(appDetail); - // Update the cache BEFORE updating the model, since the model - // elements are handles to the cache - changed = addedElement.setProject(project); - - //Should be okay to call inside synch block as the events are fired from a - // a Job now. - } - if (changed) { - notifyElementChanged(addedElement, "addElement detected setProject caused a change"); - } - return addedElement; - } - - @Override - public CloudAppDashElement getApplication(String appName) { - Set apps = getApplications().getValues(); - for (CloudAppDashElement element : apps) { - if (appName.equals(element.getName())) { - return element; - } - } - return null; - } - - public CloudServiceInstanceDashElement getService(String serviceName) { - ImmutableSet services = getServices().getValues(); - for (CloudServiceInstanceDashElement s : services) { - if (s.getName().equals(serviceName)) { - return s; - } - } - return null; - } - - private CloudAppDashElement getApplication(IProject project) { - Set apps = getApplications().getValues(); - boolean includeNonExistingProjects = !project.exists(); - for (CloudAppDashElement element : apps) { - if (project.equals(element.getProject(includeNonExistingProjects))) { - return element; - } - } - return null; - } - - public CloudAppDashElement ensureApplication(String appName) { - synchronized (this) { - return applications.addApplication(appName); - } - } - - public void removeApplication(String appName) { - synchronized (this) { - applications.removeApplication(appName); - } - } - - /** - * Perform a 'shallow' update of the application elements in this model. This only - * ensures that elements with the right names exist, creating needed ones and - * disposing removed ones, but reusing existing ones. The state of the existing elements - * is not updated in any way. - */ - public void updateAppNames(Collection names) { - applications.setAppNames(names); - } - - public void updateElements(Collection apps) throws Exception { - if (apps == null) { - /* - * Error case: set empty list of BDEs don't modify state of local to CF artifacts mappings - */ - applications.setAppNames(ImmutableSet.of()); - } else { - synchronized (this) { - applications.setAppNames(getNames(apps)); - for (CFApplicationDetail appDetails : apps) { - CloudAppDashElement app = applications.getApplication(appDetails.getName()); - app.setDetailedData(appDetails); - } - } - } - } - - private ImmutableList getNames(Collection apps) { - ImmutableList.Builder builder = ImmutableList.builder(); - for (CFApplicationDetail app : apps) { - builder.add(app.getName()); - } - return builder.build(); - } - - - public OperationsExecution getOperationsExecution() { - return new OperationsExecution(this); - } - - public void updateApplication(CFApplicationDetail appDetails) { - CloudAppDashElement app = getApplication(appDetails.getName()); - if (app!=null) { - app.setDetailedData(appDetails); - } - } - - @Override - public void delete(Collection toRemove, UserInteractions ui) { - if (toRemove == null || toRemove.isEmpty()) { - return; - } - List> asyncDeletions = new ArrayList<>(toRemove.size()); - for (BootDashElement element : toRemove) { - if (element instanceof AsyncDeletable) { - asyncDeletions.add(((AsyncDeletable)element).deleteAsync()); - } - else if (element instanceof Deletable) { - try { - ((Deletable) element).delete(); - } catch (Exception e) { - Log.log(e); - } - } - } - if (!asyncDeletions.isEmpty()) { - int numElements = asyncDeletions.size(); - runAsynch("Deleting ["+numElements+"] services", "", (IProgressMonitor mon) -> { - //Careful... deleting more elements takes more time... - Duration timeout = Duration.ofSeconds(20*asyncDeletions.size()); - mon.beginTask("Deleting ["+numElements+"] services", numElements); - AtomicInteger leftToDelete = new AtomicInteger(numElements); - try { - ReactorUtils.safeMerge( - Flux.fromIterable(asyncDeletions) - .map((Mono deleteOp) -> { - return deleteOp.doOnTerminate(() -> { - mon.worked(1); - mon.setTaskName("Deleting ["+leftToDelete.decrementAndGet()+"] services"); - }); - }), - 5 //limit concurrency to avoid flooding/choking request broker - ) - .block(timeout); - } finally { - mon.done(); - } - }, ui); - } - } - - @Override - public String toString() { - return this.getClass().getName() + "(" + getRunTarget().getName() + ")"; - } - - private static ITextFileBuffer getDirtyBuffer(IFile file) { - ITextFileBuffer buffer = FileBuffers.getTextFileBufferManager().getTextFileBuffer(file.getFullPath(), LocationKind.IFILE); - if (buffer!=null && buffer.isDirty()) { - return buffer; - } - return null; - } - - /** - * - * @param project - * @param ui - * @param requests - * @param monitor - * @return non-null deployment properties for the application. - * @throws Exception - * if error occurred while resolving the deployment properties - * @throws OperationCanceledException - * if user canceled operation while resolving deployment - * properties - */ - public CloudApplicationDeploymentProperties resolveDeploymentProperties(CloudAppDashElement cde, UserInteractions ui, IProgressMonitor monitor) throws Exception { - IProject project = cde.getProject(); - CFApplication app = cde.getSummaryData(); - - CloudData cloudData = buildOperationCloudData(monitor, project); - - CloudApplicationDeploymentProperties deploymentProperties = CloudApplicationDeploymentProperties.getFor(project, cloudData, app); - CloudAppDashElement element = app == null ? null : getApplication(app.getName()); - final IFile manifestFile = element == null ? null : element.getDeploymentManifestFile(); - if (manifestFile != null) { // Manifest file deployment mode - - // Check if file exists in case the stored file is obsolete (e.g. no longer exists) - if (manifestFile.exists()) { - if (!saveManifestBeforePush(manifestFile, ui)) { - throw new OperationCanceledException(); - } else { - final String yamlContents = IOUtil.toString(manifestFile.getContents()); - String errorMessage = null; - TextEdit edit = null; - DumperOptions options = YamlGraphDeploymentProperties.createDumperOptions(); - try { - YamlGraphDeploymentProperties yamlGraph = new YamlGraphDeploymentProperties(yamlContents, deploymentProperties.getAppName(), cloudData); - MultiTextEdit me = yamlGraph.getDifferences(deploymentProperties); - edit = me != null && me.hasChildren() ? me : null; - if (yamlGraph.getInheritFilePath() != null) { - errorMessage = "'inherit' attribute is present in the manifest but is not supported. Merge with caution."; - } - } catch (MalformedTreeException e) { - Log.log(e); - errorMessage = "Failed to create text differences between local manifest file and deployment properties on CF. Merge with caution."; - edit = new ReplaceEdit(0, yamlContents.length(), - new Yaml(new SafeConstructor(), new Representer(options), options) - .dump(ApplicationManifestHandler.toYaml(deploymentProperties, cloudData))); - } catch (Throwable t) { - Log.log(t); - errorMessage = "Failed to parse local manifest file YAML contents. Merge with caution."; - edit = new ReplaceEdit(0, yamlContents.length(), - new Yaml(new SafeConstructor(), new Representer(options), options) - .dump(ApplicationManifestHandler.toYaml(deploymentProperties, cloudData))); - } - - /* - * If UI is available and there differences between manifest and - * current deployment properties on CF then prompt the user to - * perform the merge - */ - if (edit != null && ui != null) { - final IDocument doc = new Document(yamlContents); - edit.apply(doc); - - final YamlFileInput left = new YamlFileInput(manifestFile, - BootDashActivator.getDefault().getImageRegistry().get(BootDashActivator.CLOUD_ICON)); - final YamlInput right = new YamlInput("Current deployment properties from Cloud Foundry", - BootDashActivator.getDefault().getImageRegistry().get(BootDashActivator.CLOUD_ICON), - doc.get()); - - CompareConfiguration config = new CompareConfiguration(); - config.setLeftLabel(left.getName()); - config.setLeftImage(left.getImage()); - config.setRightLabel(right.getName()); - config.setRightImage(right.getImage()); - config.setLeftEditable(true); - config.setProperty("manifest", manifestFile); - - final String message = errorMessage; - - final CompareEditorInput input = new CompareEditorInput(config) { - @Override - protected Object prepareInput(IProgressMonitor arg0) - throws InvocationTargetException, InterruptedException { - setMessage(message); - return new DiffNode(left, right); - } - }; - input.setTitle("Merge Local Deployment Manifest File"); - - input.run(monitor); - ManifestDiffDialogModel model = new ManifestDiffDialogModel(input); - Result result = cfUi().openManifestDiffDialog(model); - if (result==null) { - result = Result.USE_MANIFEST; - } - switch (result) { - case CANCELED: - throw new OperationCanceledException(); - case FORGET_MANIFEST: - element.setDeploymentManifestFile(null); - /* - * Use the current CF deployment properties, hence just break out of the switch - */ - break; - case USE_MANIFEST: - /* - * Load deployment properties from YAML text content - */ - final byte[] yamlBytes = left.getContent(); - List props = new ApplicationManifestHandler(project, - cloudData, manifestFile) { - @Override - protected InputStream getInputStream() throws Exception { - return new ByteArrayInputStream(yamlBytes); - } - }.load(monitor); - CloudApplicationDeploymentProperties found = null; - for (CloudApplicationDeploymentProperties p : props) { - if (deploymentProperties.getAppName().equals(p.getAppName())) { - found = p; - break; - } - } - if (found == null) { - throw ExceptionUtil.coreException( - "Cannot load deployment properties for application '" + deploymentProperties.getAppName() - + "' from the manifest file '" + manifestFile.getFullPath() + "'"); - } else { - deploymentProperties = found; - } - break; - default: - } - } - // TODO: refactor so that adding archive only gets called once for all properties resolving and creating cases. - // Reason to call multiple times in different conditions is to retain the old logic when - // switching to v2 usage and not introduce regressions with manifest diffing - addApplicationArchive(project, deploymentProperties, cloudData, ui, monitor); - } - } else { - // Still in manifest file deployment mode, but manifest file does not exist anymore therefore create properties - deploymentProperties = createDeploymentProperties(project, ui, monitor); - } - } else { - // Manual deployment mode - addApplicationArchive(project, deploymentProperties, cloudData, ui, monitor); - } - - // TODO: We need to clean up push and restart code. There are multiple paths that end up doing - // the same thing, so the check below is appearing in at least two different places. - // We should ideally only check for unsupported properties in one place: wherever we resolve - // deployment properties regardless of which path we take (either a project deployment or app restart) - getUnsupportedProperties().allowOrCancelIfFound(ui, deploymentProperties); - - return deploymentProperties; - } - - /** - * Check for dirty manifest. If manifest is dirty, ask user if it is okay to save. - * If they say yes do it. - * @return Whether push operation is okay to proceed. (Manifest is not dirty at the end). - * @throws ExecutionException - * @throws InterruptedException - */ - private boolean saveManifestBeforePush(IFile manifestFile, UserInteractions ui) throws Exception { - ITextFileBuffer dirtyManifest = getDirtyBuffer(manifestFile); - if (dirtyManifest==null) { - return true; - } else { - boolean save = ui.confirmOperation("Save Cf Manifest?", - "The CF manifest at `"+manifestFile.getFullPath()+"' has unsaved changes.\n\n" + - "Do you want to save it now?", - new String[] { - "Save", "Cancel" - }, 0 - ) == 0; - if (save) { - JobUtil.runInJob("Save dirty manifest", (progres) -> dirtyManifest.commit(progres, true)).get(); - } - return save; - } - } - - /** - * Creates deployment properties either based on user inout via the UI if UI context is available or generates default deployment properties - * @param project the workspace project - * @param ui UI context - * @param monitor progress monitor - * @return deployment properties - * @throws Exception - */ - public CloudApplicationDeploymentProperties createDeploymentProperties(IProject project, UserInteractions ui, IProgressMonitor monitor) throws Exception { - CloudData cloudData = buildOperationCloudData(monitor, project); - CloudApplicationDeploymentProperties props = null; - if (ui != null) { - DeploymentPropertiesDialogModel dialogModel; - dialogModel = new DeploymentPropertiesDialogModel(ui, cloudData, project, null, true); - IFile foundManifestFile = DeploymentPropertiesDialog.findManifestYamlFile(project); - dialogModel.setSelectedManifest(foundManifestFile); - dialogModel.setManifestType(foundManifestFile == null ? ManifestType.MANUAL : ManifestType.FILE); - - props = cfUi().promptApplicationDeploymentProperties(dialogModel); - - addApplicationArchive(project, props, cloudData, ui, monitor); - } - return props; - } - - private CfUserInteractions cfUi() { - return injections().getBean(CfUserInteractions.class); - } - - public void addApplicationArchive(IProject project, CloudApplicationDeploymentProperties properties, CloudData cloudData, - UserInteractions ui, IProgressMonitor monitor) throws Exception { - ICloudApplicationArchiver archiver = getArchiver(properties, cloudData, ui, monitor); - if (archiver != null) { - File archive = archiver.getApplicationArchive(monitor); - properties.setArchive(archive); - } else { - throw ExceptionUtil.coreException( - "No applicable archiver strategy found for project '"+project.getName()+"'! " + - "Check the project's packaging type; or add " + - "an explicit path attribute to your manifest.yml." - ); - } - } - - protected ICloudApplicationArchiver getArchiver( - CloudApplicationDeploymentProperties deploymentProperties, - CloudData cloudData, - UserInteractions ui, - IProgressMonitor mon - ) { - try { - for (CloudApplicationArchiverStrategy s : getArchiverStrategies(deploymentProperties, cloudData, ui, mon)) { - ICloudApplicationArchiver a = s.getArchiver(mon); - if (a != null) { - return a; - } - } - } catch (Exception e) { - Log.log(e); - } - return null; - } - - protected CloudApplicationArchiverStrategy[] getArchiverStrategies( - CloudApplicationDeploymentProperties deploymentProperties, - CloudData cloudData, - UserInteractions ui, - IProgressMonitor mon - ) throws Exception { - IProject project = deploymentProperties.getProject(); - - IFile manifestFile = deploymentProperties.getManifestFile(); - String appName = deploymentProperties.getAppName(); - ApplicationManifestHandler parser = new ApplicationManifestHandler(project, cloudData, manifestFile); - - return new CloudApplicationArchiverStrategy[] { - CloudApplicationArchiverStrategies.fromManifest(project, appName, parser), - CloudApplicationArchiverStrategies.packageAsJar(project, ui), - CloudApplicationArchiverStrategies.packageMvnAsWar(project, ui) - }; - } - - - @Override - public boolean canDelete(BootDashElement element) { - return element instanceof Deletable || element instanceof AsyncDeletable; - } - - @Override - public String getDeletionConfirmationMessage(Collection value) { - return "Are you sure that you want to delete the selected applications/services from: " - + getRunTarget().getName() + "? The applications/services will be permanently removed."; - } - - public boolean isConnected() { - return getRunTarget().isConnected(); - } - - public void setServices(Set newServices) { - this.services.replaceAll(newServices); - } - - public ObservableSet getApplications() { - return applications.getApplications(); - } - - public ImmutableSet getApplicationValues() { - return applications.getApplicationValues(); - } - - public ObservableSet getServices() { - return services; - } - - public CloudData buildOperationCloudData(IProgressMonitor monitor, IProject project) throws Exception { - return new CloudData(getRunTarget().getDomains(monitor), getRunTarget().getBuildpack(project), getRunTarget().getStacks(monitor)); - } - - public CloudDashElementFactory getElementFactory() { - return elementFactory; - } - - public ClientRequests getClient() { - return getRunTarget().getClient(); - } - - public List getCloudDomains(IProgressMonitor monitor) throws Exception { - return getRunTarget().getDomains(monitor); - } - - /* TODO: These asynch methods probably should not be here but leaving them in the model for now as model is commonly shared across boot dash */ - - public void runAsynch(String opName, String appName, JobBody body, UserInteractions ui) { - getOperationsExecution().runAsynch(opName, appName, body, ui); - } - - public void runSynch(String opName, String appName, JobBody body, UserInteractions ui) throws Exception { - CompletableFuture f = new CompletableFuture<>(); - runAsynch(opName, appName, (mon) -> { - try { - body.run(mon); - f.complete(null); - } catch (Throwable e) { - f.completeExceptionally(e); - } - }, ui); - f.get(); - } - - public void runAsynch(Operation op, UserInteractions ui) { - getOperationsExecution().runAsynch(op, ui); - } - - public void removeService(String serviceName) { - for (CloudServiceInstanceDashElement s : services.getValues()) { - if (s.getName().equals(serviceName)) { - services.remove(s); - } - } - } - - public UnsupportedPushProperties getUnsupportedProperties() { - return unsupportedPushProperties; - } - - public DebugSupport getDebugSupport() { - return cfDebugStrategies.getStrategy(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudServiceInstanceDashElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudServiceInstanceDashElement.java deleted file mode 100644 index 2b8927858..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/model/CloudServiceInstanceDashElement.java +++ /dev/null @@ -1,176 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 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.cf.model; - -import java.util.EnumSet; - -import org.eclipse.core.resources.IProject; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.Image; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFServiceInstance; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.model.AbstractBootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.AsyncDeletable; -import org.springframework.ide.eclipse.boot.dash.model.RunState; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn; -import org.springsource.ide.eclipse.commons.core.pstore.IPropertyStore; -import org.springsource.ide.eclipse.commons.core.pstore.PropertyStoreApi; -import org.springsource.ide.eclipse.commons.core.pstore.PropertyStores; - -import reactor.core.publisher.Mono; - -public class CloudServiceInstanceDashElement extends CloudDashElement implements AsyncDeletable { - - private static final EnumSet SERVICE_RUN_GOAL_STATES = EnumSet.noneOf(RunState.class); - - private static final BootDashColumn[] COLUMNS = {BootDashColumn.NAME, BootDashColumn.TAGS}; - - private final CFServiceInstance service; - private final PropertyStoreApi persistentProperties; - - public CloudServiceInstanceDashElement(AbstractBootDashModel parent, CFServiceInstance service, IPropertyStore modelStore) { - super(parent, service.getName()+"@"+parent.getRunTarget().getId()); - this.service = service; - IPropertyStore backingStore = PropertyStores.createSubStore("S"+getName(), modelStore); - this.persistentProperties = PropertyStores.createApi(backingStore); - } - - @Override - public CloudFoundryBootDashModel getBootDashModel() { - return (CloudFoundryBootDashModel) super.getBootDashModel(); - } - - @Override - public Object getParent() { - return getBootDashModel(); - } - - @Override - public int getLivePort() { - return -1; - } - - @Override - public String getLiveHost() { - return null; - } - - @Override - public ILaunchConfiguration getActiveConfig() { - return null; - } - - @Override - public void stop() throws Exception { - } - - @Override - public void restart(RunState runingOrDebugging, UserInteractions ui) throws Exception { - } - - @Override - public void openConfig(UserInteractions ui) { - } - - @Override - public int getActualInstances() { - return 0; - } - - @Override - public int getDesiredInstances() { - return 0; - } - - @Override - public String getName() { - return service.getName(); - } - - @Override - public BootDashColumn[] getColumns() { - return COLUMNS; - } - - @Override - public PropertyStoreApi getPersistentProperties() { - return persistentProperties; - } - - @Override - public IProject getProject() { - return null; - } - - @Override - public RunState getRunState() { - return null; - } - - @Override - public String getUrl() { - return service != null ? service.getDashboardUrl() : null; - } - - public String getDocumentationUrl() { - return service!=null ? service.getDocumentationUrl() : null; - } - - public CFServiceInstance getCloudService() { - return service; - } - - public String getPlan() { - CFServiceInstance s = getCloudService(); - return s==null?null:s.getPlan(); - } - - public String getService() { - CFServiceInstance s = getCloudService(); - return s==null?null:s.getService(); - } - - public String getDescription() { - CFServiceInstance s = getCloudService(); - return s==null?null:s.getDescription(); - } - - @Override - public Mono deleteAsync() { - CloudFoundryBootDashModel model = getBootDashModel(); - String serviceName = getName(); - return Mono.fromRunnable(this::cancelOperations) - .then(getClient().deleteServiceAsync(serviceName)) - .doOnSuccess((ignore) -> model.removeService(serviceName)); - } - - private ClientRequests getClient() { - return getTarget().getClient(); - } - - @Override - public EnumSet supportedGoalStates() { - return SERVICE_RUN_GOAL_STATES; - } - - @Override - public ImageDescriptor getCustomRunStateIcon() { - return BootDashActivator.getDefault().getImageRegistry().getDescriptor(BootDashActivator.SERVICE_ICON); - } - - @Override - public Image getPropertiesTitleIconImage() { - return BootDashActivator.getDefault().getImageRegistry().get(BootDashActivator.SERVICE_ICON); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/AppInstancesRefreshOperation.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/AppInstancesRefreshOperation.java deleted file mode 100644 index 9b550c3c3..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/AppInstancesRefreshOperation.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.ops; - -import java.time.Duration; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.RefreshState; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; - -import reactor.core.publisher.Flux; - -/** - * Refreshes the application instances. - *

- * This will indirectly refresh the application running state as the running - * state of an app is resolved from the number of running instances - * - */ -public class AppInstancesRefreshOperation extends CloudOperation { - - private List appsToLookUp; - - public AppInstancesRefreshOperation(CloudFoundryBootDashModel model, List appsToLookUp) { - super("Refreshing running state of applications in: " + model.getRunTarget().getName(), model); - this.appsToLookUp = appsToLookUp; - } - - @Override - protected void doCloudOp(IProgressMonitor monitor) throws Exception { - this.model.refreshTracker.call("Fetching App Instances...", () -> { - if (!appsToLookUp.isEmpty()) { - Duration timeToWait = Duration.ofSeconds(30); - ClientRequests client = model.getRunTarget().getClient(); - if (client!=null) { - client.getApplicationDetails(appsToLookUp) - .doOnNext(this.model::updateApplication) - .then() - .block(timeToWait); - } - } - return null; - }); - } - - @Override - public ISchedulingRule getSchedulingRule() { - return new RefreshSchedulingRule(model.getRunTarget()); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/ApplicationOperationEvent.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/ApplicationOperationEvent.java deleted file mode 100644 index c5f428d49..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/ApplicationOperationEvent.java +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.ops; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CloudAppInstances; - -/** - * Event that occurs during application operations. - */ -public interface ApplicationOperationEvent { - - void fire(); - - CloudAppInstances getAppInstances(); - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/CloudApplicationOperation.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/CloudApplicationOperation.java deleted file mode 100644 index 3d646ceeb..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/CloudApplicationOperation.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2018 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.cf.ops; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.console.LogType; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; - -/** - * A cloud operation that is performed on a Cloud application (for example, - * creating, starting, or stopping an application) - */ -public abstract class CloudApplicationOperation extends CloudOperation { - - protected String appName; - private ISchedulingRule schedulingRule; - private final CancelationToken cancelationToken; - - public CloudApplicationOperation(String opName, CloudFoundryBootDashModel model, String appName, CancelationToken cancelationToken) { - super(opName, model); - this.cancelationToken = cancelationToken; - this.appName = appName; - setSchedulingRule(new StartApplicationSchedulingRule(model.getRunTarget(), appName)); - } - - protected CloudAppDashElement getDashElement() { - return model.getApplication(appName); - } - - @Override - public ISchedulingRule getSchedulingRule() { - return this.schedulingRule; - } - - public void setSchedulingRule(ISchedulingRule schedulingRule) { - this.schedulingRule = schedulingRule; - } - - protected void log(String message) { - try { - model.getElementConsoleManager().writeToConsole(getDashElement(), message, LogType.STDOUT); - } catch (Exception e) { - BootDashActivator.log(e); - } - } - - protected void logAndUpdateMonitor(String message, IProgressMonitor monitor) { - if (monitor != null) { - monitor.setTaskName(message); - } - try { - model.getElementConsoleManager().writeToConsole(getDashElement(), message, LogType.STDOUT); - } catch (Exception e) { - BootDashActivator.log(e); - } - } - - @Override - String getOpErrorPrefix() { - return "Error: " + appName + " in '" + model.getRunTarget().getName() + "'"; - } - - public void checkTerminationRequested(IProgressMonitor mon) throws OperationCanceledException { - if ( - mon!=null && mon.isCanceled() || - cancelationToken!=null && cancelationToken.isCanceled() - ) { - throw new OperationCanceledException(); - } - } - - protected CancelationToken getCancelationToken() { - return cancelationToken; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/CloudOperation.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/CloudOperation.java deleted file mode 100644 index c1e324957..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/CloudOperation.java +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.ops; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.cf.ui.CfUserInteractions; -import org.springframework.ide.eclipse.boot.dash.cf.util.CloudErrors; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; - -public abstract class CloudOperation extends Operation { - - protected final CloudFoundryBootDashModel model; - - public CloudOperation(String opName, CloudFoundryBootDashModel model) { - super(opName); - this.model = model; - } - - abstract protected void doCloudOp(IProgressMonitor monitor) throws Exception, OperationCanceledException; - - @Override - protected Void runOp(IProgressMonitor monitor) throws Exception, OperationCanceledException { - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - try { - doCloudOp(monitor); - } catch (Exception e) { - CloudErrors.checkAndRethrowCloudException(e, getOpErrorPrefix()); - } - return null; - } - - String getOpErrorPrefix() { - return "Error in target: " + model.getRunTarget().getName(); - } - - protected CloudFoundryRunTarget getRunTarget() { - return model.getRunTarget(); - } - - protected ClientRequests getClientRequests() { - CloudFoundryRunTarget target = getRunTarget(); - if (target.isConnected()) { - return target.getClient(); - } - return null; - } - - protected SimpleDIContext getDIContext() { - return model.getViewModel().getContext().injections; - } - - protected CfUserInteractions cfUi() { - return getDIContext().getBean(CfUserInteractions.class); - } - - protected UserInteractions ui() { - return getDIContext().getBean(UserInteractions.class); - } - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/CloudSchedulingRule.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/CloudSchedulingRule.java deleted file mode 100644 index 7eae5f75c..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/CloudSchedulingRule.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.ops; - -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; - -public class CloudSchedulingRule implements ISchedulingRule { - - protected final RunTarget runTarget; - - public CloudSchedulingRule(RunTarget runTarget) { - this.runTarget = runTarget; - } - - @Override - public boolean contains(ISchedulingRule rule) { - return rule == this; - } - - @Override - public boolean isConflicting(ISchedulingRule rule) { - if (rule instanceof CloudSchedulingRule) { - CloudSchedulingRule otherRefreshRule = (CloudSchedulingRule) rule; - if (otherRefreshRule.getRunTarget().getId().equals(this.getRunTarget().getId())) { - return true; - } - } - return false; - } - - public RunTarget getRunTarget() { - return runTarget; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/JobBody.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/JobBody.java deleted file mode 100644 index e8331b138..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/JobBody.java +++ /dev/null @@ -1,17 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.ops; - -import org.eclipse.core.runtime.IProgressMonitor; - -public interface JobBody { - public void run(IProgressMonitor mon) throws Exception; -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/Operation.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/Operation.java deleted file mode 100644 index 4ed3d2c1f..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/Operation.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.ops; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.jface.operation.IRunnableContext; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.springframework.ide.eclipse.boot.dash.model.Nameable; - -public abstract class Operation implements Nameable { - - protected final String opName; - - public Operation(String opName) { - this.opName = opName; - } - - public String getName() { - return this.opName; - } - - public T run(IProgressMonitor monitor) throws Exception, OperationCanceledException { - monitor.setTaskName(getName()); - return runOp(monitor); - } - - protected abstract T runOp(IProgressMonitor monitor) throws Exception, OperationCanceledException; - - /** - * Optional. Return null if no scheduling rule is needed - * - * @return - */ - public ISchedulingRule getSchedulingRule() { - return null; - } - - public T run(IRunnableContext context, boolean fork) throws Exception { - - final List val = new ArrayList(); - IRunnableWithProgress runnable = new IRunnableWithProgress() { - - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - try { - val.add(Operation.this.run(monitor)); - } catch (Exception e) { - throw new InvocationTargetException(e); - } - } - }; - try { - context.run(fork, true, runnable); - - } catch (InvocationTargetException ite) { - // Don't throw the wrapper - throw ite.getTargetException() instanceof Exception ? (Exception) ite.getTargetException() : ite; - } - return val.get(0); - } - - @Override - public String toString() { - return getName(); - } -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/OperationsExecution.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/OperationsExecution.java deleted file mode 100644 index 54fcf3bfb..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/OperationsExecution.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.ops; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.core.runtime.jobs.Job; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens; -import org.springframework.ide.eclipse.boot.util.Log; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -public class OperationsExecution { - - - private final CloudFoundryBootDashModel model; - - public OperationsExecution(CloudFoundryBootDashModel model) { - this.model = model; - } - - public void runAsynch(String opName, String appName, JobBody runnable, UserInteractions ui) { - runAsynch(new CloudApplicationOperation(opName, model, appName, CancelationTokens.NULL) { - @Override - protected void doCloudOp(IProgressMonitor monitor) throws Exception, OperationCanceledException { - runnable.run(monitor); - } - }, ui); - } - - public void runAsynch(final Operation op) { - runAsynch(op, null); - } - - public void runAsynch(final Operation op, UserInteractions ui) { - if (op!=null) { - Job job = new Job(op.getName()) { - - @Override - protected IStatus run(IProgressMonitor monitor) { - try { - op.run(monitor); - } catch (Exception e) { - if (!ExceptionUtil.isCancelation(e)) { - if (ui != null) { - String message = e.getMessage() != null && e.getMessage().trim().length() > 0 - ? e.getMessage() - : "Error type: " + e.getClass().getName() - + ". Check Error Log view for further details."; - ui.errorPopup("Operation Failure", message); - - } - Log.log(e); - } - } - // Only return OK status to avoid a second error dialogue - // appearing, which is opened by Eclipse when a job returns - // error status. - return Status.OK_STATUS; - } - - }; - - ISchedulingRule rule = op.getSchedulingRule(); - if (rule != null) { - job.setRule(rule); - } - - job.setPriority(Job.INTERACTIVE); - job.schedule(); - } - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/ProjectsDeployer.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/ProjectsDeployer.java deleted file mode 100644 index 2458a8ed4..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/ProjectsDeployer.java +++ /dev/null @@ -1,248 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2018 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.cf.ops; - -import java.io.StringWriter; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.function.Consumer; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFPushArguments; -import org.springframework.ide.eclipse.boot.dash.cf.debug.DebugSupport; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudData; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.JmxSupport; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel.Result; -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.LocalRunTarget; -import org.springframework.ide.eclipse.boot.dash.model.RunState; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; -import org.springframework.ide.eclipse.boot.util.Log; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -public class ProjectsDeployer extends CloudOperation { - - private static final boolean DEBUG = - (""+Platform.getLocation()).contains("bamboo") || - (""+Platform.getLocation()).contains("kdvolder"); - - private static void debug(String string) { - if (DEBUG) { - System.out.println(string); - } - } - - private final Set projectsToDeploy; - private final UserInteractions ui; - private final RunState runOrDebug; - private final DebugSupport debugSupport; - - public ProjectsDeployer(CloudFoundryBootDashModel model, - UserInteractions ui, - Set projectsToDeploy, - RunState runOrDebug, - DebugSupport debugSupport) { - super("Deploying projects", model); - this.projectsToDeploy = projectsToDeploy; - this.ui = ui; - this.runOrDebug = runOrDebug; - this.debugSupport = debugSupport; - } - - @Override - protected void doCloudOp(IProgressMonitor monitor) throws Exception, OperationCanceledException { - monitor.beginTask("Deploy projects", projectsToDeploy.size()); - try { - for (Iterator it = projectsToDeploy.iterator(); it.hasNext();) { - IProject project = it.next(); - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - deployProject(project, new SubProgressMonitor(monitor, 1)); - } - } finally { - monitor.done(); - } - } - - private void deployProject(IProject project, IProgressMonitor monitor) throws Exception { - debug("deployProject["+project.getName()+"] starting"); - CloudApplicationDeploymentProperties properties = model.createDeploymentProperties(project, ui, monitor); - debug("deployProject["+project.getName()+"] got deployment properties"); - - // IMPORTANT: We check for unsupported properties BEFORE creating the CDE, so that if operation is cancelled, - // the cde has not been created and it avoids having it appear in the boot dash view - model.getUnsupportedProperties().allowOrCancelIfFound(ui, properties); - - CloudAppDashElement cde = model.ensureApplication(properties.getAppName()); - debug("deployProject["+project.getName()+"] created cde: "+cde.getName()); - model.runAsynch("Deploy project '"+project.getName()+"'", properties.getAppName(), (IProgressMonitor progressMonitor) -> { - doDeployProject(cde, properties, project, progressMonitor); - }, ui); - } - - protected CloudData buildOperationCloudData(IProgressMonitor monitor, IProject project) throws Exception { - return new CloudData(getRunTarget().getDomains(monitor), getRunTarget().getBuildpack(project), getRunTarget().getStacks(monitor)); - } - - protected void doDeployProject(CloudAppDashElement cde, CloudApplicationDeploymentProperties initialProperties, - IProject project, IProgressMonitor monitor) throws Exception { - ClientRequests client = model.getRunTarget().getClient(); - CancelationToken cancelationToken = cde.createCancelationToken(); - - IFile manifestFile = initialProperties.getManifestFile(); - - // An app may already exist in CF, so when confirming to replace the exist app below, the option to - // use the existing app deployment properties rather than the initial properties may result in a different deployment - // properties. Therefore use a LiveExpression to support possible change in the properties to be used. - LiveVariable pushPropertiesToUse = new LiveVariable<>( - initialProperties); - pushPropertiesToUse.addListener((exp, val) -> { - // Make sure that the local archive gets set in the properties, even on changes, - // because - // we want to push the locally archived sources regardless of which other - // properties have changed (e.g. bound services, env vars, etc...) - val.setArchive(initialProperties.getArchive()); - val.setEnableJmxSshTunnel(initialProperties.getEnableJmxSshTunnel()); - - }); - - try { - - cde.whileStarting(ui, cancelationToken, monitor, () -> { - CFApplicationDetail existingCloudApp = client.getApplication(initialProperties.getAppName()); - if (existingCloudApp != null) { - CloudData cloudData = buildOperationCloudData(monitor, project); - CloudApplicationDeploymentProperties existingAppProperties = CloudApplicationDeploymentProperties.getFor(project, cloudData, existingCloudApp); - - confirmReplaceApp(cloudData, cde, existingAppProperties, project, manifestFile, monitor, (result) -> { - switch (result) { - case CANCELED: - cde.print("Canceled pushing project '"+project.getName() + "'"); - throw new OperationCanceledException(); - case USE_MANIFEST: - // Initial properties were generated from Manifest some point earlier so just set the initial properties - // if using manifest - pushPropertiesToUse.setValue(initialProperties); - cde.setDeploymentManifestFile(initialProperties.getManifestFile()); - break; - case FORGET_MANIFEST: - // "Forget Manifest" means use the existing Cloud app deployment properties (e.g retain existing bound services, memory, env vars, etc..). Only the - // app content will be replaced - cde.setDeploymentManifestFile(null); - pushPropertiesToUse.setValue(existingAppProperties); - break; - } - }); - } else { - cde.setDeploymentManifestFile(manifestFile); - } - cde.setProject(project); - copyTags(project, cde); - cde.print("Pushing project '"+project.getName()+"'"); - cde.setEnableJmxSshTunnel(pushPropertiesToUse.getValue().getEnableJmxSshTunnel()); - JmxSupport jmxSupport = cde.getJmxSupport(); - try (CFPushArguments args = pushPropertiesToUse.getValue().toPushArguments(model.getCloudDomains(monitor))) { - if (jmxSupport!=null) jmxSupport.setupEnvVars(args.getEnv()); - if (isDebugEnabled()) { - debugSupport.setupEnvVars(args.getEnv()); - } - client.push(args, CancelationTokens.merge(cancelationToken, monitor)); - cde.print("Pushing project '"+project.getName()+"' SUCCEEDED!"); - pushPropertiesToUse.close(); - } - if (cde.refresh()!=null) { - //Careful... connecting the debugger must be done after the refresh because it needs the app guid which - // won't be available for a newly created element if its not yet been populated with data from CF. - if (isDebugEnabled()) { - debugSupport.createOperation(cde, "Connect Debugger for "+cde.getName() , ui, cancelationToken).runOp(monitor); - } - } - }); - } catch (Exception e) { - cde.refresh(); - cde.printError("Pushing FAILED!"); - if (!ExceptionUtil.isCancelation(e)) { - Log.log(e); - if (ui != null) { - String message = e.getMessage() != null && e.getMessage().trim().length() > 0 ? e.getMessage() - : "Error type: " + e.getClass().getName() - + ". Check Error Log view for further details."; - ui.errorPopup("Operation Failure", message); - } - } - } - } - - private boolean isDebugEnabled() { - return runOrDebug==RunState.DEBUGGING && debugSupport!=null; - } - - private void copyTags(IProject project, CloudAppDashElement cde) { - BootDashElement localElement = findLocalBdeForProject(project); - if (localElement!=null) { - copyTags(localElement, cde); - } - } - - private BootDashElement findLocalBdeForProject(IProject project) { - BootDashModel localModel = model.getViewModel().getSectionByTargetId(LocalRunTarget.INSTANCE.getId()); - if (localModel != null) { - for (BootDashElement bde : localModel.getElements().getValue()) { - if (project.equals(bde.getProject())) { - return bde; - } - } - } - return null; - } - - private static void copyTags(BootDashElement sourceBde, BootDashElement targetBde) { - LinkedHashSet tagsToCopy = sourceBde.getTags(); - if (tagsToCopy != null && !tagsToCopy.isEmpty()) { - LinkedHashSet targetTags = targetBde.getTags(); - for (String tag : tagsToCopy) { - targetTags.add(tag); - } - targetBde.setTags(targetTags); - } - } - - private void confirmReplaceApp(CloudData cloudData, CloudAppDashElement element, CloudApplicationDeploymentProperties existingAppProperties, IProject project, IFile manifestFile, IProgressMonitor monitor, Consumer handleResult) throws Exception{ - StringWriter writer = new StringWriter(); - writer.append("Replace existing Cloud application - "); - writer.append(existingAppProperties.getAppName()); - writer.append(" - with the project '"); - writer.append(project.getName()); - writer.append("'?"); - - String title = writer.toString(); - - Result result = cfUi().confirmReplaceApp(title, cloudData, manifestFile, existingAppProperties); - - handleResult.accept(result); - } -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/RefreshSchedulingRule.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/RefreshSchedulingRule.java deleted file mode 100644 index 102b1b1ab..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/RefreshSchedulingRule.java +++ /dev/null @@ -1,21 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.ops; - -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; - -public class RefreshSchedulingRule extends CloudSchedulingRule { - - public RefreshSchedulingRule(RunTarget runTarget) { - super(runTarget); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/RemoteDevClientStartOperation.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/RemoteDevClientStartOperation.java deleted file mode 100644 index b497bb94a..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/RemoteDevClientStartOperation.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.ops; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.eclipse.debug.core.ILaunchManager; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.devtools.DevtoolsUtil; -import org.springframework.ide.eclipse.boot.dash.model.RunState; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; - -/** - * Operation for (re)starting Remote DevTools Client - * - * @author Alex Boyko - * - */ -public class RemoteDevClientStartOperation extends CloudApplicationOperation { - - private final RunState startMode; - - public RemoteDevClientStartOperation(CloudFoundryBootDashModel model, String appName, RunState startMode, CancelationToken cancelationToken) { - super("Starting Remote DevTools Client for application '" + appName + "'", model, appName, cancelationToken); - this.startMode = startMode; - } - - @Override - protected void doCloudOp(IProgressMonitor monitor) throws Exception, OperationCanceledException { - CloudAppDashElement cde = model.getApplication(appName); - if (cde == null || cde.getProject() == null) { - throw new CoreException(new Status(IStatus.ERROR, BootDashActivator.PLUGIN_ID, "Local project not associated to CF app '" + appName + "'")); - } - DevtoolsUtil.disconnectDevtoolsClientsFor(cde); - //TODO: create a 'monitor' that is aware of cancelation token to apss to the launch operation. - DevtoolsUtil.launchDevtools(cde, DevtoolsUtil.getSecret(cde.getProject()), startMode == RunState.DEBUGGING ? ILaunchManager.DEBUG_MODE : ILaunchManager.RUN_MODE , monitor); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/SelectManifestOp.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/SelectManifestOp.java deleted file mode 100644 index 7c5a59acd..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/SelectManifestOp.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 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.cf.ops; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudData; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialogModel.ManifestType; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -public class SelectManifestOp extends CloudOperation { - - protected final CloudAppDashElement cde; - - public SelectManifestOp(CloudAppDashElement cde) { - super("Select a manifest file", cde.getBootDashModel()); - this.cde = cde; - } - - @Override - protected void doCloudOp(final IProgressMonitor monitor) throws Exception, OperationCanceledException { - - IProject project = cde.getProject(); - - if (cde == null || project == null) { - return; - } - - IFile manifest = cde.getDeploymentManifestFile(); - - /* - * Commented out because manual manifest contents based on current - * deployment props from CF don't need to be the latest since they are - * not editable - */ - // /* -// * Refresh the latest cloud application -// */ -// new RefreshApplications(model, Collections.singletonList(model.getAppCache().getApp(project))).run(monitor); - - CloudData cloudData = model.buildOperationCloudData(monitor, project); - - DeploymentPropertiesDialogModel dialogModel = new DeploymentPropertiesDialogModel(ui(), cloudData, project, cde.getSummaryData(), false); - dialogModel.setSelectedManifest(manifest); - dialogModel.setManifestType(manifest == null ? ManifestType.MANUAL : ManifestType.FILE); - CloudApplicationDeploymentProperties props = cfUi().promptApplicationDeploymentProperties(dialogModel); - - if (props == null) { - throw ExceptionUtil.coreException("Error loading deployment properties from the manifest YAML"); - } - - cde.setDeploymentManifestFile(props.getManifestFile()); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/ServicesRefreshOperation.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/ServicesRefreshOperation.java deleted file mode 100644 index 11f10c3cb..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/ServicesRefreshOperation.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.ops; - -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFServiceInstance; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudDashElementFactory; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudServiceInstanceDashElement; -import org.springframework.ide.eclipse.boot.util.Log; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSet.Builder; - -public class ServicesRefreshOperation extends CloudOperation{ - -// private static final boolean DEBUG = (""+Platform.getLocation()).contains("kdvolder"); - -// private static void debug(String msg) { -// if (DEBUG) { -// System.out.println(msg); -// } -// } - - final private CloudDashElementFactory elementFactory; - - public ServicesRefreshOperation(CloudFoundryBootDashModel model) { - super("Refresh Cloud Services", model); - this.elementFactory = model.getElementFactory(); - } - - @Override - protected void doCloudOp(IProgressMonitor monitor) throws Exception, OperationCanceledException { - monitor.beginTask("Refresh services", 2); - boolean success = false; - try { - ClientRequests client = getClientRequests(); - monitor.worked(1); - if (client!=null) { -// debug("Resfres Services for connected client"); - List serviceInfos = client.getServices(); - Builder services = ImmutableSet.builder(); - for (CFServiceInstance service : serviceInfos) { - services.add(elementFactory.createService(service)); - } - model.setServices(services.build()); - success = true; - } - } catch (Exception e) { - //If Network is down, typically the same error will happen in parallel for refresing the aps. - //We don't want a double popup so just log this here instead of letting it fly. - //Note: handling this would be possible if the operations where able to parallel composed so there can - //be a single handler attached that is called when both of them are complete. - Log.log(e); - } finally { - if (!success) { -// debug("Resfresh Services for DISconnected client"); - model.setServices(ImmutableSet.of()); - } - monitor.done(); - } - } - - public ISchedulingRule getSchedulingRule() { - return new RefreshSchedulingRule(model.getRunTarget()); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/SetHealthCheckOperation.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/SetHealthCheckOperation.java deleted file mode 100644 index 36458ae8e..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/SetHealthCheckOperation.java +++ /dev/null @@ -1,78 +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.cf.ops; - -import java.util.UUID; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; - -/** - * @author Kris De Volder - */ -public class SetHealthCheckOperation extends CloudApplicationOperation { - - private String hcType; - private CloudAppDashElement app; - private UserInteractions ui; - private boolean confirmChange; - private static final String CONFIRM_CHANGE_KEY = SetHealthCheckOperation.class.getName()+".confirm"; - - public SetHealthCheckOperation(CloudAppDashElement app, String hcType, UserInteractions ui, boolean confirmChange, CancelationToken cancelationToken) { - super("set-health-check "+app.getName()+" "+hcType, app.getBootDashModel(), app.getName(), cancelationToken); - this.app = app; - this.hcType = hcType; - this.ui = ui; - this.confirmChange = confirmChange; - } - - public SetHealthCheckOperation(CloudAppDashElement app, String hcType, CancelationToken cancelationToken) { - this(app, hcType, null, false, cancelationToken); - } - - @Override - protected void doCloudOp(IProgressMonitor monitor) throws Exception, OperationCanceledException { - monitor.beginTask(getName(), 2); - try { - ClientRequests client = getClientRequests(); - UUID guid = app.getAppGuid(); - String current = client.getHealthCheck(guid); - //When current==null it means that there's no 'health-check' info in the info returned by - //cloudcontroller. Probably this means app has no support for this and so we shouldn't try to - //set it. - monitor.worked(1); - if (current!=null) { - if (!current.equals(hcType)) { - boolean confirmed = true; - if (confirmChange) { - confirmed = ui.yesNoWithToggle(CONFIRM_CHANGE_KEY, "Set health check for '"+app+"' to '"+hcType+"'?", - "Health check is currently set to '"+current+"'. This may interfere with Spring Boot Devtools "+ - "reload functionality. Do you want to set it to '"+hcType+"'?", - "Remember my decision" - ); - } - if (confirmed) { - client.setHealthCheck(guid, hcType); - app.setHealthCheck(hcType); - } - monitor.worked(1); - } - } - } finally { - monitor.done(); - } - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/StartApplicationSchedulingRule.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/StartApplicationSchedulingRule.java deleted file mode 100644 index e4c5da174..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/StartApplicationSchedulingRule.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.ops; - -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; - -public class StartApplicationSchedulingRule extends CloudSchedulingRule { - - private final String appName; - - public StartApplicationSchedulingRule(RunTarget runTarget, String appName) { - super(runTarget); - this.appName = appName; - } - - @Override - public boolean isConflicting(ISchedulingRule otherRule) { - if (otherRule instanceof CloudSchedulingRule) { - CloudSchedulingRule otherCloudRule = (CloudSchedulingRule) otherRule; - - // Possibly in conflict only if the other operation is also on the - // same run target - if (otherCloudRule.getRunTarget().getId().equals(this.getRunTarget().getId())) { - // Application ops for the same target cannot run in parallel - // with that target's refresh op - if (otherCloudRule instanceof RefreshSchedulingRule) { - return true; - } else if (otherCloudRule instanceof StartApplicationSchedulingRule) { - - StartApplicationSchedulingRule otherApplicationSchedlingRule = (StartApplicationSchedulingRule) otherCloudRule; - - // Only operation per app can be running. Other app - // operations can run in parallel for other apps - return otherApplicationSchedlingRule.getAppName().equals(this.getAppName()); - } - - } - } - return false; - } - - public String getAppName() { - return appName; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/StopApplicationSchedulingRule.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/StopApplicationSchedulingRule.java deleted file mode 100644 index 37306a778..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/StopApplicationSchedulingRule.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.ops; - -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; - -public class StopApplicationSchedulingRule extends CloudSchedulingRule { - - private final String appName; - - public StopApplicationSchedulingRule(RunTarget runTarget, String appName) { - super(runTarget); - this.appName = appName; - } - - @Override - public boolean isConflicting(ISchedulingRule otherRule) { - if (otherRule instanceof CloudSchedulingRule) { - CloudSchedulingRule otherCloudRule = (CloudSchedulingRule) otherRule; - - // Possibly in conflict only if the other operation is also on the - // same run target - if (otherCloudRule.getRunTarget().getId().equals(this.getRunTarget().getId()) - && otherCloudRule instanceof StopApplicationSchedulingRule) { - StopApplicationSchedulingRule otherApplicationSchedulingRule = (StopApplicationSchedulingRule) otherCloudRule; - - return otherApplicationSchedulingRule.getAppName().equals(this.getAppName()); - } - } - return false; - } - - public String getAppName() { - return this.appName; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/TargetApplicationsRefreshOperation.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/TargetApplicationsRefreshOperation.java deleted file mode 100644 index 393d1ae57..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ops/TargetApplicationsRefreshOperation.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.ops; - -import java.util.Collection; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.RefreshState; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableList.Builder; - -/** - * This performs a "two-tier" refresh as fetching list of - * {@link CloudApplication} can be slow, especially if also fetching each app's - * instances. - *

- * This refresh operation only fetches a "basic" shallow list of - * {@link CloudApplication}, which may be quicker to resolve, and notifies the - * model when element changes occur. - * - *

- * It also launches a separate refresh job that may take longer to complete - * which is fetching instances and app running state. - * - * @see AppInstancesRefreshOperation - */ -public final class TargetApplicationsRefreshOperation extends CloudOperation { - - private UserInteractions ui; - - public TargetApplicationsRefreshOperation(CloudFoundryBootDashModel model, UserInteractions ui) { - super("Refreshing list of Cloud applications for: " + model.getRunTarget().getName(), model); - this.ui = ui; - } - - @Override - synchronized protected void doCloudOp(IProgressMonitor monitor) throws Exception { - if (model.getRunTarget().isConnected()) { - model.refreshTracker.call("Fetching Apps...", () -> { - for (CloudAppDashElement app : model.getApplicationValues()) { - app.setError(null); // clear old error states. - } - try { - - // 1. Fetch basic list of applications. Should be the "faster" of - // the - // two refresh operations - - List apps = model.getRunTarget().getClient().getApplicationsWithBasicInfo(); - this.model.updateAppNames(getNames(apps)); - - // 2. Launch the slower app stats/instances refresh operation. - this.model.runAsynch(new AppInstancesRefreshOperation(this.model, apps), ui); - return null; - } catch (Exception e) { - /* - * Failed to obtain applications list from CF - */ - model.updateElements(null); - throw e; - } - }); - } else { - model.updateElements(null); - } - } - - private Collection getNames(List apps) { - Builder builder = ImmutableList.builder(); - for (CFApplication app : apps) { - builder.add(app.getName()); - } - return builder.build(); - } - - @Override - public ISchedulingRule getSchedulingRule() { - return new RefreshSchedulingRule(model.getRunTarget()); - } -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiver.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiver.java deleted file mode 100644 index fb4e6670c..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiver.java +++ /dev/null @@ -1,269 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2018 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.cf.packaging; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IPackageFragmentRoot; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.ui.jarpackager.IJarExportRunnable; -import org.eclipse.jdt.ui.jarpackager.JarPackageData; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.springframework.boot.loader.tools.Libraries; -import org.springframework.boot.loader.tools.Library; -import org.springframework.boot.loader.tools.LibraryCallback; -import org.springframework.boot.loader.tools.LibraryScope; -import org.springframework.boot.loader.tools.Repackager; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.ApplicationManifestHandler; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.JavaPackageFragmentRootHandler; -import org.springframework.ide.eclipse.boot.dash.util.UiUtil; -import org.springsource.ide.eclipse.commons.frameworks.core.util.FileUtil; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -public class CloudApplicationArchiver implements ICloudApplicationArchiver { - - private IJavaProject javaProject; - - private String applicationName; - - private final ApplicationManifestHandler parser; - - private static final String TEMP_FOLDER_NAME = "springidetempFolderForJavaAppJar"; - - public CloudApplicationArchiver(IJavaProject javaProject, String applicationName, - ApplicationManifestHandler parser) { - this.javaProject = javaProject; - this.applicationName = applicationName; - this.parser = parser; - } - - public File getApplicationArchive(IProgressMonitor monitor) throws Exception { - File archive = getArchiveFromManifest(monitor); - if (archive == null) { - - File packagedFile = null; - - JavaPackageFragmentRootHandler rootResolver = getPackageFragmentRootHandler(javaProject, monitor); - - final IPackageFragmentRoot[] roots = rootResolver.getPackageFragmentRoots(monitor); - - if (roots == null || roots.length == 0) { - throw ExceptionUtil.coreException("Unable to package project" + javaProject.getElementName() - + " as a jar application. Please verify that the project is a valid Java project and contains a main type in source."); - } - - IType mainType = rootResolver.getMainType(monitor); - - JarPackageData jarPackageData = getJarPackageData(roots, mainType, monitor); - - // generate a manifest file. Note that manifest files - // are only generated in the temporary jar meant for - // deployment. - // The associated Java project is no modified. - jarPackageData.setGenerateManifest(true); - - // This ensures that folders in output folders appear at root - // level - // Example: src/main/resources, which is in the project's - // classpath, contains non-Java templates folder and - // has output folder target/classes. If not exporting output - // folder, - // templates will be packaged in the jar using this path: - // resources/templates - // This may cause problems with the application's dependencies - // if they are looking for just /templates at top level of the - // jar - // If exporting output folders, templates folder will be - // packaged at top level in the jar. - jarPackageData.setExportOutputFolders(true); - - packagedFile = packageApplication(jarPackageData, monitor); - - bootRepackage(roots, packagedFile); - - archive = packagedFile; - } - - return archive; - } - - protected JavaPackageFragmentRootHandler getPackageFragmentRootHandler(IJavaProject javaProject, - IProgressMonitor monitor) throws CoreException { - - return new JavaPackageFragmentRootHandler(javaProject); - } - - protected void bootRepackage(final IPackageFragmentRoot[] roots, File packagedFile) throws Exception { - Repackager bootRepackager = new Repackager(packagedFile); - bootRepackager.repackage(new Libraries() { - - public void doWithLibraries(LibraryCallback callBack) throws IOException { - for (IPackageFragmentRoot root : roots) { - - if (root.isArchive()) { - - File rootFile = new File(root.getPath().toOSString()); - if (rootFile.exists()) { - callBack.library(new Library(rootFile, LibraryScope.COMPILE)); - } - } - } - } - }); - } - - protected JarPackageData getJarPackageData(IPackageFragmentRoot[] roots, IType mainType, IProgressMonitor monitor) - throws Exception { - - String filePath = getTempJarPath(); - - IPath location = new Path(filePath); - - // Note that if no jar builder is specified in the package data - // then a default one is used internally by the data that does NOT - // package any jar dependencies. - JarPackageData packageData = new JarPackageData(); - - packageData.setJarLocation(location); - - // Don't create a manifest. A repackager should determine if a generated - // manifest is necessary - // or use a user-defined manifest. - packageData.setGenerateManifest(false); - - // Since user manifest is not used, do not save to manifest (save to - // manifest saves to user defined manifest) - packageData.setSaveManifest(false); - - packageData.setManifestMainClass(mainType); - packageData.setElements(roots); - return packageData; - } - - protected File packageApplication(final JarPackageData packageData, IProgressMonitor monitor) throws Exception { - - int progressWork = 10; - final SubMonitor subProgress = SubMonitor.convert(monitor, progressWork); - - final File[] createdFile = new File[1]; - - final Exception[] error = new Exception[1]; - Display.getDefault().syncExec(new Runnable() { - - @Override - public void run() { - Shell shell = UiUtil.getShell(); - - IJarExportRunnable runnable = packageData.createJarExportRunnable(shell); - try { - runnable.run(subProgress); - - File file = new File(packageData.getJarLocation().toString()); - createdFile[0] = file; - - } catch (InvocationTargetException e) { - error[0] = e; - } catch (InterruptedException ie) { - error[0] = ie; - } finally { - subProgress.done(); - } - } - - }); - if (error[0] != null) { - throw error[0]; - } - - return createdFile[0]; - } - - public String getTempJarPath() throws Exception { - File tempFolder = FileUtil.createTempDirectory(TEMP_FOLDER_NAME); - tempFolder.delete(); - tempFolder.mkdirs(); - - if (!tempFolder.exists()) { - throw ExceptionUtil.coreException("Failed to create temporary jar file when packaging application for deployment: " - + tempFolder.getAbsolutePath()); - } - - File targetFile = new File(tempFolder, applicationName + ".jar"); - - String path = new Path(targetFile.getAbsolutePath()).toString(); - - System.out.println("getTempJarPath => "+path); - return path; - } - - public File getArchiveFromManifest(IProgressMonitor monitor) throws Exception { - String archivePath = null; - // Read the path again instead of deployment info, as a user may be - // correcting the path after the module was creating and simply - // attempting to push it again without the - // deployment wizard - if (parser.hasManifest()) { - archivePath = parser.getApplicationProperty(applicationName, ApplicationManifestHandler.PATH_PROP, monitor); - } - - File packagedFile = null; - if (archivePath != null) { - // Only support paths that point to archive files - IPath path = new Path(archivePath); - if (path.getFileExtension() != null) { - - if (!path.isAbsolute()) { - // Check if it is project relative first - IFile projectRelativeFile = javaProject.getProject().getFile(path); - if (projectRelativeFile != null && projectRelativeFile.exists()) { - packagedFile = projectRelativeFile.getLocation().toFile(); - } else { - // Case where file exists in file system but is not - // present in workspace (i.e. IProject may be out of - // synch with file system) - IPath projectPath = javaProject.getProject().getLocation(); - if (projectPath != null) { - archivePath = projectPath.append(archivePath).toString(); - File absoluteFile = new File(archivePath); - if (absoluteFile.exists() && absoluteFile.canRead()) { - packagedFile = absoluteFile; - } - } - } - } else { - // See if it is an absolute path - File absoluteFile = new File(archivePath); - if (absoluteFile.exists() && absoluteFile.canRead()) { - packagedFile = absoluteFile; - } - } - } - // If a path is specified but no file found stop further deployment - if (packagedFile == null) { - throw ExceptionUtil.coreException( - "No file found at: " + path + ". Unable to package the application for deployment"); - } else { - return packagedFile; - } - } - return null; - } -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategies.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategies.java deleted file mode 100644 index 2fc7aaca7..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategies.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.packaging; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IProgressMonitor; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.ApplicationManifestHandler; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; - -/** - * Some utilities for creating {@link CloudApplicationArchiverStrategy} instances. - * - * @author Kris De Volder - */ -public class CloudApplicationArchiverStrategies { - - public static CloudApplicationArchiverStrategy justReturn(final ICloudApplicationArchiver archiver) { - return new CloudApplicationArchiverStrategy() { - @Override - public ICloudApplicationArchiver getArchiver(IProgressMonitor mon) { - return archiver; - } - }; - } - - public static CloudApplicationArchiverStrategy fromManifest(IProject project, String appName, ApplicationManifestHandler parser) { - return new CloudApplicationArchiverStrategyFromManifest(project, appName, parser); - } - - public static CloudApplicationArchiverStrategy packageAsJar(IProject project, UserInteractions ui) { - return new CloudApplicationArchiverStrategyAsJar(project, ui); - } - - public static CloudApplicationArchiverStrategy packageMvnAsWar(IProject project, UserInteractions ui) { - return new CloudApplicationArchiverStrategyMavenAsWar(project, ui); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategy.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategy.java deleted file mode 100644 index c73d2ea89..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategy.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.packaging; - -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * Instances of this interface is responsible for initializing and instance of {@link ICloudApplicationArchiver}. - * @author Kris De Volder - */ -public interface CloudApplicationArchiverStrategy { - - /** - * A strategy may or may not always be applicable in a given situation. In that case it may return null when - * asked to produce a ICloudApplicationArchiver. - */ - ICloudApplicationArchiver getArchiver(IProgressMonitor mon); - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategyAsJar.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategyAsJar.java deleted file mode 100644 index df5380ebe..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategyAsJar.java +++ /dev/null @@ -1,309 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2018 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.cf.packaging; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.JavaCore; -import org.springframework.boot.loader.tools.JarWriter; -import org.springframework.boot.loader.tools.Libraries; -import org.springframework.boot.loader.tools.Library; -import org.springframework.boot.loader.tools.LibraryCallback; -import org.springframework.boot.loader.tools.LibraryScope; -import org.springframework.boot.loader.tools.Repackager; -import org.springframework.ide.eclipse.boot.core.ISpringBootProject; -import org.springframework.ide.eclipse.boot.core.SpringBootCore; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.launch.BootLaunchConfigurationDelegate; -import org.springframework.ide.eclipse.boot.util.JavaProjectUtil; -import org.springframework.ide.eclipse.boot.util.Log; -import org.springsource.ide.eclipse.commons.frameworks.core.maintype.MainTypeFinder; -import org.springsource.ide.eclipse.commons.frameworks.core.util.FileUtil; - -public class CloudApplicationArchiverStrategyAsJar implements CloudApplicationArchiverStrategy { - - private static final String TEMP_FOLDER_NAME = "springidetempFolderForJavaAppJar"; - private static final boolean DEBUG = false; - - private static void debug(String string) { - if (DEBUG) { - System.out.println(string); - } - } - - /** - * Classpath entries spilt into two lists, one that correspond to the current project's output folders - * and all the others (which correspond to the project's dependencies). The dependencies could be - * jars or output folders for other projects in the workspace. - */ - private static class SplitClasspath { - private List projectContents = new ArrayList<>(2); //one or two is typical - private List dependencies = new ArrayList<>(); - public SplitClasspath(IJavaProject jp, File[] entries) { - Set outputFolders = toFileSet(JavaProjectUtil.getOutputFolders(jp)); - for (File file : entries) { - if (contains(outputFolders, file)) { - projectContents.add(file); - } else { - dependencies.add(file); - } - } - } - - private boolean contains(Set outputFolders, File file) { - return outputFolders.contains(canonical(file)); - } - - private File canonical(File file) { - try { - return file.getCanonicalFile(); - } catch (IOException e) { - //Next best thing: - return file.getAbsoluteFile(); - } - } - - /** - * Convert a collection of Eclipse IContainer to List of java.io.File. Containers that - * don't correspond to stuff on disk are silently ignored. - */ - private Set toFileSet(Set containers) { - Set files = new HashSet<>(); - for (IContainer folder : containers) { - IPath loc = folder.getLocation(); - if (loc!=null) { - File file = loc.toFile(); - files.add(canonical(file)); //use canonical file to make equals / Set work as expected. - } - } - return files; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder("SplitClasspath(\n"); - for (File file : projectContents) { - builder.append(" "+file+"\n"); - } - builder.append(" ------------\n"); - for (File file : dependencies) { - builder.append(" "+file+"\n"); - } - builder.append(")"); - return builder.toString(); - } - } - - - - private static final File[] NO_FILES = new File[]{}; - - private static class Archiver implements ICloudApplicationArchiver { - - private IJavaProject jp; - private IType mainType; - private ILaunchConfiguration conf; - private BootLaunchConfigurationDelegate delegate; - private JarNameGenerator jarNames; - private File _tempFolder; - - Archiver(IJavaProject jp, IType mainType) throws CoreException { - this.jp = jp; - this.mainType = mainType; - this.conf = BootLaunchConfigurationDelegate.createWorkingCopy(mainType); - this.delegate = new BootLaunchConfigurationDelegate(); - this.jarNames = new JarNameGenerator(); - } - - private SplitClasspath getRuntimeClasspath() throws CoreException { - return new SplitClasspath(jp, toFiles(delegate.getClasspath(conf))); - } - - private File[] toFiles(String[] classpath) { - if (classpath!=null) { - File[] files = new File[classpath.length]; - for (int i = 0; i < files.length; i++) { - files[i] = new File(classpath[i]); - } - return files; - } - return NO_FILES; - } - - @Override - public File getApplicationArchive(IProgressMonitor mon) throws Exception { - SplitClasspath classpath = getRuntimeClasspath(); - File tempFolder = getTempFolder(); - File baseJar = new File(tempFolder, jp.getElementName()+".original.jar"); - File repackagedJar = new File(tempFolder, jp.getElementName()+".repackaged.jar"); - - createBaseJar(classpath.projectContents, baseJar); - repackage(baseJar, classpath.dependencies, repackagedJar); - return repackagedJar; - } - - private File getTempFolder() throws IOException { - if (_tempFolder==null) { - _tempFolder = FileUtil.createTempDirectory(TEMP_FOLDER_NAME); - } - return _tempFolder; - } - - private void createBaseJar(List projectContents, File baseJar) throws FileNotFoundException, IOException { - JarWriter jarWriter = new JarWriter(baseJar); - try { - for (File outputFolder : projectContents) { - writeFolder(jarWriter, outputFolder); - } - } finally { - jarWriter.close(); - } - } - - private void writeFolder(JarWriter jarWriter, File baseFolder) throws FileNotFoundException, IOException { - for (String name : baseFolder.list()) { - write(jarWriter, baseFolder, name); - } - } - - private void write(JarWriter jarWriter, File baseFolder, String relativePath) throws FileNotFoundException, IOException { - debug("Writing: "+relativePath + " from "+baseFolder); - File file = new File(baseFolder, relativePath); - if (file.isDirectory()) { - debug("Folder"); - for (String name : file.list()) { - write(jarWriter, baseFolder, pathJoin(relativePath, name)); - } - } else if (file.isFile()) { - debug("File"); - jarWriter.writeEntry(relativePath, new FileInputStream(file)); - } else { - debug("Huh?"); - } - } - - private String pathJoin(String relativePath, String name) { - return relativePath + "/" +name; - } - - private void repackage(File baseJar, List dependencies, File repackagedJar) throws IOException { - Repackager repackager = new Repackager(baseJar); - repackager.setMainClass(mainType.getFullyQualifiedName()); - repackager.repackage(repackagedJar, asLibraries(dependencies)); - } - - private Libraries asLibraries(final List dependencies) { - return new Libraries() { - public void doWithLibraries(LibraryCallback callback) throws IOException { - for (File dep : dependencies) { - if (dep.isFile()) { - callback.library(new Library(jarNames.createName(dep), dep, LibraryScope.COMPILE, false)); - } else if (dep.isDirectory()) { - String jarName = jarNames.createName(dep); - File jarFile = new File(getTempFolder(), jarName); - JarWriter jarWriter = new JarWriter(jarFile); - try { - writeFolder(jarWriter, dep); - } finally { - jarWriter.close(); - } - callback.library(new Library(jarName, jarFile, LibraryScope.COMPILE, false)); - } - } - } - }; - } - } - - private SpringBootCore springBootCore = SpringBootCore.getDefault(); - private IProject project; - private UserInteractions ui; - - public CloudApplicationArchiverStrategyAsJar(IProject project, UserInteractions ui) { - this.project = project; - this.ui = ui; - } - - @Override - public ICloudApplicationArchiver getArchiver(IProgressMonitor mon) { - try { - final IJavaProject jp = getJavaProject(); - if (jp!=null && checkPackagingType(jp)) { - final IType type = getMainType(jp, mon); - if (type!=null) { - return new Archiver(jp, type); - } - } - } catch (Exception e) { - Log.log(e); - } - return null; - } - - private boolean checkPackagingType(IJavaProject jp) throws CoreException { - ISpringBootProject bootProject = springBootCore.project(jp); - if (bootProject==null) { - //Gradle is poorly supported. We don't know how to determin packaging type. So just - // give such projects the benefit of the doubdt. They *might have the correct - // packaging type. - return true; - } - return ISpringBootProject.PACKAGING_JAR.equals(bootProject.getPackaging()); - } - - private IJavaProject getJavaProject() { - try { - if (project.isAccessible() && project.hasNature(JavaCore.NATURE_ID)) { - return JavaCore.create(project); - } - } catch (Exception e) { - Log.log(e); - } - return null; - } - - private IType getMainType(IJavaProject jp, IProgressMonitor mon) { - try { - IType[] candidates = MainTypeFinder.guessMainTypes(jp, mon); - if (candidates!=null && candidates.length>0) { - if (candidates.length==1) { - return candidates[0]; - } else { - //TODO: should persist main type so we don't ask again next time. - // however we persist this, user must be able to change it. - // Prolly we should create a launchconf to store info like this and - // create UI for user to modify it. - return ui.chooseMainType(candidates, "Choose a main type", "Deploying a standalone boot-app requires " - + "that the main type is identified. We found several candidates, please choose one." ); - } - } - } catch (Exception e) { - Log.log(e); - } - return null; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategyFromManifest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategyFromManifest.java deleted file mode 100644 index b324328ee..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategyFromManifest.java +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.packaging; - -import java.io.File; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.ApplicationManifestHandler; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -/** - * Archiver strategy that consults manifest.yml file for an entry pointing to an existing archive. - * The existing archive is returned by the archiver rather than building an archive. - */ -public class CloudApplicationArchiverStrategyFromManifest implements CloudApplicationArchiverStrategy { - -// private IProject project; - private String applicationName; - private ApplicationManifestHandler parser; - - public CloudApplicationArchiverStrategyFromManifest(IProject project, String applicationName, ApplicationManifestHandler parser) { -// this.project = project; - this.applicationName = applicationName; - this.parser = parser; - } - - @Override - public ICloudApplicationArchiver getArchiver(IProgressMonitor mon) { - final String archivePath = getArchivePath(mon); - if (archivePath!=null) { - return new ICloudApplicationArchiver() { - public File getApplicationArchive(IProgressMonitor monitor) throws Exception { - return getArchive(archivePath); - } - }; - } - return null; - } - - private String getArchivePath(IProgressMonitor mon) { - if (parser.hasManifest()) { - return parser.getApplicationProperty(applicationName, ApplicationManifestHandler.PATH_PROP, mon); - } - return null; - } - - private File getArchive(String archivePath) throws Exception { - Assert.isNotNull(archivePath); - File packagedFile = null; - // Only support paths that point to archive files - IPath path = new Path(archivePath); - if (path.getFileExtension() != null) { - if (path.isAbsolute()) { - // See if it is an absolute path - File absoluteFile = new File(archivePath); - if (absoluteFile.exists() && absoluteFile.canRead()) { - packagedFile = absoluteFile; - } - } else { - // We'll try and resolve the relative starting from the filesystem directory the manifest itself resides in. - File manifestLocation = parser.getManifestFile(); - if (manifestLocation!=null) { - File baseDir = manifestLocation.getParentFile(); - File absoluteFile = new File(baseDir, archivePath).getAbsoluteFile(); - if (absoluteFile.exists() && absoluteFile.canRead()) { - packagedFile = absoluteFile; - } - } - } - } - // If a path is specified but no file found stop further deployment - if (packagedFile == null) { - throw ExceptionUtil.coreException( - "No file found at: " + path + ". Unable to package the application for deployment"); - } else { - return packagedFile; - } - } - -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategyMavenAsWar.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategyMavenAsWar.java deleted file mode 100644 index b6f534d07..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/CloudApplicationArchiverStrategyMavenAsWar.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.packaging; - -import java.io.File; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.springframework.ide.eclipse.boot.core.ISpringBootProject; -import org.springframework.ide.eclipse.boot.core.SpringBootCore; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.util.Log; - -/** - * Package a boot app to deploy it as a 'war'. - * - * @author Kris De Volder - */ -public class CloudApplicationArchiverStrategyMavenAsWar implements CloudApplicationArchiverStrategy { - - private SpringBootCore springBootCore = SpringBootCore.getDefault(); - private IProject project; -// private UserInteractions ui; - - public CloudApplicationArchiverStrategyMavenAsWar(IProject project, UserInteractions ui) { - this.project = project; -// this.ui = ui; - } - - @Override - public ICloudApplicationArchiver getArchiver(IProgressMonitor mon) { - try { - ISpringBootProject bootProject = springBootCore.project(project); - if (bootProject!=null && ISpringBootProject.PACKAGING_WAR.equals(bootProject.getPackaging())) { - return new WarArchiver(); - } - } catch (CoreException e) { - Log.log(e); - } - return null; - } - - private class WarArchiver implements ICloudApplicationArchiver { - - @Override - public File getApplicationArchive(IProgressMonitor monitor) throws Exception { - ISpringBootProject bootProject = springBootCore.project(project); - if (bootProject!=null) { - return bootProject.executePackagingScript(monitor); - } - return null; - } - - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/ICloudApplicationArchiver.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/ICloudApplicationArchiver.java deleted file mode 100644 index ab8c7a7ac..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/ICloudApplicationArchiver.java +++ /dev/null @@ -1,21 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.packaging; - -import java.io.File; - -import org.eclipse.core.runtime.IProgressMonitor; - -public interface ICloudApplicationArchiver { - - File getApplicationArchive(IProgressMonitor monitor) throws Exception; - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/JarNameGenerator.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/JarNameGenerator.java deleted file mode 100644 index b7733c466..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/packaging/JarNameGenerator.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.packaging; - -import java.io.File; -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; - -/** - * Responsible for picking the names for dependency jars when packaging a boot app. - *

- * This class could be turned into an interface with multiple implementations - * should we want to support different naming strategies. But for now there's - * just one implementation, so this is a concrete class. - * - * @author Kris De Volder - */ -public class JarNameGenerator { - - private static final String UNKNOWN_DEPENDENCY = "unknown-dependency"; - private static final IResource[] NO_RESOURCES = {}; - private Set used = new HashSet(); - - private final String EXTENSION = ".jar"; - - public String createName(File dep) { - String candidate = getNameCandidate(dep); - return makeUnique(candidate); - } - - private String makeUnique(String candidate) { - if (candidate.toLowerCase().endsWith(EXTENSION)) { - candidate = candidate.substring(0, candidate.length()-EXTENSION.length()); - } - String name = candidate + EXTENSION; - int id = 0; - while (used.contains(name)) { - name = candidate+"-"+(++id) + EXTENSION; - } - used.add(name); - return name; - } - - protected String getNameCandidate(File dep) { - if (isJar(dep)) { - return getNameCandidateForJar(dep); - } else if (dep.isDirectory()) { - return getNameCandidateForDir(dep); - } - //Shouldn't happen, but return something anyway - return UNKNOWN_DEPENDENCY; - } - - private String getNameCandidateForDir(File dep) { - //We'll try to use the name of enclosing workspace project if possible - IProject p = getEnclosingProject(dep); - if (p!=null) { - return p.getName(); - } - return UNKNOWN_DEPENDENCY; - } - - protected IProject getEnclosingProject(File dep) { - IResource best = chooseBest(getResources(dep)); - if (best!=null) { - return best.getProject(); - } - return null; - } - - /** - * If more than one resource matched a dependency we try to find the - * 'best' resource. We do this by looking at the path relative to the workspace - * and pick the one with the shortest path. This way we will pick the resource - * in the most nested project (i.e. when projects are nested a resource - * may exists both in the parent and child projects. We are interested in - * the child in this case. - */ - protected IResource chooseBest(IResource[] resources) { - int bestLen = Integer.MAX_VALUE; - IResource best = null; - for (IResource r : resources) { - int len = r.getFullPath().segmentCount(); - if (len < bestLen) { - best = r; - bestLen = len; - } - } - return best; - } - - protected IResource[] getResources(File dep) { - if (dep.isDirectory()) { - return getWorkspaceRoot().findContainersForLocationURI(dep.toURI()); - } else if (dep.isFile()) { - return getWorkspaceRoot().findFilesForLocationURI(dep.toURI()); - } - return NO_RESOURCES; - } - - protected IWorkspaceRoot getWorkspaceRoot() { - return ResourcesPlugin.getWorkspace().getRoot(); - } - - protected String getNameCandidateForJar(File dep) { - return dep.getName(); - } - - protected boolean isJar(File dep) { - String name = dep.getName(); - return name.endsWith(".jar") || name.endsWith(".JAR"); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/ParsedUri.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/ParsedUri.java deleted file mode 100644 index 6e63c4daa..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/ParsedUri.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Spring IDE Developers - * 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: - * Spring IDE Developers - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.routes; - -/** - * Represents the result of 'parsing; a route uri by a 'dumb' parser. - *

- * Dumb parser is unaware of dynamic infos about existing domains and so it - * doesn't have the ability to split host and domain name apart as the uri - * syntax alone is not sufficient to determine where the host-name ends and - * the domain name begins. - * - * @author Kris De Volder - */ -public class ParsedUri { - - private String hostAndDomain; // These aren't split apart by the parser, because a dumb parser can't know where to split - private String path; - private Integer port; - - public ParsedUri(String uri) { - //Format: ${hostAndDomain}:${port}/${path} (where the slash is considered a part of the path) - int slash = uri.indexOf('/'); - if (slash>=0) { - path = uri.substring(slash); - uri = uri.substring(0, slash); - } - int colon = uri.indexOf(':'); - if (colon>=0) { - port = Integer.parseInt(uri.substring(colon+1)); - uri = uri.substring(0, colon); - } - hostAndDomain = uri; - } - - @Override - public String toString() { - return "ParsedUri [hostAndDomain=" + hostAndDomain + ", path=" + path + ", port=" + port + "]"; - } - - public String getHostAndDomain() { - return hostAndDomain; - } - - public String getPath() { - return path; - } - - public Integer getPort() { - return port; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/Randomized.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/Randomized.java deleted file mode 100644 index ad3633289..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/Randomized.java +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Spring IDE Developers - * 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: - * Spring IDE Developers - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.routes; - -import org.eclipse.core.runtime.Assert; - -/** - * Represents an intention to set a value to either: - *

    - *
  • a specific value, or - *
  • a randomly chosen value. - *
- */ -public class Randomized { - - private final T fixedValue; - - private Randomized(T v) { - this.fixedValue = v; - } - - public boolean isRandom() { - return this.fixedValue==null; - } - - public T getValue() { - Assert.isNotNull(this.fixedValue); - return this.fixedValue; - } - - public static Randomized value(T value) { - Assert.isNotNull(value); - return new Randomized<>(value); - } - - public static Randomized random() { - return new Randomized<>(null); - } - - @Override - public String toString() { - if (isRandom()) { - return "?"; - } else { - return getValue().toString(); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fixedValue == null) ? 0 : fixedValue.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; - Randomized other = (Randomized) obj; - if (fixedValue == null) { - if (other.fixedValue != null) - return false; - } else if (!fixedValue.equals(other.fixedValue)) - return false; - return true; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/RouteAttributes.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/RouteAttributes.java deleted file mode 100644 index bded05338..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/RouteAttributes.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Spring IDE Developers - * 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: - * Spring IDE Developers - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.routes; - -import java.util.List; - -import org.springframework.ide.eclipse.boot.dash.cf.deployment.YamlGraphDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentProperties; - -/** - * Data object containing attributes from a manifest.yml related to route bindings. - * (i.e. any attribute in the manifest.yml file that potentially affects the routes - * that will be bound to an app on push, is included here. - *

- * This is intented to be a 'dumb' data object. It should have no smarts around interpreting the - * meanings of attributes. Its only purpose is to be a container for - * exactly the values as found in the manifest.mf file. - * - * @author Kris De Volder - */ -public class RouteAttributes { - - private final String appName; - private final List routes; - private final String host; - private final List hosts; - private final String domain; - private final List domains; - private final boolean noHost; - private final boolean noRoute; - private final boolean randomRoute; - - public RouteAttributes(YamlGraphDeploymentProperties manifest) { - this.appName = manifest.getAppName(); - this.routes = manifest.getRoutes(); - this.domain = manifest.getRawDomain(); - this.domains = manifest.getRawDomains(); - this.host = manifest.getRawHost(); - this.hosts = manifest.getRawHosts(); - this.noRoute = manifest.getRawNoRoute(); - this.randomRoute = manifest.getRawRandomRoute(); - this.noHost = manifest.getRawNoHost(); - } - - public List getRoutes() { - return routes; - } - public String getHost() { - return host; - } - public List getHosts() { - return hosts; - } - public String getDomain() { - return domain; - } - public List getDomains() { - return domains; - } - public boolean isNoHost() { - return noHost; - } - public boolean isNoRoute() { - return noRoute; - } - public boolean isRandomRoute() { - return randomRoute; - } - public String getAppName() { - return appName; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/RouteBinding.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/RouteBinding.java deleted file mode 100644 index a1d8e6f21..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/RouteBinding.java +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Spring IDE Developers - * 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: - * Spring IDE Developers - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.routes; - -public class RouteBinding { - - private Randomized host; - private String domain; - private Randomized port; - private String path; - - public Randomized getHost() { - return host; - } - - public void setHost(String host) { - setHost(host==null ? null : Randomized.value(host)); - } - public void setHost(Randomized host) { - this.host = host; - } - - public Randomized getPort() { - return port; - } - public void setPort(Randomized port) { - this.port = port; - } - public void setPort(Integer port) { - setPort(port == null ? null : Randomized.value(port)); - } - public String getDomain() { - return domain; - } - public void setDomain(String domain) { - this.domain = domain; - } - - public String getPath() { - return path; - } - - /** - * This toString returns something that is not quite a uri. The '.' separating host from - * domain is replaced by '@'. This is so we can actually see where the host ends and the - * domain name starts (which you can't in a uri, since host and domains may both contain - * dots. - */ - @Override - public String toString() { - StringBuilder s = new StringBuilder(); - if (host!=null) { - s.append(getHost()); - s.append('@'); - } - s.append(getDomain()); - if (port!=null) { - s.append(':'); - s.append(getPort()); - } - if (path!=null) { - s.append(getPath()); - } - return s.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((domain == null) ? 0 : domain.hashCode()); - result = prime * result + ((host == null) ? 0 : host.hashCode()); - result = prime * result + ((port == null) ? 0 : port.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; - RouteBinding other = (RouteBinding) obj; - if (domain == null) { - if (other.domain != null) - return false; - } else if (!domain.equals(other.domain)) - return false; - if (host == null) { - if (other.host != null) - return false; - } else if (!host.equals(other.host)) - return false; - if (port == null) { - if (other.port != null) - return false; - } else if (!port.equals(other.port)) - return false; - return true; - } - - public String toUri() { - StringBuilder s = new StringBuilder(); - if (host!=null) { - s.append(host); - s.append('.'); - } - s.append(domain); - if (port!=null) { - s.append(':'); - s.append(port); - } - if (path!=null) { - if (!path.startsWith("/")) { - s.append('/'); - } - s.append(path); - } - return s.toString(); - } - - public void setPath(String path) { - this.path = path; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/RouteBuilder.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/RouteBuilder.java deleted file mode 100644 index 0f57096c2..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/routes/RouteBuilder.java +++ /dev/null @@ -1,241 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Spring IDE Developers - * 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: - * Spring IDE Developers - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.routes; - -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFDomainStatus; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableList.Builder; -import com.google.common.collect.ImmutableMap; - -/** - * This class implements the logics of translating from the multitude of attributes in a - * `manifest.mf` like 'random-route', 'no-host', 'domain', 'domains', etc. into concrete - * 'route bindings' that can be passed of to a lower-level cf client operation such as `mapRoute` - * to bind a route to an app. - *

- * This process is somewhat complex because of the multitude of attributes, and their interactions, - * as well as different interpretations of some attributes depending on the target domain being a - * TCP vs HTTP domain. - * - * @author Kris De Volder - */ -public class RouteBuilder { - - private Map domainsByName = new LinkedHashMap<>(); - private String defaultDomain; - - public RouteBuilder(Collection domains) { - ImmutableMap.Builder builder = ImmutableMap.builder(); - for (CFCloudDomain d : domains) { - builder.put(d.getName(), d); - } - domainsByName = builder.build(); - } - - /** - * Builds the list of route bindings from a parsed manifest.yml's attributes. - *

- * The routes builder makes implicit assumptions that the manifest doesn't have - * conflicting attributes (e.g. `host` and `random-route`). - *

- * If conflicting attributes *are* present then the routes builder will ignore - * some of the conflicting attributes in a somewhat arbitrary way. So it will still - * compute a list of route bindings rather than raise an exception. - *

- * A similar approach is taken for 'routes' definitions that can't be mapped onto - * the list of known domains in a valid way. These routes will simply be silently - * ignored. - */ - public List buildRoutes(RouteAttributes manifest) { - if (manifest.isNoRoute()) { - return ImmutableList.of(); - } - if (manifest.isRandomRoute()) { - return buildRandomRoutes(manifest); - } - if (manifest.getRoutes()!=null) { - return buildRoutesFromUris(manifest); - } - return buildRoutesFromHostsAndDomains(manifest); - } - - private List buildRoutesFromHostsAndDomains(RouteAttributes manifest) { - if (manifest.isNoHost()) { - List domains = getDomains(manifest); - ImmutableList.Builder routes = ImmutableList.builder(); - for (String domain : domains) { - RouteBinding route = new RouteBinding(); - route.setDomain(domain); - routes.add(route); - } - return routes.build(); - } else { - List hosts = getHosts(manifest); - List domains = getDomains(manifest); - ImmutableList.Builder routes = ImmutableList.builder(); - for (String host : hosts) { - for (String domain : domains) { - RouteBinding route = new RouteBinding(); - route.setHost(host); - route.setDomain(domain); - routes.add(route); - } - } - return routes.build(); - } - } - - protected List buildRoutesFromUris(RouteAttributes manifest) { - Builder builder = ImmutableList.builder(); - for (String desiredUri : manifest.getRoutes()) { - RouteBinding route = buildRouteFromUri(desiredUri, manifest); - if (route!=null) { - builder.add(route); - } - } - return builder.build(); - } - - protected List buildRandomRoutes(RouteAttributes manifest) { - Builder builder = ImmutableList.builder(); - List domains = getDomains(manifest); - for (String domain : domains) { - RouteBinding route = new RouteBinding(); - route.setDomain(domain); - if (isTcpDomain(domain)) { - route.setPort(Randomized.random()); - } else { - route.setHost(Randomized.random()); - } - builder.add(route); - } - return builder.build(); - } - - private boolean isTcpDomain(String domainName) { - CFCloudDomain d = domainsByName.get(domainName); - if (d!=null) { - return d.getType()==CFDomainType.TCP; - } - return false; - } - - private List getHosts(RouteAttributes manifest) { - Set builder = new LinkedHashSet<>(); - String host = manifest.getHost(); - if (host!=null) { - builder.add(host); - } - List hosts = manifest.getHosts(); - if (hosts!=null) { - builder.addAll(hosts); - } - if (builder.isEmpty()) { - String appName = manifest.getAppName(); - if (appName!=null) { - builder.add(appName); - } - } - return ImmutableList.copyOf(builder); - } - - private List getDomains(RouteAttributes manifest) { - Set domains = new LinkedHashSet<>(); - List ds = manifest.getDomains(); - if (ds!=null) { - domains.addAll(ds); - } - String d = manifest.getDomain(); - if (d!=null) { - domains.add(d); - } - if (domains.isEmpty()) { - //This assumes 'getDomains' is only called in context where we actually - // want the domains from the 'domain' or 'domains' attributes. So, not - // for example, in a manifest with a 'routes' or a 'no-routes'. - //In these contexts, of the list of domains is empty, we generally want - // to fallback to using the defaultDomain. - String dflt = getDefaultDomain(); - if (dflt!=null) { - domains.add(dflt); - } - } - return ImmutableList.copyOf(domains); - } - - /** - * Create a RouteBinding from a 'target' uri. Such a routebinding is always specific - * and doesn't contain randomized components (i.e. no random host/port). - */ - private RouteBinding buildRouteFromUri(String _uri, RouteAttributes args) { - ParsedUri uri = new ParsedUri(_uri); - CFCloudDomain bestDomain = domainsByName.values().stream() - .filter(domain -> matches(domain, uri)) - .max((d1, d2) -> Integer.compare(d1.getName().length(), d2.getName().length())) - .orElse(null); - if (bestDomain!=null) { - RouteBinding route = new RouteBinding(); - route.setDomain(bestDomain.getName()); - route.setHost(bestDomain.splitHost(uri.getHostAndDomain())); - route.setPath(uri.getPath()); - route.setPort(uri.getPort()); - return route; - } - return null; - } - - public String getDefaultDomain() { - if (defaultDomain==null) { - defaultDomain = getDomains().stream() - .filter(d -> d.getStatus()==CFDomainStatus.SHARED && d.getType()==CFDomainType.HTTP) - .findFirst() - .map(d -> d.getName()) - .orElse(null); - } - return defaultDomain; - } - - private Collection getDomains() { - return domainsByName.values(); - } - - /** - * Determines whether a given domain can be used to construct a route for a given - * target uri. This check is strictly based on the names of the domain and target uri, - * type of the domain/uri doesn't play into it (so, for example there are no 'smarts' here - * to detect whether or not a domain's type is compatible with the uri type). - */ - private boolean matches(CFCloudDomain domainData, ParsedUri uri) { - String domain = domainData.getName(); - String hostAndDomain = uri.getHostAndDomain(); - if (!hostAndDomain.endsWith(domain)) { - return false; - } - if (domain.length()==hostAndDomain.length()) { - //The uri matches domain precisely - return true; - } else if (hostAndDomain.charAt(hostAndDomain.length()-domain.length()-1)=='.') { - //The uri matches as ${host}.${domain} - return true; - } - return false; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CfTargetsInfo.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CfTargetsInfo.java deleted file mode 100644 index 66e20b5da..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CfTargetsInfo.java +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 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.cf.runtarget; - -import java.util.List; - -/** - * JSON-friendly representation of Cloud Foundry targets, used for integrations that need - * to serialise CF target information for transmission (e.g. between a client and server) - *

- * WARNING: As this is used to serialise and deserialise between client and server, this exact type is used on both client and server. - * Therefore this type should always match the one in the language server. For example, see the identical copy of this class in: - * org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CfTargetsInfo - * - */ -public class CfTargetsInfo { - - private List cfTargets; - private TargetDiagnosticMessages diagnosticMessages; - - public List getCfTargets() { - return cfTargets; - } - - public void setCfTargets(List cfTargets) { - this.cfTargets = cfTargets; - } - - public TargetDiagnosticMessages getDiagnosticMessages() { - return diagnosticMessages; - } - - public void setDiagnosticMessages(TargetDiagnosticMessages diagnosticMessages) { - this.diagnosticMessages = diagnosticMessages; - } - - public static class TargetDiagnosticMessages { - - - private String noTargetsFound; - private String connectionError; - private String noOrgSpace; - private String targetSource; - - /** - * - * @return only when there are no targets available (e.g. cf CLI is not connected or no boot dash targets) - */ - public String getNoTargetsFound() { - return noTargetsFound; - } - - public void setNoTargetsFound(String noTargetsFound) { - this.noTargetsFound = noTargetsFound; - } - - /** - * - * @return error if any existing target cannot connect. - */ - public String getConnectionError() { - return connectionError; - } - - public void setConnectionError(String connectionError) { - this.connectionError = connectionError; - } - - public String getNoOrgSpace() { - return noOrgSpace; - } - - public void setNoOrgSpace(String noOrgSpace) { - this.noOrgSpace = noOrgSpace; - } - - public String getTargetSource() { - return targetSource; - } - - public void setTargetSource(String targetSource) { - this.targetSource = targetSource; - } - } - - public static class Target { - private String api; - private String org; - private String space; - - private boolean sslDisabled; - private String refreshToken; - - public String getApi() { - return api; - } - - public void setApi(String api) { - this.api = api; - } - - public String getOrg() { - return org; - } - - public void setOrg(String org) { - this.org = org; - } - - public void setSpace(String space) { - this.space = space; - } - - public String getSpace() { - return space; - } - - public boolean getSslDisabled() { - return sslDisabled; - } - - public void setSslDisabled(boolean sslDisabled) { - this.sslDisabled = sslDisabled; - } - - public String getRefreshToken() { - return refreshToken; - } - - public void setRefreshToken(String refreshToken) { - this.refreshToken = refreshToken; - } - - @Override - public String toString() { - return "Target [api=" + api + ", org=" + org + ", space=" + space + "]"; - } - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CloudFoundryRunTarget.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CloudFoundryRunTarget.java deleted file mode 100644 index 29bf54a89..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CloudFoundryRunTarget.java +++ /dev/null @@ -1,454 +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.cf.runtarget; - -import static org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.BootDashCfColumns.JMX_SSH_TUNNEL; -import static org.springframework.ide.eclipse.boot.dash.model.RunState.DEBUGGING; -import static org.springframework.ide.eclipse.boot.dash.model.RunState.INACTIVE; -import static org.springframework.ide.eclipse.boot.dash.model.RunState.RUNNING; -import static org.springframework.ide.eclipse.boot.dash.model.RunState.STARTING; -import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.DEFAULT_PATH; -import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.INSTANCES; -import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.NAME; -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 java.util.Arrays; -import java.util.Collection; -import java.util.EnumSet; -import java.util.List; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.JavaCore; -import org.osgi.framework.Version; -import org.springframework.ide.eclipse.boot.dash.api.App; -import org.springframework.ide.eclipse.boot.dash.api.DebuggableTarget; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFBuildpack; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFStack; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.CloudFoundryClientFactory; -import org.springframework.ide.eclipse.boot.dash.cf.client.SshClientSupport; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.PasswordDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.StoreCredentialsMode; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.ui.CfUserInteractions; -import org.springframework.ide.eclipse.boot.dash.model.AbstractBootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.AbstractRunTarget; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -import org.springframework.ide.eclipse.boot.dash.model.RunState; -import org.springframework.ide.eclipse.boot.dash.model.RunTargetWithProperties; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.CannotAccessPropertyException; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.RemoteRunTarget; -import org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn; -import org.springsource.ide.eclipse.commons.core.pstore.PropertyStoreApi; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.util.Log; -import org.springsource.ide.eclipse.commons.livexp.util.OldValueDisposer; -import org.springsource.ide.eclipse.commons.ui.UiUtil; - -import com.google.common.collect.ImmutableSet; - -public class CloudFoundryRunTarget extends AbstractRunTarget -implements RunTargetWithProperties, RemoteRunTarget, DebuggableTarget { - - private CloudFoundryTargetProperties targetProperties; - - // Cache these to avoid frequent client calls - private List domains; - private List spaces; - private List stacks; - - private OldValueDisposer cachedClientDisposer; - private CloudFoundryClientFactory clientFactory; - - public CloudFoundryRunTarget(CloudFoundryTargetProperties targetProperties, CloudFoundryRunTargetType runTargetType, CloudFoundryClientFactory clientFactory) { - super(runTargetType, CloudFoundryTargetProperties.getId(targetProperties), - CloudFoundryTargetProperties.getName(targetProperties)); - this.targetProperties = targetProperties; - this.clientFactory = clientFactory; - this.cachedClientDisposer = new OldValueDisposer<>(this); - cachedClient().onChange((_e, v) -> { - try { - if (getClient() != null) { - persistBuildpacks(getClient().getBuildpacks()); - } - } catch (Exception e) { - Log.log(e); - } - }); - } - - private LiveVariable cachedClient() { - return cachedClientDisposer.getVar(); - } - - public static final EnumSet RUN_GOAL_STATES = EnumSet.of(INACTIVE, STARTING, RUNNING, DEBUGGING); - private static final BootDashColumn[] DEFAULT_COLUMNS = { RUN_STATE_ICN, NAME, PROJECT, INSTANCES, DEFAULT_PATH, TAGS, JMX_SSH_TUNNEL }; - - private static final String APPS_MANAGER_HOST = "APPS_MANAGER_HOST"; - private static final String BUILDPACKS = "BUILDPACKS"; - - @Override - public ClientRequests getClient() { - return cachedClient().getValue(); - } - - @Override - public void connect(ConnectMode mode) throws Exception { - try { - this.domains = null; - this.spaces = null; - this.stacks = null; - boolean createClient = getTargetProperties().getCredentials()!=null; - if (mode==ConnectMode.INTERACTIVE && getTargetProperties().getCredentials()==null) { - updatePasswordAndConnect(); - } - if (createClient) { - cachedClient().setValue(createClient()); - } - } catch (Exception e) { - cachedClient().setValue(null); - throw e; - } - } - - private CfUserInteractions cfUi() { - return getType().injections().getBean(CfUserInteractions.class); - } - - private UserInteractions ui() { - return getType().injections().getBean(UserInteractions.class); - } - - public boolean updatePasswordAndConnect() throws Exception { - final StoreCredentialsMode storePassword = this.getTargetProperties().getStoreCredentials(); - PasswordDialogModel passwordDialogModel = new PasswordDialogModel(this.getClientFactory(), this.getTargetProperties(), storePassword); - cfUi().openPasswordDialog(passwordDialogModel); - if (passwordDialogModel.isOk()) { - this.getTargetProperties().setStoreCredentials( - passwordDialogModel.getEffectiveStoreMode()); - CFCredentials credentials = passwordDialogModel.getCredentials(); - // The credentials cannot be null or empty string - enforced by the dialog - try { - this.getTargetProperties().setCredentials(credentials); - cachedClient().setValue(createClient()); - } catch (CannotAccessPropertyException e) { - ui().warningPopup("Failed Storing Password", - "Failed to store password in Secure Storage for " + this.getId() - + ". Secure Storage is most likely locked. Current password will be kept until disconnect."); - // Set "remember password" to false. Password hasn't been stored. - this.getTargetProperties().setStoreCredentials(StoreCredentialsMode.STORE_NOTHING); - } - return true; - } - return false; - } - - @Override - public void disconnect() { - this.domains = null; - this.spaces = null; - this.stacks = null; - cachedClient().setValue(null); - } - @Override - public void dispose() { - disconnect(); - super.dispose(); - } - - protected void persistBuildpacks(List buildpacks) throws Exception { - PropertyStoreApi properties = getPersistentProperties(); - - if (properties != null) { - - String[] buildpackVals = null; - if (buildpacks != null && !buildpacks.isEmpty()) { - buildpackVals = new String[buildpacks.size()]; - for (int i = 0; i < buildpacks.size(); i++) { - buildpackVals[i] = buildpacks.get(i).getName(); - } - } - - properties.put(BUILDPACKS, buildpackVals); - } - } - - @Override - public boolean isConnected() { - return cachedClient().getValue() != null; - } - - public Version getCCApiVersion() { - try { - ClientRequests client = getClient(); - if (client!=null) { - return client.getApiVersion(); - } - } catch (Exception e) { - Log.log(e); - } - return null; - } - - public CloudFoundryClientFactory getClientFactory() { - return clientFactory; - } - - protected ClientRequests createClient() throws Exception { - return clientFactory.getClient(this.getTargetProperties()); - } - - @Override - public BootDashColumn[] getDefaultColumns() { - return DEFAULT_COLUMNS; - } - - @Override - public AbstractBootDashModel createSectionModel(BootDashViewModel parent) { - return new CloudFoundryBootDashModel(this, parent.getContext(), parent); - } - - @Override - public CloudFoundryTargetProperties getTargetProperties() { - return targetProperties; - } - - @Override - public boolean canRemove() { - return true; - } - - @Override - public boolean canDeployAppsFrom() { - return false; - } - - @Override - public boolean requiresCredentials() { - return true; - } - - public synchronized List getDomains( IProgressMonitor monitor) - throws Exception { - if (domains == null) { - SubMonitor subMonitor = SubMonitor.convert(monitor, 10); - subMonitor.beginTask("Refreshing list of domains for " + getName(), 5); - - domains = getClient().getDomains(); - - subMonitor.worked(5); - } - return domains; - } - - public synchronized List getStacks(IProgressMonitor monitor) - throws Exception { - if (stacks == null) { - SubMonitor subMonitor = SubMonitor.convert(monitor, 10); - subMonitor.beginTask("Refreshing list of stacks for " + getName(), 5); - - stacks = getClient().getStacks(); - - subMonitor.worked(5); - } - return stacks; - } - - public synchronized List getSpaces(ClientRequests requests, IProgressMonitor monitor) throws Exception { - if (spaces == null) { - SubMonitor subMonitor = SubMonitor.convert(monitor, 10); - - subMonitor.beginTask("Refreshing list of spaces for " + getName(), 5); - spaces = requests.getSpaces(); - subMonitor.worked(5); - } - return spaces; - } - - public String getUrl() { - String url = targetProperties.getUrl(); - while (url.endsWith("/")) { - url = url.substring(0, url.length()-1); - } - return url; - } - - public SshClientSupport getSshClientSupport() throws Exception { - ClientRequests client = getClient(); - return client.getSshClientSupport(); - } - - /** - * Returns list of cached buildpacks. It does NOT fetch updated buildpacks from CF as this method may - * be called in cases where fast list of buildpacks is required (e.g values that show in pop-up UI). - *

- * Do NOT use this method to fetch buildpacks from CF - * @return Collection of CACHED buildpacks, or null if none cached yet. - * @throws Exception - */ - public Collection getBuildpackValues() throws Exception { - PropertyStoreApi properties = getPersistentProperties(); - if (properties != null) { - String[] buildPackVals = properties.get(BUILDPACKS, (String[]) null); - if (buildPackVals != null) { - return Arrays.asList(buildPackVals); - } - } - return null; - } - - public String getBuildpack(IProject project) { - // Only support Java project for now - IJavaProject javaProject = JavaCore.create(project); - - if (javaProject != null) { - try { - - - Collection buildpacks = getBuildpackValues(); - if (buildpacks != null) { - String javaBuildpack = null; - // Only chose a java build iff ONE java buildpack exists - // that contains the java_buildpack pattern. - - for (String bp : buildpacks) { - // iterate through all buildpacks to make sure only - // ONE java buildpack exists - if (bp.contains("java_buildpack")) { - if (javaBuildpack == null) { - javaBuildpack = bp; - } else { - // If more than two buildpacks contain - // "java_buildpack", do not chose any. Let CF buildpack - // detection decided which one to chose. - javaBuildpack = null; - break; - } - } - } - return javaBuildpack; - } - } catch (Exception e) { - Log.log(e); - } - } - - return null; - } - - @Override - public String getTemplateVar(char name) { - switch (name) { - case 'o': - return getTargetProperties().getOrganizationName(); - case 's': - return getTargetProperties().getSpaceName(); - case 'a': - return getTargetProperties().getUrl(); - case 'u': - return getTargetProperties().getUsername(); - default: - return super.getTemplateVar(name); - } - } - - public String getAppsManagerHost() { - PropertyStoreApi props = getPersistentProperties(); - if (props != null) { - String appsManagerURL = props.get(APPS_MANAGER_HOST); - if (appsManagerURL != null) { - return appsManagerURL; - } - } - return getAppsManagerHostDefault(); - } - - public void setAppsManagerHost(String appsManagerURL) throws Exception { - getPersistentProperties().put(APPS_MANAGER_HOST, appsManagerURL); - } - - public String getAppsManagerURL() { - String host = getAppsManagerHost(); - CloudFoundryTargetProperties targetProperties = getTargetProperties(); - - String org = targetProperties.getOrganizationGuid(); - String space = targetProperties.getSpaceGuid(); - - if (host != null && host.length() > 0 && org != null && org.length() > 0 && space != null && space.length() > 0) { - return host + "/organizations/" + org + "/spaces/" + space; - } else { - return null; - } - } - - public String getAppsManagerHostDefault() { - String url = getUrl(); - if (url != null && url.contains("//api.")) { - return url.replace("//api.", "//console."); - } - else { - return null; - } - } - - @Override - public LiveExpression getClientExp() { - return cachedClient(); - } - - @Override - public void performDoubleClickAction(UserInteractions ui) { - openCloudAdminConsole(ui); - } - - public void openCloudAdminConsole(UserInteractions ui) { - String appsManagerURL = getAppsManagerURL(); - if (appsManagerURL != null && appsManagerURL.length() > 0) { - UiUtil.openUrl(appsManagerURL); - } - else { - ui.errorPopup("can't find unique identificators", - "The Cloud Target that you selected doesn't contain required information about the organization and the space yet (recently added unique identifiers). Please remove the target and add it again to fix this."); - } - } - - @Override - public CloudFoundryTargetProperties getParams() { - return this.targetProperties; - } - - @Override - public Collection fetchApps() { - //TODO: migrate CF to use GenericRemoteBootDashModel. And then this should be implement based on - // how CFBootDashModel fetches apps. - return ImmutableSet.of(); - } - - @Override - public CloudFoundryRunTargetType getType() { - return (CloudFoundryRunTargetType) super.getType(); - } - - @Override - public boolean isDebuggingSupported() { - return true; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CloudFoundryRunTargetType.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CloudFoundryRunTargetType.java deleted file mode 100644 index 56dad4668..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CloudFoundryRunTargetType.java +++ /dev/null @@ -1,194 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.runtarget; - -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.swt.widgets.Shell; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.client.CloudFoundryClientFactory; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshTunnelFactory; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.CloudFoundryTargetWizardModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.RunTargetWizard; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.JmxSshTunnelManager; -import org.springframework.ide.eclipse.boot.dash.devtools.DevtoolsUtil; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -import org.springframework.ide.eclipse.boot.dash.model.DefaultWizardModelUserInteractions; -import org.springframework.ide.eclipse.boot.dash.model.MissingLiveInfoMessages; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.model.WizardModelUserInteractions; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.AbstractRemoteRunTargetType; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.TargetProperties; -import org.springframework.ide.eclipse.boot.dash.util.UiUtil; -import org.springframework.ide.eclipse.boot.util.ProcessTracker; -import org.springframework.ide.eclipse.editor.support.util.HtmlSnippet; -import org.springsource.ide.eclipse.commons.livexp.core.LiveSetVariable; -import org.springsource.ide.eclipse.commons.livexp.ui.Disposable; -import org.springsource.ide.eclipse.commons.livexp.util.Log; - -import com.google.gson.Gson; - -/** - * @author Kris De Volder - */ -public class CloudFoundryRunTargetType extends AbstractRemoteRunTargetType implements Disposable { - - private static final ImageDescriptor SMALL_ICON = BootDashActivator.getImageDescriptor("icons/cloud_obj.png"); - - private WizardModelUserInteractions interactions; - - public CloudFoundryRunTargetType(SimpleDIContext injections) { - super(injections, "Cloud Foundry"); - injections.assertDefinitionFor(SshTunnelFactory.class); - injections.assertDefinitionFor(JmxSshTunnelManager.class); - - //TODO: Should be injected and merged with other user interactions, but required too much - // refactoring to implement in limited time - this.interactions = new DefaultWizardModelUserInteractions(); - } - - @Override - public CompletableFuture openTargetCreationUi(LiveSetVariable targets) { - try { - CloudFoundryTargetWizardModel model = new CloudFoundryTargetWizardModel(this, clientFactory(), - targets.getValues(), context(), interactions); - RunTargetWizard wizard = new RunTargetWizard(model); - Shell shell = UiUtil.getShell(); - if (shell != null) { - WizardDialog dialog = new WizardDialog(shell, wizard); - if (dialog.open() == Dialog.OK) { - CloudFoundryRunTarget target = wizard.getRunTarget(); - if (target != null) { - targets.add(target); - } - } - } - return CompletableFuture.completedFuture(null); - } catch (Exception e) { - Log.log(e); - CompletableFuture f = new CompletableFuture(); - f.completeExceptionally(e); - return f; - } - } - - - - private CloudFoundryClientFactory clientFactory() { - return injections.getBean(CloudFoundryClientFactory.class); - } - - private BootDashModelContext context() { - return injections.getBean(BootDashModelContext.class); - } - - @Override - public RunTarget createRunTarget(CloudFoundryTargetProperties props) { - return new CloudFoundryRunTarget((CloudFoundryTargetProperties) props, this, clientFactory()); - } - - @Override - public ImageDescriptor getIcon() { - return BootDashActivator.getImageDescriptor("icons/cloud-ready.png"); - } - @Override - public ImageDescriptor getDisconnectedIcon() { - return BootDashActivator.getImageDescriptor("icons/cloud-inactive.png"); - } - - @Override - public String getDefaultNameTemplate() { - return "%o : %s - [%a]"; - } - - @Override - public String getTemplateHelpText() { - return - "Enter a template pattern. The following variable substitution are defined:\n" + - " '%u': username\n" + - " '%o': organization\n" + - " '%s': space\n" + - " '%a': API URL\n" + - "\n" + - "To escape a variable name simply repeat the '%' sign. E.g. '%%u'"; - } - - @Override - public CloudFoundryTargetProperties parseParams(String serializedTargetParams) { - Gson gson = new Gson(); - @SuppressWarnings("unchecked") - Map map = gson.fromJson(serializedTargetParams, Map.class); - return new CloudFoundryTargetProperties(new TargetProperties(map, this), this, injections); - } - - @Override - public String serialize(CloudFoundryTargetProperties props) { - return props.toJson(); - } - - @Override - public UserInteractions ui() { - // TODO Auto-generated method stub - return null; - } - - @Override - public MissingLiveInfoMessages getMissingLiveInfoMessages() { - return new MissingLiveInfoMessages() { - @Override - public HtmlSnippet getMissingInfoMessage(String appName, String actuatorEndpoint) { - - return buffer -> { - buffer.raw("

"); - buffer.raw(""); - buffer.text(appName); - buffer.raw(""); - buffer.text(" must be running with JMX and actuator endpoint enabled:"); - buffer.raw("

"); - - buffer.raw("
    "); - - buffer.raw("
  1. "); - buffer.text("Enable actuator "); - buffer.raw(""); - buffer.text(actuatorEndpoint); - buffer.raw(""); - buffer.text(" endpoint in the application."); - buffer.raw("
  2. "); - - buffer.raw("
  3. "); - buffer.text("Select "); - buffer.raw(""); - buffer.text("Enable JMX SSH Tunnel"); - buffer.raw(""); - buffer.text(" in the deployment dialog."); - buffer.raw("
  4. "); - buffer.raw("
"); - - buffer.href(EXTERNAL_DOCUMENT_LINK, "See documentation"); - }; - - } - }; - } - - @Override - public void dispose() { - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CloudFoundryTargetProperties.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CloudFoundryTargetProperties.java deleted file mode 100644 index de0bb1674..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/runtarget/CloudFoundryTargetProperties.java +++ /dev/null @@ -1,173 +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.cf.runtarget; - -import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.StoreCredentialsMode; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.CannotAccessPropertyException; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.TargetProperties; - -import com.google.gson.Gson; - -public class CloudFoundryTargetProperties extends TargetProperties { - - public final static String ORG_PROP = "organization"; - public final static String SPACE_PROP = "space"; - public final static String SELF_SIGNED_PROP = "selfsigned"; - public final static String SKIP_SSL_VALIDATION_PROP = "skipSslValidation"; - - public final static String ORG_GUID = "organization_guid"; - public final static String SPACE_GUID = "space_guid"; - - public static final String USERNAME_PROP = "username"; - public static final String URL_PROP = "url"; - private static final String STORE_CREDENTIALS = "storeCredentials"; - - private CFCredentials credentials; - - final private SimpleDIContext injections; - - public CFCredentials getCredentials() throws CannotAccessPropertyException { - if (credentials == null) { - StoreCredentialsMode storeMode = getStoreCredentials(); - try { - credentials = storeMode.loadCredentials(context(), type, getRunTargetId()); - } catch (Exception e) { - throw new CannotAccessPropertyException("Cannot read password.", e); - } - } - return credentials; - } - - public void setCredentials(CFCredentials credentials) throws CannotAccessPropertyException { - this.credentials = credentials; - StoreCredentialsMode storeMode = getStoreCredentials(); - storeMode.saveCredentials(context(), type, getRunTargetId(), credentials); - } - - private BootDashModelContext context() { - return injections.getBean(BootDashModelContext.class); - } - - public CloudFoundryTargetProperties(TargetProperties copyFrom, RunTargetType runTargetType, SimpleDIContext injections) { - super(copyFrom, runTargetType); - this.injections = injections; - if (get(RUN_TARGET_ID) == null) { - put(RUN_TARGET_ID, getId(this)); - } - } - - public String getSpaceName() { - return map.get(SPACE_PROP); - } - - public String getOrganizationName() { - return map.get(ORG_PROP); - } - - public String getSpaceGuid() { - return map.get(SPACE_GUID); - } - - public String getOrganizationGuid() { - return map.get(ORG_GUID); - } - - public boolean isSelfsigned() { - return map.get(SELF_SIGNED_PROP) != null && Boolean.parseBoolean(map.get(SELF_SIGNED_PROP)); - } - - public boolean skipSslValidation() { - return map.get(SKIP_SSL_VALIDATION_PROP) != null && Boolean.parseBoolean(map.get(SKIP_SSL_VALIDATION_PROP)); - } - - public static String getId(CloudFoundryTargetProperties cloudProps) { - return getId(cloudProps.getUsername(), cloudProps.getUrl(), cloudProps.getOrganizationName(), - cloudProps.getSpaceName()); - } - - public static String getName(CloudFoundryTargetProperties cloudProps) { - return cloudProps.getOrganizationName() + " : " + cloudProps.getSpaceName() + " - [" + cloudProps.getUrl() - + "]"; - } - - public static String getId(CFClientParams params) { - return getId(params.getUsername(), params.getApiUrl(), params.getOrgName(), params.getSpaceName()); - } - - public static String getId(String userName, String url, String orgName, String spaceName) { - return userName + " : " + url + " : " + orgName + " : " + spaceName; - } - - public boolean isStoreCredentials() { - return getStoreCredentials()!=StoreCredentialsMode.STORE_NOTHING; - } - - public void setSpace(CFSpace space) { - if (space != null) { - put(ORG_PROP, space.getOrganization().getName()); - put(ORG_GUID, space.getOrganization().getGuid().toString()); - put(SPACE_PROP, space.getName()); - put(SPACE_GUID, space.getGuid().toString()); - } else { - put(ORG_PROP, null); - put(ORG_GUID, null); - put(SPACE_PROP, null); - put(SPACE_GUID, null); - } - } - - public void setUrl(String value) { - put(URL_PROP, value); - } - - public void setSelfSigned(boolean value) { - put(SELF_SIGNED_PROP, Boolean.toString(value)); - } - - public void setSkipSslValidation(boolean value) { - put(SKIP_SSL_VALIDATION_PROP, Boolean.toString(value)); - } - - public String getUsername() { - return map.get(USERNAME_PROP); - } - public void setUserName(String value) { - put(USERNAME_PROP, value); - } - - public StoreCredentialsMode getStoreCredentials() { - String s = map.get(STORE_CREDENTIALS); - if (s!=null) { - return StoreCredentialsMode.valueOf(s); - } else { - return StoreCredentialsMode.STORE_NOTHING; - } - } - - public void setStoreCredentials(StoreCredentialsMode store) { - map.put(STORE_CREDENTIALS, String.valueOf(store)); - } - - public String getUrl() { - return map.get(URL_PROP); - } - - public String toJson() { - Gson gson = new Gson(); - return gson.toJson(map); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ui/CfUserInteractions.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ui/CfUserInteractions.java deleted file mode 100644 index 5b75ec64b..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ui/CfUserInteractions.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019 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.cf.ui; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.OperationCanceledException; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudData; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.CustomizeAppsManagerURLDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.PasswordDialogModel; -import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel; - -public interface CfUserInteractions { - void openPasswordDialog(PasswordDialogModel model); - void openEditAppsManagerURLDialog(CustomizeAppsManagerURLDialogModel model); - - /** - * Brings up the UI to enter application deployment manifest - */ - CloudApplicationDeploymentProperties promptApplicationDeploymentProperties(DeploymentPropertiesDialogModel model) throws Exception; - - ManifestDiffDialogModel.Result confirmReplaceApp(String title, CloudData cloudData, IFile manifestFile, CloudApplicationDeploymentProperties deploymentProperties) - throws OperationCanceledException, Exception; - - ManifestDiffDialogModel.Result openManifestDiffDialog(ManifestDiffDialogModel model) throws Exception; - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ui/DefaultCfUserInteractions.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ui/DefaultCfUserInteractions.java deleted file mode 100644 index f3d050f3b..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/ui/DefaultCfUserInteractions.java +++ /dev/null @@ -1,217 +0,0 @@ -package org.springframework.ide.eclipse.boot.dash.cf.ui; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.CompareEditorInput; -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.text.edits.MalformedTreeException; -import org.eclipse.text.edits.MultiTextEdit; -import org.eclipse.text.edits.TextEdit; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudData; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.ManifestDiffDialog; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.YamlGraphDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.CustomizeAppsManagerURLDialog; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.CustomizeAppsManagerURLDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialog; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.PasswordDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.UpdatePasswordDialog; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.YamlFileInput; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.YamlInput; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel; -import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel.Result; -import org.springsource.ide.eclipse.commons.frameworks.core.util.IOUtil; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.ui.UIContext; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -public class DefaultCfUserInteractions implements CfUserInteractions { - - private final SimpleDIContext context; - - public DefaultCfUserInteractions(SimpleDIContext context) { - this.context = context; - } - - private Shell getShell() { - return context.getBean(UIContext.class).getShell(); - } - - @Override - public void openPasswordDialog(PasswordDialogModel model) { - getShell().getDisplay().syncExec(new Runnable() { - @Override - public void run() { - new UpdatePasswordDialog(getShell(), model).open(); - } - }); - } - - @Override - public void openEditAppsManagerURLDialog(CustomizeAppsManagerURLDialogModel model) { - getShell().getDisplay().syncExec(new Runnable() { - @Override - public void run() { - new CustomizeAppsManagerURLDialog(model, getShell()).open(); - } - }); - } - - @Override - public CloudApplicationDeploymentProperties promptApplicationDeploymentProperties(DeploymentPropertiesDialogModel model) - throws Exception { - final Shell shell = getShell(); - - if (shell != null) { - model.initFileModel(); - model.initManualModel(); - shell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - new DeploymentPropertiesDialog(shell, model).open(); - } - }); - } - - return model.getDeploymentProperties(); - } - - @Override - public ManifestDiffDialogModel.Result confirmReplaceApp(String title, CloudData cloudData, IFile manifestFile, CloudApplicationDeploymentProperties deploymentProperties) throws Exception { - final Exception[] error = new Exception[1]; - final Result[] result = new Result[1]; - getShell().getDisplay().syncExec(() -> { - try { - result[0] = confirmReplaceApp(title, cloudData, manifestFile, deploymentProperties, new NullProgressMonitor()); - } catch (Exception e) { - error[0] = e; - } - }); - - if (error[0] != null) { - throw error[0]; - } - return result[0]; - } - - private ManifestDiffDialogModel.Result confirmReplaceApp(String title, CloudData cloudData, IFile manifestFile, CloudApplicationDeploymentProperties existingAppDeploymentProperties, IProgressMonitor monitor) throws Exception { - - - Result result = confirmReplaceAppWithManifest(title, cloudData, manifestFile, - existingAppDeploymentProperties, monitor); - if (result == null) { - String message = "Replace content of the existing Cloud application? Existing deployment properties including bound services will be retained."; - if (MessageDialog.openConfirm(getShell(), title, message)) { - // Not ideal, but using "Forget Manifest" to indicate to use existing Cloud Foundry app deployment properties - return Result.FORGET_MANIFEST; - } else { - return Result.CANCELED; - } - } else { - return result; - } - } - - private ManifestDiffDialogModel.Result confirmReplaceAppWithManifest(String title, CloudData cloudData, IFile manifestFile, CloudApplicationDeploymentProperties existingAppDeploymentProperties, IProgressMonitor monitor) throws Exception { - - if (manifestFile != null && manifestFile.isAccessible()) { - - - String yamlContents = IOUtil.toString(manifestFile.getContents()); - - YamlGraphDeploymentProperties newDeploymentProperties = new YamlGraphDeploymentProperties(yamlContents, existingAppDeploymentProperties.getAppName(), cloudData); - TextEdit edit = null; - String errorMessage = null; - try { - MultiTextEdit me = newDeploymentProperties.getDifferences(existingAppDeploymentProperties); - edit = me != null && me.hasChildren() ? me : null; - } catch (MalformedTreeException e) { - errorMessage = "Failed to create text differences between local manifest file and deployment properties on CF."; - } catch (Throwable t) { - errorMessage = "Failed to parse local manifest file YAML contents."; - } - if (errorMessage != null) { - throw ExceptionUtil.coreException(errorMessage); - } - - if (edit != null) { - final IDocument doc = new Document(yamlContents); - edit.apply(doc); - - final YamlFileInput left = new YamlFileInput(manifestFile, - BootDashActivator.getDefault().getImageRegistry().get(BootDashActivator.CLOUD_ICON)); - final YamlInput right = new YamlInput("Existing application in Cloud Foundry", - BootDashActivator.getDefault().getImageRegistry().get(BootDashActivator.CLOUD_ICON), - doc.get()); - - CompareConfiguration config = new CompareConfiguration(); - config.setLeftLabel(left.getName()); - config.setLeftImage(left.getImage()); - config.setRightLabel(right.getName()); - config.setRightImage(right.getImage()); - - final CompareEditorInput input = new CompareEditorInput(config) { - @Override - protected Object prepareInput(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - if (hasDeletedService(newDeploymentProperties, existingAppDeploymentProperties)) { - setMessage("WARNING: If using the manifest file, existing service bindings for the application that are not listed in the manifest will be removed."); - } - return new DiffNode(left, right); - } - - }; - input.setTitle("Replacing existing application"); - - input.run(monitor); - - // TODO: At the moment, this dialogue offers limited functionality to just compare manifest with existing app. Eventually - // we want to have a "full feature" compare editor that allows users to forget manifest - // or make changes - config.setLeftEditable(false); - - ManifestDiffDialogModel model = new ManifestDiffDialogModel(input); - - int val = new ManifestDiffDialog(getShell(), model, title).open(); - return ManifestDiffDialog.getResultForCode(val); - } - } - return null; - } - - private boolean hasDeletedService(YamlGraphDeploymentProperties newDeployment, CloudApplicationDeploymentProperties oldDeployment) { - return !newDeployment.getServices().containsAll(oldDeployment.getServices()); - } - - @Override - public Result openManifestDiffDialog(ManifestDiffDialogModel model) throws CoreException { - LiveVariable resultCode = new LiveVariable<>(); - LiveVariable error = new LiveVariable<>(); - getShell().getDisplay().syncExec(() -> { - try { - resultCode.setValue(new ManifestDiffDialog(getShell(), model).open()); - } catch (Exception e) { - error.setValue(e); - } - }); - if (error.getValue()!=null) { - throw ExceptionUtil.coreException(error.getValue()); - } else { - return ManifestDiffDialog.getResultForCode(resultCode.getValue()); - } - } - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/util/CloudErrors.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/util/CloudErrors.java deleted file mode 100644 index 334896672..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/util/CloudErrors.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.util; - -public class CloudErrors { - - /** - * check if access token error - * - * @param e - * @return true if access token error. False otherwise - */ - public static boolean isAccessTokenError(Exception e) { - return hasCloudError(e, "access_denied") || hasCloudError(e, "Error requesting access token") - || (hasCloudError(e, "access") && hasCloudError(e, "token")); - } - - public static boolean isBadRequest(Exception e) { - return hasCloudError(e, "400"); - } - - /** - * check 404 error. For example, application does not exist - * - * @param t - * @return true if 404 error. False otherwise - */ - public static boolean isNotFoundException(Exception e) { - return hasCloudError(e, "404"); - } - - /** - * check 503 service error. - * - * @param t - * @return true if 404 error. False otherwise - */ - public static boolean is503Error(Exception e) { - return hasCloudError(e, "503"); - } - - public static boolean hasCloudError(Exception e, String error) { - return hasError(e, error); - } - - public static void checkAndRethrowCloudException(Exception e, String errorPrefix) throws Exception { - // Special case for CF exceptions: - // CF exceptions may not contain the error in the message but rather - // the description - throw e; - } - - protected static boolean hasError(Exception exception, String pattern) { - String message = exception.getMessage(); - return message != null && message.contains(pattern); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/views/properties/CloudFoundryAppPropertiesSection.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/views/properties/CloudFoundryAppPropertiesSection.java deleted file mode 100644 index f153dafaf..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/views/properties/CloudFoundryAppPropertiesSection.java +++ /dev/null @@ -1,51 +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.cf.views.properties; - -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; -import org.springframework.ide.eclipse.boot.dash.views.properties.AbstractBdeGeneralPropertiesSection; -import org.springframework.ide.eclipse.boot.dash.views.properties.AppPropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.BootDashElementPropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.DefaultPathPropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.InstancesPropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.ProjectPropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.ReadOnlyStringPropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.RunStatePropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.TagsPropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.UrlPropertyControl; - -/** - * Properties view section for Cloud Foundry app elements - * - * @author Alex Boyko - */ -public class CloudFoundryAppPropertiesSection extends AbstractBdeGeneralPropertiesSection { - - @Override - protected BootDashElementPropertyControl[] createPropertyControls() { - return new BootDashElementPropertyControl[] { - new RunStatePropertyControl(), - new AppPropertyControl(), - new ProjectPropertyControl(), - new InstancesPropertyControl(), - new UrlPropertyControl<>(BootDashElement.class, "URL:", ((e) -> e.getUrl())), - new DefaultPathPropertyControl(), - new ReadOnlyStringPropertyControl<>(CloudAppDashElement.class, "Healthcheck:", (e) -> e.getHealthCheck(), true), - new ReadOnlyStringPropertyControl<>(CloudAppDashElement.class, "Healthcheck Http Endpoint:", (e) -> e.getHealthCheckHttpEndpoint(), true), - new ReadOnlyStringPropertyControl<>(CloudAppDashElement.class, "Jmx Ssh Tunnel:", (e) -> e.getJmxSshTunnelStatus().getValue().getLabel(), false), - new ReadOnlyStringPropertyControl<>(CloudAppDashElement.class, "Jmx Local Port:", (e) -> e.getCfJmxPort()>0 ? (""+e.getCfJmxPort()) : "", false), - new ReadOnlyStringPropertyControl<>(CloudAppDashElement.class, "Jmx URL:", (e) -> e.getJmxUrl(), false), - new TagsPropertyControl() - }; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/views/properties/CloudServiceGeneralPropertiesSection.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/views/properties/CloudServiceGeneralPropertiesSection.java deleted file mode 100644 index cd200909d..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/views/properties/CloudServiceGeneralPropertiesSection.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.cf.views.properties; - -import java.util.function.Function; - -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudServiceInstanceDashElement; -import org.springframework.ide.eclipse.boot.dash.views.properties.AbstractBdeGeneralPropertiesSection; -import org.springframework.ide.eclipse.boot.dash.views.properties.AbstractBdePropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.BdeReadOnlyTextPropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.BootDashElementPropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.TagsPropertyControl; -import org.springframework.ide.eclipse.boot.dash.views.properties.UrlPropertyControl; - -/** - * Properties section for cloud service elements - * - * @author Alex Boyko - * @author Kris De Volder - */ -public class CloudServiceGeneralPropertiesSection extends AbstractBdeGeneralPropertiesSection { - - @Override - protected BootDashElementPropertyControl[] createPropertyControls() { - return new BootDashElementPropertyControl[] { - //textProperty("Name:", (e) -> e.getName()), - textProperty("Service:", (e) -> e.getService()), - textProperty("Plan:", (e) -> e.getPlan()), - textProperty("Description:", (e) -> e.getDescription()), - urlProperty("Docs:", (e) -> e.getDocumentationUrl()), - urlProperty("URL:", (e) -> e.getUrl()), - new TagsPropertyControl() - }; - } - - private AbstractBdePropertyControl urlProperty(String label, Function getter) { - return new UrlPropertyControl<>(CloudServiceInstanceDashElement.class, label, getter); - } - - private AbstractBdePropertyControl textProperty(String label, Function getter) { - return new BdeReadOnlyTextPropertyControl<>(CloudServiceInstanceDashElement.class, label, getter); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/views/properties/HealthCheckPropertyControl.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/views/properties/HealthCheckPropertyControl.java deleted file mode 100644 index 738d682bc..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.cf/src/org/springframework/ide/eclipse/boot/dash/cf/views/properties/HealthCheckPropertyControl.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cf.views.properties; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage; -import org.springframework.ide.eclipse.boot.dash.cf.client.HealthChecks; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.ops.SetHealthCheckOperation; -import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; -import org.springframework.ide.eclipse.boot.dash.views.properties.AbstractBdePropertyControl; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; - -/** - * @author Kris De Volder - */ -public class HealthCheckPropertyControl extends AbstractBdePropertyControl { - - private CloudAppDashElement app; - private Combo selection; - - @Override - public void createControl(Composite composite, TabbedPropertySheetPage page) { - super.createControl(composite, page); - page.getWidgetFactory().createLabel(composite, "Healthcheck:"); - selection = new Combo(composite, SWT.READ_ONLY); -// Don't use the 'CCombo' it looks really bad on linux. Doesn't properly size itself and so contents is 'chopped'. -// selection = page.getWidgetFactory().createCCombo(composite, SWT.READ_ONLY); - selection.setItems(HealthChecks.HC_ALL); - refreshControl(); - selection.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - handle(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - handle(); - } - - private void handle() { - String selected = selection.getText(); - if (StringUtil.hasText(selected)) { - SetHealthCheckOperation op = new SetHealthCheckOperation(app, selected, app.createCancelationToken()); - app.getBootDashModel().runAsynch(op, null /* no user interactions */); - } - } - }); - } - - @Override - public void refreshControl() { - if (app!=null && selection!=null && !selection.isDisposed()) { - String hc = app.getHealthCheck(); - if (StringUtil.hasText(hc)) { - selection.setText(hc); - } else { - selection.setText(""); - } - } - } - - @Override - public void setInput(BootDashElement bde) { - if (bde instanceof CloudAppDashElement) { - super.setInput(bde); - app = (CloudAppDashElement)bde; - } - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.feature/feature.xml b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.feature/feature.xml index d714cca69..c6268cdd8 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.feature/feature.xml +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.feature/feature.xml @@ -37,13 +37,6 @@ version="0.0.0" unpack="false"/> - - - + - - org.eclipse.m2e.feature 0.0.0 - - eclipse-feature - org.springframework.tooling.cloudfoundry.manifest.ls.feature - 0.0.0 - - - eclipse-plugin - org.springframework.ide.eclipse.boot.dash.cf - 0.0.0 - diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/AllBootDashTests.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/AllBootDashTests.java index 6ac70de8c..d8f22ec44 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/AllBootDashTests.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/AllBootDashTests.java @@ -13,13 +13,7 @@ package org.springframework.ide.eclipse.boot.dash.test; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; -import org.springframework.ide.eclipse.boot.dash.docker.ui.SelectDockerDaemonDialog; import org.springframework.ide.eclipse.boot.dash.test.actuator.ActuatorDataTest; -import org.springframework.ide.eclipse.boot.dash.test.yaml.AppNameReconcilerTest; -import org.springframework.ide.eclipse.boot.dash.test.yaml.CFRouteTests; -import org.springframework.ide.eclipse.boot.dash.test.yaml.DeploymentProperties2YamlTest; -import org.springframework.ide.eclipse.boot.dash.test.yaml.ManifestCompareMergeTests; -import org.springframework.ide.eclipse.boot.dash.test.yaml.Yaml2DeploymentPropertiesTest; @RunWith(Suite.class) @SuiteClasses({ @@ -28,42 +22,27 @@ import org.springframework.ide.eclipse.boot.dash.test.yaml.Yaml2DeploymentProper // Raised up temporarily to be run first. - BootDashDockerTests.class, //50 seconds - SelectDockerDaemonDialogTest.class, +// BootDashDockerTests.class, //50 seconds +// SelectDockerDaemonDialogTest.class, //New: (move down the chain later based on runtime) - JmxSupportTest.class, PropertyFileStoreTest.class, - // Manifest YAML/Deployment Properties tests (less than 2 seconds per suite) - DeploymentProperties2YamlTest.class, - Yaml2DeploymentPropertiesTest.class, - AppNameReconcilerTest.class, - RouteBuilderTest.class, - CFRouteTests.class, - //Really short (less than 2 seconds per suite): JLRMethodParserTest.class, OrderBasedComparatorTest.class, - ManifestCompareMergeTests.class, AbstractLaunchConfigurationsDashElementTest.class, BootDashElementTagsTests.class, ActuatorDataTest.class, ToggleFiltersModelTest.class, //Medium length (less than 30 seconds): - JarNameGeneratorTest.class, BootDashViewModelTest.class, - BootJarPackagingTest.class, BeanResourceDefinitionParsingTests.class, //Long tests (more than 30 seconds): - CloudFoundryBootDashModelMockingTest.class, - DeploymentPropertiesDialogModelTests.class, BootDashActionTests.class, BootDashModelTest.class, - CloudFoundryClientTest.class, - CloudFoundryBootDashModelIntegrationTest.class, }) public class AllBootDashTests { diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/AllUserInteractions.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/AllUserInteractions.java index 9654b6e4d..5889f4530 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/AllUserInteractions.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/AllUserInteractions.java @@ -10,9 +10,8 @@ *******************************************************************************/ package org.springframework.ide.eclipse.boot.dash.test; -import org.springframework.ide.eclipse.boot.dash.cf.ui.CfUserInteractions; import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; import org.springframework.ide.eclipse.boot.dash.docker.ui.DockerUserInteractions; -public interface AllUserInteractions extends UserInteractions, CfUserInteractions, DockerUserInteractions { +public interface AllUserInteractions extends UserInteractions, DockerUserInteractions { } \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashActionTests.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashActionTests.java index 542af13f5..157e32724 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashActionTests.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashActionTests.java @@ -16,7 +16,6 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import java.util.ArrayList; @@ -24,7 +23,6 @@ import java.util.EnumSet; import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -41,10 +39,6 @@ import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTargetType; import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveDataConnectionManagementActions; import org.springframework.ide.eclipse.boot.dash.model.AbstractLaunchConfigurationsDashElement; @@ -71,7 +65,6 @@ import org.springframework.ide.eclipse.boot.test.AutobuildingEnablement; import org.springframework.ide.eclipse.boot.test.BootProjectTestHarness; import org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.WizardConfigurer; import org.springframework.ide.eclipse.boot.test.util.TestBracketter; -import org.springsource.ide.eclipse.commons.core.pstore.InMemoryPropertyStore; import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition; import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; @@ -387,16 +380,6 @@ public class BootDashActionTests { } } - { - CloudAppDashElement cfElement = mockCfElement(appGuid, "demo-app"); - selection.setElements(cfElement); - List actions = liveActionsMenu.getActions(); - Set actualLabels = actions.stream().map(IAction::getText).collect(Collectors.toSet()); - assertEquals(ImmutableSet.of("Connect remote process 1 (lbl)"), actualLabels); - for (IAction ac : actions) { - assertTrue(ac.isEnabled()); - } - } } private IAction assertActionWithLabel(List actions, String expectedLabel) { @@ -1008,20 +991,4 @@ public class BootDashActionTests { return element; } - private CloudAppDashElement mockCfElement(String appGuid, String appName) { - CloudFoundryRunTarget cfTarget = mock(CloudFoundryRunTarget.class); - CloudFoundryRunTargetType cfType = mock(CloudFoundryRunTargetType.class); - when(cfTarget.getType()).thenReturn(cfType); - - CloudFoundryBootDashModel model = mock(CloudFoundryBootDashModel.class); - when(model.getRunTarget()).thenReturn(cfTarget); - CloudAppDashElement element = spy(new CloudAppDashElement(model, appName, new InMemoryPropertyStore())); - when(element.getAppGuid()).thenReturn(UUID.fromString(appGuid)); - when(element.getName()).thenReturn(appName); - when(element.supportedGoalStates()).thenReturn(CloudFoundryRunTarget.RUN_GOAL_STATES); - when(element.getTarget()).thenReturn(cfTarget); - return element; - } - - } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashModelTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashModelTest.java index 91da3adeb..6f13cadfa 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashModelTest.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashModelTest.java @@ -82,7 +82,6 @@ import org.springframework.ide.eclipse.boot.core.cli.BootCliCommand; import org.springframework.ide.eclipse.boot.core.cli.BootInstallManager; import org.springframework.ide.eclipse.boot.core.cli.install.CloudCliInstall; import org.springframework.ide.eclipse.boot.core.cli.install.IBootInstall; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudServiceInstanceDashElement; import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; import org.springframework.ide.eclipse.boot.dash.model.BootDashElementsFilterBoxModel; import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; @@ -1534,8 +1533,7 @@ public class BootDashModelTest { } private boolean isService(BootDashElement e) { - return e instanceof LocalCloudServiceDashElement - || e instanceof CloudServiceInstanceDashElement; + return e instanceof LocalCloudServiceDashElement; } public void waitNonServiceElements(final String... expectedElementNames) throws Exception { diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashViewModelTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashViewModelTest.java index 7900f5d07..cfd15de0f 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashViewModelTest.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashViewModelTest.java @@ -16,9 +16,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.contains; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.contains; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; @@ -38,28 +38,19 @@ import org.eclipse.debug.core.ILaunchConfiguration; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials.CFCredentialType; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.StoreCredentialsMode; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryTargetProperties; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; +import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; 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.BootDashModel.ElementStateListener; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; import org.springframework.ide.eclipse.boot.dash.model.BootProjectDashElement; import org.springframework.ide.eclipse.boot.dash.model.RunTarget; import org.springframework.ide.eclipse.boot.dash.model.RunTargets; -import org.springframework.ide.eclipse.boot.dash.model.SecuredCredentialsStore; import org.springframework.ide.eclipse.boot.dash.model.ToggleFiltersModel.FilterChoice; import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.RunTargetTypes; import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.TargetProperties; import org.springframework.ide.eclipse.boot.dash.test.mocks.MockBootDashModel; -import org.springframework.ide.eclipse.boot.dash.test.mocks.MockRunTarget; -import org.springframework.ide.eclipse.boot.dash.test.mocks.MockRunTargetType; import org.springframework.ide.eclipse.boot.launch.BootLaunchConfigurationDelegate; import org.springframework.ide.eclipse.boot.test.BootProjectTestHarness; import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; @@ -529,38 +520,6 @@ public class BootDashViewModelTest { } - @Test - public void testRestoreSingleRunTarget() throws Exception { - context.injections.def(MockRunTargetType.class, injections -> { - MockRunTargetType targetType = new MockRunTargetType(injections, "MOCK"); - return targetType; - }); - - String targetId = "foo"; - - harness = new BootDashViewModelHarness(context); - MockRunTargetType targetType = context.injections.getBean(MockRunTargetType.class); - - CloudFoundryTargetProperties props = new CloudFoundryTargetProperties(null, targetType, context.injections); - props.put(TargetProperties.RUN_TARGET_ID, targetId); - props.put("describe", "This is foo"); - RunTarget savedTarget = targetType.createRunTarget(props); - harness.model.getRunTargets().add(savedTarget); - BootDashModelContext oldContext = harness.context; - - harness.reload(); - - MockRunTarget restoredTarget = (MockRunTarget)harness.getRunTarget(targetType); - - //Not a stric requirement, but it would be a little strange of the restored - // target was the exact same object as the saved target (the test may be broken - // or some state in the model is not cleaned up when it is disposed) - assertTrue(restoredTarget != savedTarget); - - assertEquals(savedTarget, restoredTarget); - assertEquals("This is foo", restoredTarget.get("describe")); - } - @Test public void testModelComparator() throws Exception { //View model is expected to provide a comparator that is based on @@ -568,8 +527,6 @@ public class BootDashViewModelTest { //models based on type first then runtarget id second. context.withTargetTypes(RunTargetTypes.LOCAL); - context.injections.def(RunTargetType.class, injections -> new MockRunTargetType(context.injections, "foo-type")); - context.injections.def(RunTargetType.class, injections -> new MockRunTargetType(context.injections, "bar-type")); harness = new BootDashViewModelHarness(context); Comparator comparator = harness.model.getModelComparator(); @@ -622,127 +579,4 @@ public class BootDashViewModelTest { return model; } - @Test - public void testUpdatePropertiesInStore() throws Exception { - context.injections.def(MockRunTargetType.class, injections -> { - MockRunTargetType targetType = new MockRunTargetType(injections, "mock-type"); - targetType.setRequiresCredentials(true); - return targetType; - }); - harness = new BootDashViewModelHarness(context); - - MockRunTargetType targetType = context.injections.getBean(MockRunTargetType.class); - CloudFoundryTargetProperties properties = new CloudFoundryTargetProperties(null, targetType, context.injections); - properties.setCredentials(CFCredentials.fromPassword("secret")); - - MockRunTarget target = (MockRunTarget) targetType.createRunTarget(properties); - harness.model.getRunTargets().add(target); - - harness.model.updateTargetPropertiesInStore(); - - assertEquals("secret", ((CloudFoundryTargetProperties)target.getTargetProperties()).getCredentials().getSecret()); - - harness.reload(); - - MockRunTarget restoredTarget = (MockRunTarget) harness.getRunTarget(targetType); - assertTrue(restoredTarget != target); //Not a strict requirement, but it is more or less - // expected the restored target is a brand new object - - //TODO: Strange test. Shouldn't there be something to check here? - } - - @Test - public void testRememberPassword() throws Exception { - context.injections.def(MockRunTargetType.class, injections -> { - MockRunTargetType targetType = new MockRunTargetType(injections, "mock-type"); - targetType.setRequiresCredentials(true); - return targetType; - }); - harness = new BootDashViewModelHarness(context); - MockRunTargetType targetType = context.injections.getBean(MockRunTargetType.class); - CloudFoundryTargetProperties properties = new CloudFoundryTargetProperties(null, targetType, context.injections); - properties.put(TargetProperties.RUN_TARGET_ID, "target-id"); - properties.setStoreCredentials(StoreCredentialsMode.STORE_PASSWORD); - properties.setCredentials(CFCredentials.fromPassword("secret")); - - MockRunTarget target = (MockRunTarget) targetType.createRunTarget(properties); - harness.model.getRunTargets().add(target); - - harness.model.updateTargetPropertiesInStore(); - - SecuredCredentialsStore secureStore = harness.context.getSecuredCredentialsStore(); - - //This test needs to have knowledge what keys the passwords are store under. - // That seems undesirable. - String key = "mock-type:target-id"; - { - CloudFoundryTargetProperties targetProperties = (CloudFoundryTargetProperties) target.getTargetProperties(); - assertEquals(StoreCredentialsMode.STORE_PASSWORD, targetProperties.getStoreCredentials()); - assertEquals(CFCredentialType.PASSWORD, targetProperties.getCredentials().getType()); - assertEquals("secret", targetProperties.getCredentials().getSecret()); - assertEquals("secret", secureStore.getCredentials(key)); - } - - ///////////////////////////////////////// - // check that when runtargets are restored from the store the password prop is properly - // restored - - harness.reload(); - - MockRunTarget restoredTarget = (MockRunTarget) harness.getRunTarget(targetType); - assertTrue(restoredTarget != target); //Not a strict requirement, but it is more or less - // expected the restored target is a brand new object - { - CloudFoundryTargetProperties restoredTargetProperties = (CloudFoundryTargetProperties) restoredTarget.getTargetProperties(); - assertEquals(StoreCredentialsMode.STORE_PASSWORD, restoredTargetProperties.getStoreCredentials()); - assertEquals("secret", restoredTargetProperties.getCredentials().getSecret()); - } - } - - @Test - public void testDontRememberPassword() throws Exception { - context.injections.def(MockRunTargetType.class, injections -> { - MockRunTargetType targetType = new MockRunTargetType(injections, "mock-type"); - targetType.setRequiresCredentials(true); - return targetType; - }); - harness = new BootDashViewModelHarness(context); - - MockRunTargetType targetType = context.injections.getBean(MockRunTargetType.class); - CloudFoundryTargetProperties properties = new CloudFoundryTargetProperties(null, targetType, context.injections); - properties.setStoreCredentials(StoreCredentialsMode.STORE_NOTHING); - properties.setCredentials(CFCredentials.fromPassword("secret")); - - MockRunTarget target = (MockRunTarget) targetType.createRunTarget(properties); - harness.model.getRunTargets().add(target); - - harness.model.updateTargetPropertiesInStore(); - - SecuredCredentialsStore secureStore = harness.context.getSecuredCredentialsStore(); - - //This test needs to have knowledge what keys the passwords are store under. - // That seems undesirable. - String key = "mock-type:target-id"; - { - CloudFoundryTargetProperties targetProperties = (CloudFoundryTargetProperties) target.getTargetProperties(); - assertEquals(StoreCredentialsMode.STORE_NOTHING, targetProperties.getStoreCredentials()); - assertEquals("secret", targetProperties.getCredentials().getSecret()); - assertNull(secureStore.getCredentials(key)); - } - - ///////////////////////////////////////// - // check that when runtargets are restored from the store the password is not remebered - - harness.reload(); - - MockRunTarget restoredTarget = (MockRunTarget) harness.getRunTarget(targetType); - assertTrue(restoredTarget != target); //Not a strict requirement, but it is more or less - // expected the restored target is a brand new object - { - CloudFoundryTargetProperties restoredTargetProperties = (CloudFoundryTargetProperties) restoredTarget.getTargetProperties(); - assertEquals(StoreCredentialsMode.STORE_NOTHING,restoredTargetProperties.getStoreCredentials()); - assertNull(restoredTargetProperties.getCredentials()); - } - } - } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootJarPackagingTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootJarPackagingTest.java deleted file mode 100644 index a12742c3d..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootJarPackagingTest.java +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.test; - -import static org.springsource.ide.eclipse.commons.tests.util.StsTestUtil.assertNoErrors; - -import java.io.File; -import java.util.jar.JarFile; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.mockito.Mockito; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; -import org.springframework.ide.eclipse.boot.dash.cf.packaging.CloudApplicationArchiverStrategies; -import org.springframework.ide.eclipse.boot.dash.cf.packaging.CloudApplicationArchiverStrategy; -import org.springframework.ide.eclipse.boot.dash.cf.packaging.ICloudApplicationArchiver; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.test.BootProjectTestHarness; -import org.springframework.ide.eclipse.boot.test.util.JavaUtils; -import org.springframework.ide.eclipse.boot.test.util.LaunchResult; -import org.springsource.ide.eclipse.commons.tests.util.StsTestCase; -import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil; - -import static org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.setPackage; - -public class BootJarPackagingTest extends StsTestCase { - - private JavaUtils java = new JavaUtils(); - - @Override - protected void setUp() throws Exception { - super.setUp(); - StsTestUtil.deleteAllProjects(); - StsTestUtil.setAutoBuilding(false); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testSimple() throws Exception { - UserInteractions ui = Mockito.mock(UserInteractions.class); - BootProjectTestHarness harness = getHarness(); - IProject project = harness.createBootProject("simple-boot", - setPackage("demo") - ); - createFile(project, "src/main/java/demo/Greeter.java", - "package demo;\n" + - "\n" + - "import org.springframework.boot.CommandLineRunner;\n" + - "import org.springframework.stereotype.Component;\n" + - "\n" + - "@Component\n" + - "public class Greeter implements CommandLineRunner {\n" + - "\n" + - " @Override\n" + - " public void run(String... arg0) throws Exception {\n" + - " System.out.println(\"Hello World!\");\n" + - " }\n" + - "\n" + - "}\n" - ); - StsTestUtil.assertNoErrors(project); // Builds the project - File jarFile = packageAsJar(project, ui); - LaunchResult result = java.runJar(jarFile); - assertContains("Hello World!", result.out); - assertEquals(0, result.terminationCode); - Mockito.verifyZeroInteractions(ui); - } - - public void testProjectDependency() throws Exception { - IProject depProject = createPredefinedProject("demo-lib"); - StsTestUtil.assertNoErrors(depProject); - UserInteractions ui = Mockito.mock(UserInteractions.class); - BootProjectTestHarness harness = getHarness(); - - IProject project = harness.createBootProject("simple-boot", - setPackage("demo") - ); - fileReplace(project, "pom.xml", - "", - " \n" + - " org.demo\n" + - " demo-lib\n" + - " 0.0.1\n" + - " \n" + - " "); - - - createFile(project, "src/main/java/demo/Greeter.java", - "package demo;\n" + - "\n" + - "import org.demo.lib.TheLib;\n" + - "import org.springframework.boot.CommandLineRunner;\n" + - "import org.springframework.stereotype.Component;\n" + - "\n" + - "@Component\n" + - "public class Greeter implements CommandLineRunner {\n" + - "\n" + - " @Override\n" + - " public void run(String... arg0) throws Exception {\n" + - " System.out.println(TheLib.createGreeting(\"Kris\"));\n" + - " }\n" + - "\n" + - "}\n" - ); - assertNoErrors(project); - - File jarFile = packageAsJar(project, ui); - assertEntries(jarFile, - "lib/demo-lib.jar" - ); - LaunchResult result = java.runJar(jarFile); - assertContains("Hello, Kris!", result.out); - assertEquals(0, result.terminationCode); - - Mockito.verifyZeroInteractions(ui); - } - - /** - * Verifies that jarFile has at least a given list of entries (in any order). - */ - private void assertEntries(File file, String... expected) throws Exception { - JarFile jarFile = new JarFile(file); - try { - for (String name : expected) { - assertNotNull("Missing expected Jar Entry: "+name, jarFile.getJarEntry(name)); - } - } finally { - jarFile.close(); - } - } - - public static File packageAsJar(IProject project, UserInteractions ui) throws Exception { - CloudApplicationArchiverStrategy strategy = CloudApplicationArchiverStrategies.packageAsJar(project, ui); - ICloudApplicationArchiver archiver = strategy.getArchiver(new NullProgressMonitor()); - assertNotNull(archiver); - File jar = archiver.getApplicationArchive(new NullProgressMonitor()); - assertNotNull(jar); - assertTrue(jar.isFile()); - return jar; - } - - private BootProjectTestHarness getHarness() { - return new BootProjectTestHarness(ResourcesPlugin.getWorkspace()); - } - - @Override - protected String getBundleName() { - return BootDashTestBundleConstants.BUNDLE_ID; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CfTestTargetParams.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CfTestTargetParams.java deleted file mode 100644 index 65542a15a..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CfTestTargetParams.java +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.test; - -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; - -import org.eclipse.core.runtime.Assert; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springsource.ide.eclipse.commons.frameworks.core.util.StringUtils; - -/** - * @author Kris De Volder - */ -public class CfTestTargetParams { - - public static CFClientParams fromEnv() { - try { - return new CFClientParams( - fromEnv("CF_TEST_API_URL"), - fromEnv("CF_TEST_USER"), - CFCredentials.fromPassword(fromEnv("CF_TEST_PASSWORD")), - false, //self signed - fromEnv("CF_TEST_ORG"), - fromEnvOrFile("CF_TEST_SPACE"), - fromEnvBoolean("CF_TEST_SKIP_SSL") - ); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static String fromEnvOrFile(String name) throws IOException { - String envVal = getEnvMaybe(name); - if (envVal!=null) { - return envVal; - } else { - String fileName = fromEnv(name+"_FILE"); - Path path = FileSystems.getDefault().getPath(fileName); - return Files.readAllLines(path).get(0); - } - } - - private static String getEnvMaybe(String name) { - String val = System.getenv(name); - if (!StringUtils.hasText(val)) { - val = System.getenv("bamboo_"+name); - } - return val; - } - - public static String fromEnv(String name) { - String value = getEnvMaybe(name); - Assert.isLegal(StringUtils.hasText(value), "The environment varable '"+name+"' must be set"); - return value; - } - - private static boolean fromEnvBoolean(String name) { - String value = getEnvMaybe(name); - if (value == null) { - return false; - } - return Boolean.parseBoolean(value); - } - - public static CFClientParams fromEnvWithCredentials(CFCredentials credentials) { - try { - return new CFClientParams( - fromEnv("CF_TEST_API_URL"), - fromEnv("CF_TEST_USER"), - credentials, - false, //self signed - fromEnv("CF_TEST_ORG"), - fromEnvOrFile("CF_TEST_SPACE"), - fromEnvBoolean("CF_TEST_SKIP_SSL") - ); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryApplicationHarness.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryApplicationHarness.java deleted file mode 100644 index 8bd96399a..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryApplicationHarness.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; -import static org.junit.Assert.fail; - -import java.util.HashSet; -import java.util.Set; - -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.DefaultClientRequestsV2; -import org.springframework.ide.eclipse.boot.dash.console.IApplicationLogConsole; -import org.springframework.ide.eclipse.boot.dash.console.LogMessage; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; -import org.springsource.ide.eclipse.commons.livexp.core.AbstractDisposable; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -import reactor.core.Disposable; - -public class CloudFoundryApplicationHarness extends AbstractDisposable { - - private Set ownedAppNames = new HashSet<>(); - private DefaultClientRequestsV2 client; - - public CloudFoundryApplicationHarness(DefaultClientRequestsV2 client) { - this.client = client; - if (client!=null) { - onDispose((d) -> { deleteOwnedApps(); }); - } - } - - public String randomAppName() throws Exception { - String name = StringUtil.datestamp()+"-"+randomAlphabetic(10); - ownedAppNames.add(name); - streamOutput(name); - return name; - } - - private void streamOutput(String name) throws Exception { - if (client!=null) { - IApplicationLogConsole logConsole = new IApplicationLogConsole() { - - @Override - public void onMessage(LogMessage log) { - System.out.println("%"+name+"-out: "+log.getMessage()); - } - - @Override - public void onComplete() { - System.out.println("%"+name+"-COMPLETE"); - } - - @Override - public void onError(Throwable exception) { - System.out.println("%"+name+"-ERROR: "+ExceptionUtil.getMessage(exception)); - } - - }; - Disposable logToken = client.streamLogs(name, logConsole); - onDispose((d) -> { - logToken.dispose(); - }); - } - } - - protected void deleteOwnedApps() { - System.out.println("owned app names: "+ownedAppNames); - if (!ownedAppNames.isEmpty()) { - - try { - for (String name : ownedAppNames) { - try { - System.out.println("delete owned app: "+name); - this.client.deleteApplication(name); - } catch (Exception e) { - System.out.println("Delete failed: " +ExceptionUtil.getMessage(e)); - // May get 404 or other 400 errors if it is alrready - // gone so don't prevent other owned apps from being - // deleted - } - } - - } catch (Exception e) { - fail("failed to cleanup owned apps: " + e.getMessage()); - } - } - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryBootDashModelIntegrationTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryBootDashModelIntegrationTest.java deleted file mode 100644 index e85defc16..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryBootDashModelIntegrationTest.java +++ /dev/null @@ -1,606 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.contains; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; -import static org.springframework.ide.eclipse.boot.dash.test.BootDashModelTest.waitForJobsToComplete; -import static org.springframework.ide.eclipse.boot.dash.test.CloudFoundryTestHarness.APP_DELETE_TIMEOUT; -import static org.springframework.ide.eclipse.boot.dash.test.CloudFoundryTestHarness.APP_DEPLOY_TIMEOUT; -import static org.springframework.ide.eclipse.boot.dash.test.CloudFoundryTestHarness.APP_IS_VISIBLE_TIMEOUT; -import static org.springframework.ide.eclipse.boot.dash.test.CloudFoundryTestHarness.SERVICE_DELETE_TIMEOUT; -import static org.springframework.ide.eclipse.boot.dash.test.util.JobUtil.runInJob; -import static org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.withStarters; -import static org.springsource.ide.eclipse.commons.tests.util.StsTestCase.createFile; - -import java.io.File; -import java.net.URL; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import org.apache.commons.io.IOUtils; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.Assert; -import org.eclipse.debug.core.DebugPlugin; -import org.junit.After; -import org.junit.Before; -import org.junit.FixMethodOrder; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runners.MethodSorters; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFServiceInstance; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials.CFCredentialType; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.DefaultClientRequestsV2; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.DefaultCloudFoundryClientFactoryV2; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.StoreCredentialsMode; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudServiceInstanceDashElement; -import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; -import org.springframework.ide.eclipse.boot.dash.model.BootProjectDashElement; -import org.springframework.ide.eclipse.boot.dash.model.RunState; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.test.util.SslValidationDisabler; -import org.springframework.ide.eclipse.boot.test.AutobuildingEnablement; -import org.springframework.ide.eclipse.boot.test.BootProjectTestHarness; -import org.springframework.ide.eclipse.boot.test.util.TestBracketter; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; -import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition; -import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -/** - * @author Kris De Volder - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class CloudFoundryBootDashModelIntegrationTest { - - private TestBootDashModelContext context; - private BootProjectTestHarness projects; - private CloudFoundryTestHarness harness; - - //////////////////////////////////////////////////////////// - private CFClientParams clientParams = CfTestTargetParams.fromEnv(); - private DefaultCloudFoundryClientFactoryV2 clientFactory = DefaultCloudFoundryClientFactoryV2.INSTANCE; - private DefaultClientRequestsV2 client = CloudFoundryClientTest.createClient(clientParams); - - public CloudFoundryApplicationHarness appHarness = new CloudFoundryApplicationHarness(client); - - @Rule - public AutobuildingEnablement disableAutoBuild = new AutobuildingEnablement(false); - - @Rule - public TestBracketter testBracketter = new TestBracketter(); - - public CloudFoundryServicesHarness services = new CloudFoundryServicesHarness(clientParams, client); - - @Before - public void setup() throws Exception { - SslValidationDisabler.disableSslValidation(); - StsTestUtil.deleteAllProjects(); - this.context = new TestBootDashModelContext( - ResourcesPlugin.getWorkspace(), - DebugPlugin.getDefault().getLaunchManager() - ).withCfClient(clientFactory); - this.harness = CloudFoundryTestHarness.create(context); - this.projects = new BootProjectTestHarness(context.getWorkspace()); - } - - @After - public void tearDown() throws Exception { - appHarness.deleteOwnedApps(); - services.dispose(); - client.close(); - harness.dispose(); - } - - //////////////////////////////////////////////////////////// - - @Test - public void testCreateCfTarget() throws Exception { - CloudFoundryBootDashModel target = harness.createCfTarget(CfTestTargetParams.fromEnv()); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertNotNull(target); - assertEquals(CFCredentialType.PASSWORD, credentials.getType()); - assertNotNull(credentials.getSecret()); - assertEquals(1, harness.getCfRunTargetModels().size()); - } - - @Test public void refreshTokenStreamTerminatedOnDispose() throws Exception { - CFClientParams params = CfTestTargetParams.fromEnv(); - ClientRequests client = clientFactory.getClient(params); - - Future> tokens = runInJob(() -> { - return client.getRefreshTokens().collect(Collectors.toList()).block(); - }); - - client.getApplicationsWithBasicInfo(); // forces the client to authenticate - client.dispose(); - - assertEquals(1, tokens.get(2, TimeUnit.SECONDS).size()); - } - - @Test public void testCreateCfTargetAndStoreToken() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_TOKEN); - assertNotNull(target); - assertTrue(target.isConnected()); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(CFCredentialType.REFRESH_TOKEN, credentials.getType()); - assertNotNull(credentials.getSecret()); - assertEquals(1, harness.getCfRunTargetModels().size()); - } - - - /** - * Test that tests a bunch of things. - * TODO: It isn't good practice to create 'test everything' tests... - * but we do it anyway because ramping up a test that deploys an app takes about 90 seconds... - * Maybe we can factor this better somehow so we have separate tests, but only deploy app once? - */ - @Test - public void testDeployAppAndDeleteAndStuff() throws Exception { - harness.createCfTarget(CfTestTargetParams.fromEnv()); - final CloudFoundryBootDashModel model = harness.getCfTargetModel(); - - final BootProjectDashElement project = harness.getElementFor( - projects.createBootProject("to-deploy", withStarters("actuator", "web")) - ); - final String appName = appHarness.randomAppName(); - - harness.answerDeploymentPrompt(ui(), appName, appName); - model.add(ImmutableList.of(project)); - - //The resulting deploy is asynchronous - new ACondition("wait for app '"+ appName +"'to appear", APP_IS_VISIBLE_TIMEOUT) { - public boolean test() throws Exception { - assertNotNull(model.getApplication(appName)); - return true; - } - }; - - new ACondition("wait for app '"+ appName +"'to be RUNNING", APP_DEPLOY_TIMEOUT) { - public boolean test() throws Exception { - CloudAppDashElement element = model.getApplication(appName); - assertEquals(RunState.RUNNING, element.getRunState()); - return true; - } - }; - - //Try to get request mappings - //TODO: make this work again in recent boot version (the rm endpoints are now not accessible anymore over http/https by default - // must actuator + ssh tunnel -// new ACondition("wait for request mappings", FETCH_REQUEST_MAPPINGS_TIMEOUT) { -// public boolean test() throws Exception { -// CloudAppDashElement element = model.getApplication(appName); -// List mappings = element.getLiveRequestMappings(); -// assertNotNull(mappings); //Why is the test sometimes failing here? -// assertTrue(!mappings.isEmpty()); //Even though this is an 'empty' app should have some mappings, -// // for example an 'error' page. -// return true; -// } -// }; - - //Try to delete the app... - reset(ui()); - when(ui().confirmOperation(eq("Deleting Elements"), anyString())).thenReturn(true); - - CloudAppDashElement app = model.getApplication(appName); - app.getBootDashModel().delete(ImmutableList.of(app), ui()); - - new ACondition("wait for app to be deleted", APP_DELETE_TIMEOUT) { - - @Override - public boolean test() throws Exception { - assertNull(model.getApplication(appName)); - return true; - } - }; - } - - private AllUserInteractions ui() { - return context.injections.getBean(AllUserInteractions.class); - } - - @Test public void testDeployAppIntoDebugMode() throws Exception { - harness.createCfTarget(CfTestTargetParams.fromEnv()); - final CloudFoundryBootDashModel model = harness.getCfTargetModel(); - - final BootProjectDashElement project = harness.getElementFor( - projects.createBootProject("to-deploy", withStarters("actuator", "web")) - ); - final String appName = appHarness.randomAppName(); - - harness.answerDeploymentPrompt(ui(), appName, appName); - model.performDeployment(ImmutableSet.of(project.getProject()), RunState.DEBUGGING); - - new ACondition("wait for app '"+ appName +"'to be DEBUGGING", APP_DEPLOY_TIMEOUT) { - public boolean test() throws Exception { - CloudAppDashElement element = model.getApplication(appName); - assertEquals(RunState.DEBUGGING, element.getRunState()); - return true; - } - }; - - } - -//This test commented because it uses 'createApplication' which no longer exists in V2 client. -// @Test -// public void testPreexistingApplicationInModel() throws Exception { -// // Create external client and deploy app "externally" -// ClientRequests externalClient = harness.createExternalClient(CfTestTargetParams.fromEnv()); -// -// List domains = externalClient.getDomains(); -// -// final String preexistingAppName = harness.randomAppName(); -// -// CloudApplicationDeploymentProperties deploymentProperties = new CloudApplicationDeploymentProperties(); -// deploymentProperties.setAppName(preexistingAppName); -// deploymentProperties.setMemory(1024); -// deploymentProperties.setUris(ImmutableList.of(preexistingAppName + "." + domains.get(0).getName())); -// deploymentProperties.setServices(ImmutableList.of()); -// externalClient.createApplication(deploymentProperties); -// -// // Create the boot dash target and model -// harness.createCfTarget(CfTestTargetParams.fromEnv()); -// -// final CloudFoundryBootDashModel model = harness.getCfTargetModel(); -// -// final BootProjectDashElement project = harness -// .getElementFor(projects.createBootWebProject("testPreexistingApplicationInModel")); -// final String newAppName = harness.randomAppName(); -// -// // Create a new one too -// harness.answerDeploymentPrompt(ui(), newAppName, newAppName); -// -// model.add(ImmutableList. of(project), ui); -// -// // The resulting deploy is asynchronous -// new ACondition("wait for apps '" + newAppName + "' and '" + preexistingAppName + "' to appear", -// APP_IS_VISIBLE_TIMEOUT) { -// public boolean test() throws Exception { -// assertNotNull(model.getApplication(newAppName)); -// assertNotNull(model.getApplication(preexistingAppName)); -// -// // check project mapping -// assertEquals("Expected new element in model to have workspace project mapping", -// model.getApplication(newAppName).getProject(), project.getProject()); -// -// // No project mapping for the "external" app -// assertNull(model.getApplication(preexistingAppName).getProject()); -// -// // check the actual CloudApplication -// CFApplication actualNewApp = model.getApplication(newAppName).getSummaryData(); -// assertEquals("No CloudApplication mapping found", actualNewApp.getName(), newAppName); -// -// CFApplication actualPreexistingApp = model.getApplication(preexistingAppName).getSummaryData(); -// assertEquals("No CloudApplication mapping found", actualPreexistingApp.getName(), preexistingAppName); -// -// return true; -// } -// }; -// } - - @Test - public void testEnvVarsSetOnFirstDeploy() throws Exception { - CloudFoundryBootDashModel target = harness.createCfTarget(CfTestTargetParams.fromEnv()); - final CloudFoundryBootDashModel model = harness.getCfTargetModel(); - - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - final String appName = appHarness.randomAppName(); - - Map env = new HashMap<>(); - env.put("FOO", "something"); - harness.answerDeploymentPrompt(ui(), appName, appName, env); - - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - new ACondition("wait for app '"+ appName +"'to be RUNNING", APP_DEPLOY_TIMEOUT) { - public boolean test() throws Exception { - CloudAppDashElement element = model.getApplication(appName); - assertEquals(RunState.RUNNING, element.getRunState()); - return true; - } - }; - - Map actualEnv = harness.fetchEnvironment(target, appName); - - assertEquals("something", actualEnv.get("FOO")); - } - - - @Test - public void testServicesBoundOnFirstDeploy() throws Exception { - CloudFoundryBootDashModel target = harness.createCfTarget(CfTestTargetParams.fromEnv()); - final CloudFoundryBootDashModel model = harness.getCfTargetModel(); - - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - List bindServices = ImmutableList.of( - services.createTestService(), services.createTestService() - ); - ACondition.waitFor("services exist "+bindServices, 30_000, () -> { - Set services = client.getServices().stream() - .map(CFServiceInstance::getName) - .collect(Collectors.toSet()); - System.out.println("services = "+services); - assertTrue(services.containsAll(bindServices)); - }); - - final String appName = appHarness.randomAppName(); - - harness.answerDeploymentPrompt(ui(), appName, appName, bindServices); - - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - new ACondition("wait for app '"+ appName +"'to be RUNNING", APP_DEPLOY_TIMEOUT) { - public boolean test() throws Exception { - CloudAppDashElement element = model.getApplication(appName); - assertEquals(RunState.RUNNING, element.getRunState()); - return true; - } - }; - - Set actualServices = client.getBoundServicesSet(appName).block(); - - assertEquals(ImmutableSet.copyOf(bindServices), actualServices); - } - - @Test public void testDeployManifestWithAbsolutePathAttribute() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - IProject project = projects.createProject("to-deploy"); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - waitForJobsToComplete(); - - File zipFile = getTestZip("testapp"); - final String appName = appHarness.randomAppName(); - IFile manifestFile = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " path: "+zipFile.getAbsolutePath() + "\n" + - " buildpack: staticfile_buildpack\n" - ); - harness.answerDeploymentPrompt(ui(), manifestFile); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - ACondition.waitFor("app to appear", APP_IS_VISIBLE_TIMEOUT, () -> { - assertNotNull(model.getApplication(appName)); - }); - - CloudAppDashElement app = model.getApplication(appName); - - ACondition.waitFor("app to be running", APP_DEPLOY_TIMEOUT, () -> { - assertEquals(RunState.RUNNING, app.getRunState()); - String url = pathJoin(app.getUrl(),"test.txt"); - assertEquals(url, "some content here\n", IOUtils.toString(new URL(url))); - }); - - verify(ui()).promptApplicationDeploymentProperties(any()); - verifyNoMoreInteractions(ui()); - } - - @Test public void randomRoute() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForJobsToComplete(); - - final String appName = appHarness.randomAppName(); - IFile manifestFile = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " random-route: true\n" + - " buildpack: java_buildpack\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ \"jre\": { version: 11.+ } }'\n" - ); - harness.answerDeploymentPrompt(ui(), manifestFile); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - ACondition.waitFor("app to appear", APP_IS_VISIBLE_TIMEOUT, () -> { - assertNotNull(model.getApplication(appName)); - }); - - CloudAppDashElement app = model.getApplication(appName); - - ACondition.waitFor("app to be running", APP_DEPLOY_TIMEOUT, () -> { - assertEquals(RunState.RUNNING, app.getRunState()); - }); - - String host = app.getLiveHost(); - assertTrue("app has host", StringUtil.hasText(host)); - assertTrue("app has default domain", host.endsWith("."+CFAPPS_IO())); - host = host.substring(0, host.length()-CFAPPS_IO().length()-1); - assertTrue("host is random generated on push", !host.equals(appName)); - } - - private String CFAPPS_IO() { - return CloudFoundryClientTest.get_CFAPPS_IO(clientParams); - } - - @Test public void randomRouteWithDomain() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForJobsToComplete(); - - final String appName = appHarness.randomAppName(); - IFile manifestFile = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " domain: "+CFAPPS_IO() + "\n" + - " random-route: true\n" + - " buildpack: java_buildpack\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ \"jre\": { version: 11.+ } }'\n" - ); - harness.answerDeploymentPrompt(ui(), manifestFile); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - ACondition.waitFor("app to appear", APP_IS_VISIBLE_TIMEOUT, () -> { - assertNotNull(model.getApplication(appName)); - }); - - CloudAppDashElement app = model.getApplication(appName); - - ACondition.waitFor("app to be running", APP_DEPLOY_TIMEOUT, () -> { - assertEquals(RunState.RUNNING, app.getRunState()); - }); - - String host = app.getLiveHost(); - assertTrue("app has host", StringUtil.hasText(host)); - assertTrue("app has default domain", host.endsWith("."+CFAPPS_IO())); - host = host.substring(0, host.length()-CFAPPS_IO().length()-1); - assertTrue("host is random generated on push", !host.equals(appName)); - } - - @Test public void httpRoute() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForJobsToComplete(); - - final String appName = appHarness.randomAppName(); - IFile manifestFile = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " buildpack: java_buildpack\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ \"jre\": { version: 11.+ } }'\n" + - " routes:\n" + - " - route: " + appName + '.'+CFAPPS_IO() - - ); - harness.answerDeploymentPrompt(ui(), manifestFile); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - ACondition.waitFor("app to appear", APP_IS_VISIBLE_TIMEOUT, () -> { - assertNotNull(model.getApplication(appName)); - }); - - CloudAppDashElement app = model.getApplication(appName); - - ACondition.waitFor("app to be running", APP_DEPLOY_TIMEOUT, () -> { - assertEquals(RunState.RUNNING, app.getRunState()); - }); - - String host = app.getLiveHost(); - assertEquals(appName + '.'+CFAPPS_IO(), host); - } - - @Ignore - @Test public void httpRouteWithPath() throws Exception { - // This fails because the path part is not obtained from element. Bug already raised - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForJobsToComplete(); - - final String appName = appHarness.randomAppName(); - IFile manifestFile = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " buildpack: java_buildpack\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ \"jre\": { version: 11.+ } }'\n" + - " routes:\n" + - " - route: " + appName + '.'+CFAPPS_IO() + "/myapppath" - - ); - harness.answerDeploymentPrompt(ui(), manifestFile); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - ACondition.waitFor("app to appear", APP_IS_VISIBLE_TIMEOUT, () -> { - assertNotNull(model.getApplication(appName)); - }); - - CloudAppDashElement app = model.getApplication(appName); - - ACondition.waitFor("app to be running", APP_DEPLOY_TIMEOUT, () -> { - assertEquals(RunState.RUNNING, app.getRunState()); - }); - - String host = app.getLiveHost(); - assertEquals(appName + '.'+CFAPPS_IO()+ "/myapppath", host); - } - - private String pathJoin(String url, String append) { - while (url.endsWith("/")) { - url = url.substring(0, url.length()-1); - } - while (append.startsWith("/")) { - append = append.substring(1); - } - return url+"/"+append; - } - - @Test public void deleteService() throws Exception { - String serviceName = services.createTestService(); - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - ACondition.waitFor("service to appear", APP_IS_VISIBLE_TIMEOUT, () -> { - assertNotNull(model.getService(serviceName)); - }); - - when(ui().confirmOperation(contains("Deleting"), contains("Are you sure that you want to delete"))) - .thenReturn(true); - - CloudServiceInstanceDashElement service = model.getService(serviceName); - model.canDelete(service); - model.delete(ImmutableSet.of(service), ui()); - - ACondition.waitFor("service to disapear", SERVICE_DELETE_TIMEOUT, () -> { - assertNull(model.getService(serviceName)); - }); - - } - - /////////////////////////////////////////////////////////////////////////////////// - - private File getTestZip(String fileName) { - File sourceWorkspace = new File( - StsTestUtil.getSourceWorkspacePath("org.springframework.ide.eclipse.boot.dash.test")); - File file = new File(sourceWorkspace, fileName + ".zip"); - Assert.isTrue(file.exists(), ""+ file); - return file; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryBootDashModelMockingTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryBootDashModelMockingTest.java deleted file mode 100644 index f56af1930..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryBootDashModelMockingTest.java +++ /dev/null @@ -1,3143 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2019 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.test; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.contains; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; -import static org.springframework.ide.eclipse.boot.dash.test.BootDashModelTest.waitForJobsToComplete; -import static org.springframework.ide.eclipse.boot.dash.test.CloudFoundryTestHarness.APP_DELETE_TIMEOUT; -import static org.springframework.ide.eclipse.boot.dash.test.CloudFoundryTestHarness.APP_DEPLOY_TIMEOUT; -import static org.springframework.ide.eclipse.boot.dash.test.util.JobUtil.runInJob; -import static org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.withPackaging; -import static org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.withStarters; -import static org.springsource.ide.eclipse.commons.tests.util.StsTestCase.assertContains; -import static org.springsource.ide.eclipse.commons.tests.util.StsTestCase.createFile; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.RandomStringUtils; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Platform; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.jface.action.IAction; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.springframework.ide.eclipse.boot.core.SpringBootCore; -import org.springframework.ide.eclipse.boot.core.internal.MavenSpringBootProject; -import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; -import org.springframework.ide.eclipse.boot.dash.cf.actions.EnableJmxSshTunnelAction; -import org.springframework.ide.eclipse.boot.dash.cf.actions.RestartApplicationOnlyAction; -import org.springframework.ide.eclipse.boot.dash.cf.actions.SelectManifestAction; -import org.springframework.ide.eclipse.boot.dash.cf.actions.UpdatePasswordAction; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials.CFCredentialType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials.LoginMethod; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.HealthChecks; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFDomainStatus; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.ReactorUtils; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.PasswordDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.StoreCredentialsMode; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.JmxSshTunnelManager; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTargetType; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryTargetProperties; -import org.springframework.ide.eclipse.boot.dash.dialogs.EditTemplateDialogModel; -import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel; -import org.springframework.ide.eclipse.boot.dash.model.AbstractBootDashModel; -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.BootDashModel.ElementStateListener; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel.ModelStateListener; -import org.springframework.ide.eclipse.boot.dash.model.LocalBootDashModel; -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.RunTargetPropertiesManager; -import org.springframework.ide.eclipse.boot.dash.model.SecuredCredentialsStore; -import org.springframework.ide.eclipse.boot.dash.test.CloudFoundryTestHarness.DeploymentAnswerer; -import org.springframework.ide.eclipse.boot.dash.test.mocks.MockCFApplication; -import org.springframework.ide.eclipse.boot.dash.test.mocks.MockCFSpace; -import org.springframework.ide.eclipse.boot.dash.test.mocks.MockCloudFoundryClientFactory; -import org.springframework.ide.eclipse.boot.dash.test.mocks.RunStateHistory; -import org.springframework.ide.eclipse.boot.dash.test.util.ZipDiff; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens; -import org.springframework.ide.eclipse.boot.dash.views.BootDashActions; -import org.springframework.ide.eclipse.boot.dash.views.CustmomizeTargetLabelAction; -import org.springframework.ide.eclipse.boot.dash.views.CustomizeTargetLabelDialogModel; -import org.springframework.ide.eclipse.boot.dash.views.ToggleBootDashModelConnection; -import org.springframework.ide.eclipse.boot.test.AutobuildingEnablement; -import org.springframework.ide.eclipse.boot.test.BootProjectTestHarness; -import org.springframework.ide.eclipse.boot.test.util.TestBracketter; -import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.RemoteAppData; -import org.springsource.ide.eclipse.commons.core.pstore.IPropertyStore; -import org.springsource.ide.eclipse.commons.core.pstore.PropertyStoreApi; -import org.springsource.ide.eclipse.commons.frameworks.core.util.ArrayEncoder; -import org.springsource.ide.eclipse.commons.frameworks.core.util.IOUtil; -import org.springsource.ide.eclipse.commons.frameworks.core.util.StringUtils; -import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; -import org.springsource.ide.eclipse.commons.livexp.core.ObservableSet; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; -import org.springsource.ide.eclipse.commons.livexp.core.ValueListener; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; -import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSet.Builder; -import com.google.gson.Gson; -import com.google.gson.JsonElement; - -/** - * @author Kris De Volder - */ -public class CloudFoundryBootDashModelMockingTest { - - private TestBootDashModelContext context; - private BootProjectTestHarness projects; - private MockCloudFoundryClientFactory clientFactory; - private CloudFoundryTestHarness harness; - private BootDashActions actions; - - //////////////////////////////////////////////////////////// - - public CloudFoundryApplicationHarness appHarness = new CloudFoundryApplicationHarness(null); - - @Rule - public AutobuildingEnablement disableAutoBuild = new AutobuildingEnablement(false); - - @Rule - public TestBracketter testBracketter = new TestBracketter(); - - private SpringBootCore springBootCore = SpringBootCore.getDefault(); - - @Before - public void setup() throws Exception { - System.out.println("java.version="+System.getProperty("java.version")); - StsTestUtil.deleteAllProjects(); - this.clientFactory = new MockCloudFoundryClientFactory(); - this.context = new TestBootDashModelContext( - ResourcesPlugin.getWorkspace(), - DebugPlugin.getDefault().getLaunchManager() - ).withCfClient(clientFactory); - this.harness = CloudFoundryTestHarness.create(context); - this.projects = new BootProjectTestHarness(context.getWorkspace()); - this.actions = new BootDashActions(harness.model, harness.selection.forReading(), harness.sectionSelection, context.injections, null); - } - - @After - public void tearDown() throws Exception { - waitForJobsToComplete(); - appHarness.dispose(); - clientFactory.assertOnlyImplementedStubsCalled(); - harness.dispose(); - } - - //////////////////////////////////////////////////////////// - - @Test - public void testCreateCfTarget() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_PASSWORD); - - assertNotNull(target); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(CFCredentialType.PASSWORD, credentials.getType()); - assertNotNull(credentials.getSecret()); - assertEquals(1, harness.getCfRunTargetModels().size()); - } - - @Test public void refreshTokenStreamTerminatedOnDispose() throws Exception { - CFClientParams params = CfTestTargetParams.fromEnv(); - clientFactory.defSpace(params.getOrgName(), params.getSpaceName()); - ClientRequests client = clientFactory.getClient(params); - - CountDownLatch latch = new CountDownLatch(1); - Future> tokens = runInJob(() -> { - return client.getRefreshTokens() - .doOnNext(token -> latch.countDown()) - .collect(Collectors.toList()).block(Duration.ofSeconds(10)); - }); - client.getApplicationsWithBasicInfo(); // forces the client to authenticate - latch.await(); //To avoid race condition (job tends to be slow and might start asking tokens only after disposed client (and this yields a empty stream of tokens) - client.dispose(); - assertEquals(ImmutableList.of(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN), tokens.get()); - } - - - @Test - public void testCreateCfTargetSsoAndStoreRefreshToken() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnvWithCredentials(CFCredentials.fromSsoToken(clientFactory.getSsoToken())); - { - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_TOKEN); - - assertNotNull(target); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(CFCredentialType.REFRESH_TOKEN, credentials.getType()); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, credentials.getSecret()); - assertEquals(1, harness.getCfRunTargetModels().size()); - } - harness.reload(); - - CloudFoundryBootDashModel target = harness.getCfTargetModel(); - assertNotNull(target); - - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(CFCredentialType.REFRESH_TOKEN, credentials.getType()); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, credentials.getSecret()); - assertEquals(StoreCredentialsMode.STORE_TOKEN, target.getRunTarget().getTargetProperties().getStoreCredentials()); - - waitForJobsToComplete(); - assertTrue(target.isConnected()); //should auto connect. - verifyZeroInteractions(ui()); //should not prompt for password (but used stored pass). - - { - SecuredCredentialsStore store = harness.getCredentialsStore(); - assertFalse(store.isUnlocked()); //not unlocked because token is stored in simple private file - } - - { - String storedCred = getStoredToken(target); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, storedCred); - } - - clientFactory.changeRefrestToken("another-1"); - clientFactory.changeRefrestToken("another-2"); - ACondition.waitFor("changed stored token", 300, () -> { - assertEquals("another-2", getStoredToken(target)); - }); - } - - private AllUserInteractions ui() { - return context.injections.getBean(AllUserInteractions.class); - } - - private String getStoredToken(CloudFoundryBootDashModel target) { - IPropertyStore store = harness.getPrivateStore(); - String key = harness.privateStoreKey(target); - String storedCred = store.get(key); - return storedCred; - } - - @Test - public void testCreateCfTargetSsoAndStoreNothing() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnvWithCredentials(CFCredentials.fromSsoToken(clientFactory.getSsoToken())); - { - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_NOTHING); - - assertNotNull(target); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(CFCredentialType.REFRESH_TOKEN, credentials.getType()); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, credentials.getSecret()); - assertEquals(1, harness.getCfRunTargetModels().size()); - } - harness.reload(); - - CloudFoundryBootDashModel target = harness.getCfTargetModel(); - assertNotNull(target); - - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertNull(credentials); - - waitForJobsToComplete(); - assertFalse(target.isConnected()); //should not auto connect. - verifyZeroInteractions(ui()); - - { - SecuredCredentialsStore store = harness.getCredentialsStore(); - assertFalse(store.isUnlocked()); //not unlocked because token is stored in simple private file - assertNull(store.getCredentials(harness.secureStoreKey(target))); - } - - { - IPropertyStore store = harness.getPrivateStore(); - String key = harness.privateStoreKey(target); - String storedCred = store.get(key); - assertNull(storedCred); - } - } - - @Test - public void testCreateCfTargetSsoAndStorePassword() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnvWithCredentials(CFCredentials.fromSsoToken(clientFactory.getSsoToken())); - { - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_PASSWORD, (wizard) -> { - assertContains("'Store Password' is useless for a 'Temporary Code'", wizard.getValidator().getValue().msg); - }); - //STORE_PASSWORD is meaningless for sso login and should be ignored (so behaves as STORE_NOTHING instead) - - assertNotNull(target); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(CFCredentialType.REFRESH_TOKEN, credentials.getType()); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, credentials.getSecret()); - assertEquals(1, harness.getCfRunTargetModels().size()); - } - harness.reload(); - - CloudFoundryBootDashModel target = harness.getCfTargetModel(); - assertNotNull(target); - - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertNull(credentials); - - waitForJobsToComplete(); - assertFalse(target.isConnected()); //should not auto connect. - verifyZeroInteractions(ui()); - - { - SecuredCredentialsStore store = harness.getCredentialsStore(); - assertFalse(store.isUnlocked()); //not unlocked because token is stored in simple private file - assertNull(store.getCredentials(harness.secureStoreKey(target))); - } - - { - IPropertyStore store = harness.getPrivateStore(); - String key = harness.privateStoreKey(target); - String storedCred = store.get(key); - assertNull(storedCred); - } - } - - @Test public void testCreateCfTargetAndStorePassword() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - { - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_PASSWORD); - - assertNotNull(target); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(CFCredentialType.PASSWORD, credentials.getType()); - assertNotNull(credentials.getSecret()); - assertEquals(1, harness.getCfRunTargetModels().size()); - - SecuredCredentialsStore store = harness.getCredentialsStore(); - assertTrue(store.isUnlocked()); - } - - harness.reload(); - { - CloudFoundryBootDashModel target = harness.getCfTargetModel(); - String expectedPass = targetParams.getCredentials().getSecret(); - - assertNotNull(target); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - String password = credentials.getSecret(); - assertEquals(CFCredentialType.PASSWORD, credentials.getType()); - assertEquals(expectedPass, password); - assertEquals(StoreCredentialsMode.STORE_PASSWORD, target.getRunTarget().getTargetProperties().getStoreCredentials()); - - waitForJobsToComplete(); - assertTrue(target.isConnected()); //should auto connect. - verifyZeroInteractions(ui()); //should not prompt for password (but used stored pass). - - { - SecuredCredentialsStore store = harness.getCredentialsStore(); - assertTrue(store.isUnlocked()); - String key = harness.secureStoreKey(target); - String storedCred = store.getCredentials(key); - assertEquals(expectedPass, storedCred); - } - - { - IPropertyStore store = harness.getPrivateStore(); - String key = harness.privateStoreKey(target); - String storedCred = store.get(key); - assertNull(storedCred); - } - } - } - - @Test public void testCreateCfTargetAndForgetPassword() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - { - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_NOTHING); - - assertNotNull(target); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(CFCredentialType.REFRESH_TOKEN, credentials.getType()); - assertNotNull(credentials.getSecret()); - assertEquals(1, harness.getCfRunTargetModels().size()); - - SecuredCredentialsStore store = harness.getCredentialsStore(); - assertFalse(store.isUnlocked()); // should not have gotten unlocked. - } - - harness.reload(); - - { - CloudFoundryBootDashModel target = harness.getCfTargetModel(); - - waitForJobsToComplete(); - - assertEquals(StoreCredentialsMode.STORE_NOTHING, target.getRunTarget().getTargetProperties().getStoreCredentials()); - assertNotNull(target); - assertNull(target.getRunTarget().getTargetProperties().getCredentials()); - assertFalse(target.isConnected()); // no auto connect if no creds are stored. - { //check secure store is clean - SecuredCredentialsStore store = harness.getCredentialsStore(); - assertFalse(store.isUnlocked()); // should not have gotten unlocked. - String storedCred = store.getCredentials(harness.secureStoreKey(target)); - assertNull(storedCred); - } - { //check private store is clean - IPropertyStore store = harness.getPrivateStore(); - String storedCred = store.get(harness.privateStoreKey(target)); - assertNull(storedCred); - } - - verifyZeroInteractions(ui()); - - //When we connect... the user should get prompted for password - harness.answerPasswordPrompt(ui(), (d) -> { - d.getMethodVar().setValue(targetParams.getCredentials().getType().toLoginMethod()); - d.getPasswordVar().setValue(targetParams.getCredentials().getSecret()); - d.validateCredentials().block(); - d.performOk(); - }); - - harness.sectionSelection.setValue(target); - IAction connectAction = toggleTargetConnectionAction(); - connectAction.run(); - - ACondition.waitFor("connected to target", 5_000, () -> { - assertTrue(target.isConnected()); - }); - - verify(ui()).openPasswordDialog(any()); - verifyNoMoreInteractions(ui()); - } - } - - @Test public void testCreateCfTargetAndStoreToken() throws Exception { - - { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - space.defApp("foo"); - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_TOKEN); - assertNotNull(target); - assertTrue(target.isConnected()); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(CFCredentialType.REFRESH_TOKEN, credentials.getType()); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, credentials.getSecret()); - assertEquals(1, harness.getCfRunTargetModels().size()); - } - - harness.reload(); - - { - CloudFoundryBootDashModel target = harness.getCfTargetModel(); - - { //secure store shouldn't have been accessed (i.e. avoid opening it and popping password) - SecuredCredentialsStore store = harness.getCredentialsStore(); - assertFalse(store.isUnlocked()); - String key = harness.secureStoreKey(target); - String storedCred = store.getCredentials(key); - assertNull(storedCred); - } - { - IPropertyStore store = harness.getPrivateStore(); - String key = harness.privateStoreKey(target); - String storedCred = store.get(key); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, storedCred); - } - - assertNotNull(target); - CFCredentials credentials = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, credentials.getSecret()); - assertEquals(CFCredentialType.REFRESH_TOKEN, credentials.getType()); - assertEquals(StoreCredentialsMode.STORE_TOKEN, target.getRunTarget().getTargetProperties().getStoreCredentials()); - - waitForJobsToComplete(); - assertTrue(target.isConnected()); //should auto connect. - verifyZeroInteractions(ui()); //should not prompt for password (but used stored token). - - clientFactory.changeRefrestToken("another-1"); - clientFactory.changeRefrestToken("another-2"); - ACondition.waitFor("changed stored token", 300, () -> { - assertEquals("another-2", getStoredToken(target)); - }); - } - } - - @Test - public void testAppsShownInBootDash() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - space.defApp("foo"); - space.defApp("bar"); - - final CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - - new ACondition("wait for apps to appear", 3000) { - @Override - public boolean test() throws Exception { - ImmutableSet appNames = getNames(target.getApplications().getValues()); - assertEquals(ImmutableSet.of("foo", "bar"), appNames); - return true; - } - }; - } - - @Test - public void testBasicRefreshApps() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - space.defApp("foo"); - space.defApp("bar"); - - final CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - - waitForApps(target, "foo", "bar"); - - space.defApp("anotherfoo"); - space.defApp("anotherbar"); - target.refresh(ui()); - - waitForApps(target, "foo", "bar", "anotherfoo", "anotherbar"); - } - - @Test - public void testRefreshAppsRunState() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - final MockCFApplication foo = space.defApp("foo"); - space.defApp("bar"); - - final CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - - waitForApps(target, "foo", "bar"); - - foo.start(CancelationTokens.NULL); - - target.refresh(ui()); - - new ACondition("wait for app states", 3000) { - @Override - public boolean test() throws Exception { - ImmutableSet appNames = getNames(target.getApplications().getValues()); - assertEquals(ImmutableSet.of("foo", "bar"), appNames); - CloudAppDashElement appElement = harness.getCfTargetModel().getApplication("foo"); - assertEquals(RunState.RUNNING, appElement.getRunState()); - - appElement = harness.getCfTargetModel().getApplication("bar"); - assertEquals(RunState.INACTIVE, appElement.getRunState()); - - return true; - } - }; - } - - @Test - public void testRefreshAppsHealthCheck() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - final MockCFApplication foo = space.defApp("foo"); - - - final CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - - waitForApps(target, "foo"); - - CloudAppDashElement appElement = harness.getCfTargetModel().getApplication("foo"); - assertEquals(HealthChecks.HC_PORT, appElement.getHealthCheck()); - - - foo.setHealthCheckType(HealthChecks.HC_PROCESS); - - target.refresh(ui()); - - new ACondition("wait for app health check", 3000) { - @Override - public boolean test() throws Exception { - ImmutableSet appNames = getNames(target.getApplications().getValues()); - assertEquals(ImmutableSet.of("foo"), appNames); - - CloudAppDashElement appElement = harness.getCfTargetModel().getApplication("foo"); - assertEquals(HealthChecks.HC_PROCESS, appElement.getHealthCheck()); - - return true; - } - }; - } - - @Test - public void testRefreshServices() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - space.defApp("foo"); - space.defService("elephantsql"); - space.defService("cleardb"); - - final CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - - waitForApps(target, "foo"); - waitForServices(target, "elephantsql", "cleardb"); - waitForElements(target, "foo", "elephantsql", "cleardb"); - - space.defService("rabbit"); - - target.refresh(ui()); - waitForServices(target, "elephantsql", "cleardb", "rabbit"); - waitForElements(target, "foo", "elephantsql", "cleardb", "rabbit"); - } - - @Test - public void testAppsAndServicesShownInBootDash() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - space.defApp("foo"); - space.defApp("bar"); - space.defService("a-sql"); - space.defService("z-rabbit"); - - final CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - assertTrue(target.isConnected()); - - debugListener("applications", target.getApplications()); - debugListener("services", target.getServices()); - debugListener("all", target.getElements()); - - new ACondition("wait for elements to appear", 3000) { - @Override - public boolean test() throws Exception { - ImmutableSet appNames = getNames(target.getApplications().getValues()); - ImmutableSet serviceNames = getNames(target.getServices().getValues()); - ImmutableSet allNames = getNames(target.getElements().getValues()); - assertEquals(ImmutableSet.of("foo", "bar"), appNames); - assertEquals(ImmutableSet.of("a-sql", "z-rabbit"), serviceNames); - assertEquals(ImmutableSet.of("foo", "bar", "a-sql", "z-rabbit"), allNames); - return true; - } - }; - - //Also test we sort this stuff in the right order. - - ArrayList elements = new ArrayList<>(target.getElements().getValues()); - Collections.sort(elements, target.getElementComparator()); - assertNames(elements, - //first apps... alphabetic - "bar", - "foo", - //then services... alphabetic - "a-sql", - "z-rabbit" - ); - - //For https://www.pivotaltracker.com/story/show/114408475 - // Apps and services should disappear when target is disconnected - - IAction toggleConnection = toggleTargetConnectionAction(); - harness.sectionSelection.setValue(target); - toggleConnection.run(); - - new ACondition("wait for elements to disappear", 10000) { - @Override - public boolean test() throws Exception { - assertFalse(target.isConnected()); - ImmutableSet appNames = getNames(target.getApplications().getValues()); - ImmutableSet serviceNames = getNames(target.getServices().getValues()); - ImmutableSet allNames = getNames(target.getElements().getValues()); - assertEquals(ImmutableSet.of(), appNames); - assertEquals(ImmutableSet.of(), serviceNames); - assertEquals(ImmutableSet.of(), allNames); - return true; - } - }; - } - - - @Test - public void testDeployActionsSorted() throws Exception { - //Generate some random 'space' names. - String orgName = "CloudRunAMock"; - String[] spaceNames = new String[6]; - for (int i = 0; i < spaceNames.length; i++) { - spaceNames[i] = RandomStringUtils.randomAlphabetic(10).toLowerCase(); - } - - //Define the spaces in the 'mock' cloud: - for (String spaceName : spaceNames) { - //Since this is just a mock client we creating, the params don't matter all that much at all. - clientFactory.defSpace(orgName, spaceName); - } - - //Create targets in the boot dash that connect to these spaces: - for (String spaceName : spaceNames) { - CFClientParams params = new CFClientParams( - "https://api.run.cloud.mock.com", - "some-user", CFCredentials.fromLogin(LoginMethod.PASSWORD, MockCloudFoundryClientFactory.FAKE_PASSWORD), - false, - orgName, - spaceName, - false - ); - harness.createCfTarget(params); - } - - { - ImmutableList deployActions = actions.getDebugOnTargetActions(); - assertEquals(spaceNames.length, deployActions.size()); - assertSorted(deployActions); - } - - { - ImmutableList deployActions = actions.getRunOnTargetActions(); - assertEquals(spaceNames.length, deployActions.size()); - assertSorted(deployActions); - } - - } - - @Test - public void targetTypeProperties() throws Exception { - { - CloudFoundryRunTargetType cfTargetType = harness.getCfTargetType(); - PropertyStoreApi props = cfTargetType.getPersistentProperties(); - props.put("testkey", "testvalue"); - assertEquals("testvalue", props.get("testkey")); - } - - harness.reload(); - - { - CloudFoundryRunTargetType cfTargetType = harness.getCfTargetType(); - PropertyStoreApi props = cfTargetType.getPersistentProperties(); - assertEquals("testvalue", props.get("testkey")); - } - - } - - @Test - public void appsManagerDefaultHost() throws Exception { - MockCFSpace space = clientFactory.defSpace("my-org", "foo"); - - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - CloudFoundryBootDashModel cfModel = harness.createCfTarget(new CFClientParams( - apiUrl, - username, CFCredentials.fromLogin(LoginMethod.PASSWORD, password), - false, - "my-org", - "foo", - false)); - - assertEquals("https://console.some-cloud.com", cfModel.getRunTarget().getAppsManagerHost()); - assertEquals("https://console.some-cloud.com", cfModel.getRunTarget().getAppsManagerHostDefault()); - - assertEquals("https://console.some-cloud.com/organizations/" + space.getOrganization().getGuid() + "/spaces/" + space.getGuid(), cfModel.getRunTarget().getAppsManagerURL()); - } - - @Test - public void appsManagerCustomizedHost() throws Exception { - MockCFSpace space = clientFactory.defSpace("my-org", "foo"); - - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - CloudFoundryBootDashModel cfModel = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "foo", false - )); - - cfModel.getRunTarget().setAppsManagerHost("https://totallyDifferentHost.com"); - - assertEquals("https://totallyDifferentHost.com", cfModel.getRunTarget().getAppsManagerHost()); - assertEquals("https://console.some-cloud.com", cfModel.getRunTarget().getAppsManagerHostDefault()); - - assertEquals("https://totallyDifferentHost.com/organizations/" + space.getOrganization().getGuid() + "/spaces/" + space.getGuid(), cfModel.getRunTarget().getAppsManagerURL()); - } - - @Test - public void templateDrivenTargetNames() throws Exception { - clientFactory.defSpace("my-org", "foo"); - clientFactory.defSpace("your-org", "bar"); - - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - AbstractBootDashModel fooSpace = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "foo", false)); - AbstractBootDashModel barSpace = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "your-org", "bar", false)); - - //check the default rendering is like it used to be before introducing templates. - assertEquals("my-org : foo - [https://api.some-cloud.com]", fooSpace.getDisplayName()); - assertEquals("your-org : bar - [https://api.some-cloud.com]", barSpace.getDisplayName()); - - RunTargetType targetType = fooSpace.getRunTarget().getType(); - - //Let's try switching the order of org and space - targetType.setNameTemplate("%s - %o @ %a"); - assertEquals("foo - my-org @ https://api.some-cloud.com", fooSpace.getDisplayName()); - assertEquals("bar - your-org @ https://api.some-cloud.com", barSpace.getDisplayName()); - - //Let's try adding 'username' into the label - targetType.setNameTemplate("%u@%s"); - assertEquals("freddy@foo", fooSpace.getDisplayName()); - assertEquals("freddy@bar", barSpace.getDisplayName()); - } - - @Test public void pushTcpRouteWithRandomPort() throws Exception { - String appName = "moriarty-app"; - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - MockCFSpace space = clientFactory.defSpace("my-org", "my-space"); - clientFactory.defDomain("tcp.domain.com", CFDomainType.TCP, CFDomainStatus.SHARED); - - assertEquals("cfmockapps.io", clientFactory.getDefaultDomain()); - - CloudFoundryBootDashModel target = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "my-space", false)); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - IFile manifest = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " random-route: true\n" + - " domain: tcp.domain.com\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 11.+}}'\n" - ); - harness.answerDeploymentPrompt(ui(), manifest); - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(target, appName); - CloudAppDashElement app = getApplication(target, project); - waitForState(app, RunState.RUNNING, 10_000); - - MockCFApplication deployedApp = space.getApplication(appName); - List uris = deployedApp.getBasicInfo().getUris(); - assertEquals(ImmutableList.of("tcp.domain.com:63000"), uris); - - doUnchangedAppRestartTest(app, deployedApp); - } - - @Test public void redeploy_app_and_enable_ssh_tunnel() throws Exception { - String appName = "tunneled-jmx-app"; - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - MockCFSpace space = clientFactory.defSpace("my-org", "my-space"); - CloudFoundryBootDashModel target = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "my-space", false)); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - String yaml = "applications:\n" + - "- name: "+appName+"\n"; - IFile manifest = createFile(project, "manifest.yml", yaml); - harness.answerDeploymentPrompt(ui(), new DeploymentAnswerer(yaml) { - @Override - public void apply(CloudApplicationDeploymentProperties properties) throws Exception { - properties.setManifestFile(manifest); - properties.setEnableJmxSshTunnel(false); - } - }); - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(target, appName); - CloudAppDashElement app = getApplication(target, project); - waitForState(app, RunState.RUNNING, 10_000); - assertFalse(app.getEnableJmxSshTunnel()); - - ACondition.waitFor("stop hammering", 20000, () -> { - app.stopAsync(); - assertEquals(RunState.INACTIVE, app.getRunState()); - }); - - //Now... redeploy and overwrite, cahning ssh enablement - reset(ui()); - harness.answerDeploymentPrompt(ui(), new DeploymentAnswerer(yaml) { - @Override - public void apply(CloudApplicationDeploymentProperties properties) throws Exception { - properties.setManifestFile(manifest); - properties.setEnableJmxSshTunnel(true); - } - }); - - Mockito.doReturn(ManifestDiffDialogModel.Result.USE_MANIFEST).when(ui()).confirmReplaceApp(any(), any(), any(), any()); - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - ACondition.waitFor("app restart", 20000, () -> { - assertEquals(RunState.RUNNING, app.getRunState()); - }); - JmxSshTunnelManager tunnels = harness.getJmxSshTunnelManager(); - ACondition.waitFor("sshtunnel creation", 2_000, () -> { - int jmxPort = app.getCfJmxPort(); - assertEquals( - ImmutableSet.of(remoteAppData(ImmutableMap.of( - "jmxurl", "service:jmx:rmi://localhost:"+jmxPort+"/jndi/rmi://localhost:"+jmxPort+"/jmxrmi", - "host", "tunneled-jmx-app.cfmockapps.io", - "keepChecking", false, - "processId", app.getAppGuid().toString() - ))), - tunnels.getUrls().getValues() - ); - }); - - ACondition.waitFor("stop hammering", 20000, () -> { - app.stopAsync(); - assertEquals(RunState.INACTIVE, app.getRunState()); - }); - ACondition.waitFor("tunnel closed", 2_000, () -> { - assertEquals(ImmutableSet.of(), tunnels.getUrls().getValues()); - }); - } - - @Test public void enable_jmx_after_deploy_decline_restart() throws Exception { - //See: https://www.pivotaltracker.com/story/show/159349926 - String appName = "tunneled-jmx-app"; - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - MockCFSpace space = clientFactory.defSpace("my-org", "my-space"); - CloudFoundryBootDashModel target = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "my-space", false)); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - String yaml = "applications:\n" + - "- name: "+appName+"\n"; - IFile manifest = createFile(project, "manifest.yml", yaml); - harness.answerDeploymentPrompt(ui(), new DeploymentAnswerer(yaml) { - @Override - public void apply(CloudApplicationDeploymentProperties properties) throws Exception { - properties.setManifestFile(manifest); - properties.setEnableJmxSshTunnel(false); - } - }); - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(target, appName); - CloudAppDashElement app = getApplication(target, project); - waitForState(app, RunState.RUNNING, 10_000); - assertFalse(app.getEnableJmxSshTunnel()); - - harness.selection.setElements(app); - EnableJmxSshTunnelAction toggleJmx = enableJmxSshTunnel(); - assertTrue(toggleJmx.isEnabled()); - assertTrue(toggleJmx.isVisible()); - assertEquals("Enable JMX Ssh Tunnelling", toggleJmx.getText()); - - harness.answerConfirmationMultipleChoice(ui(), (title, msg, choices, defaultIndex) -> { - assertEquals("Enabling JMX Requires Restart", title); - for (int i = 0; i < choices.length; i++) { - if (choices[i].startsWith("No")) { - return i; - } - } - throw new IllegalStateException("Didn't find expected choice"); - }); - - toggleJmx.run(); - assertTrue(app.getEnableJmxSshTunnel()); - - JmxSshTunnelManager tunnels = harness.getJmxSshTunnelManager(); - ACondition.expectAllways("sshtunnel creation", 2_000, () -> { - assertTrue(tunnels.getUrls().getValues().isEmpty()); - }); - - ACondition.waitFor("stop hammering", 2_000, () -> { - app.stopAsync(); - assertEquals(RunState.INACTIVE, app.getRunState()); - }); - } - - @Test public void enable_and_disable_jmx_after_deploy() throws Exception { - //See: https://www.pivotaltracker.com/story/show/159349926 - String appName = "tunneled-jmx-app"; - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - MockCFSpace space = clientFactory.defSpace("my-org", "my-space"); - CloudFoundryBootDashModel target = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "my-space", false)); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - String yaml = "applications:\n" + - "- name: "+appName+"\n"; - IFile manifest = createFile(project, "manifest.yml", yaml); - harness.answerDeploymentPrompt(ui(), new DeploymentAnswerer(yaml) { - @Override - public void apply(CloudApplicationDeploymentProperties properties) throws Exception { - properties.setEnableJmxSshTunnel(false); - properties.setManifestFile(manifest); - } - }); - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(target, appName); - CloudAppDashElement app = getApplication(target, project); - waitForState(app, RunState.RUNNING, 10_000); - assertFalse(app.getEnableJmxSshTunnel()); - - harness.selection.setElements(app); - EnableJmxSshTunnelAction toggleJmx = enableJmxSshTunnel(); - assertTrue(toggleJmx.isEnabled()); - assertTrue(toggleJmx.isVisible()); - assertEquals("Enable JMX Ssh Tunnelling", toggleJmx.getText()); - - harness.answerConfirmationMultipleChoice(ui(), (title, msg, choices, defaultIndex) -> { - assertEquals("Enabling JMX Requires Restart", title); - for (int i = 0; i < choices.length; i++) { - if (choices[i].startsWith("Yes")) { - return i; - } - } - throw new IllegalStateException("Didn't find expected choice"); - }); - - toggleJmx.run(); - assertTrue(app.getEnableJmxSshTunnel()); - - JmxSshTunnelManager tunnels = harness.getJmxSshTunnelManager(); - ACondition.waitFor("sshtunnel creation", 2_000, () -> { - int jmxPort = app.getCfJmxPort(); - assertEquals( - ImmutableSet.of(remoteAppData(ImmutableMap.of( - "jmxurl", "service:jmx:rmi://localhost:"+jmxPort+"/jndi/rmi://localhost:"+jmxPort+"/jmxrmi", - "host", "tunneled-jmx-app.cfmockapps.io", - "keepChecking", false, - "processId", app.getAppGuid().toString() - ))), - tunnels.getUrls().getValues() - ); - }); - - reset(ui()); - harness.answerConfirmationMultipleChoice(ui(), (title, msg, choices, defaultIndex) -> { - assertEquals("Disabling JMX Requires Restart", title); - for (int i = 0; i < choices.length; i++) { - if (choices[i].startsWith("Yes")) { - return i; - } - } - throw new IllegalStateException("Didn't find expected choice"); - }); - - assertTrue(toggleJmx.isEnabled()); - assertTrue(toggleJmx.isVisible()); - assertEquals("Disable JMX Ssh Tunnelling", toggleJmx.getText()); - - toggleJmx.run(); - assertFalse(app.getEnableJmxSshTunnel()); - - ACondition.waitFor("tunnel closed", 2_000, () -> { - assertEquals(ImmutableSet.of(), tunnels.getUrls().getValues()); - }); - ACondition.waitFor("app restarted", 2_000, () -> { - assertEquals(RunState.RUNNING, app.getRunState()); - }); - ACondition.expectAllways("sshtunnel creation", 2_000, () -> { - assertTrue(tunnels.getUrls().getValues().isEmpty()); - }); - - ACondition.waitFor("stop hammering", 2_000, () -> { - app.stopAsync(); - assertEquals(RunState.INACTIVE, app.getRunState()); - }); - } - - private RemoteAppData remoteAppData(ImmutableMap map) { - Gson gson = new Gson(); - JsonElement tree = gson.toJsonTree(map); - return gson.fromJson(tree, RemoteAppData.class); - } - - @Test public void deploy_app_with_jmx_ssh_tunnel_enabled() throws Exception { - String appName = "tunneled-jmx-app"; - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - MockCFSpace space = clientFactory.defSpace("my-org", "my-space"); - clientFactory.defDomain("tcp.domain.com", CFDomainType.TCP, CFDomainStatus.SHARED); - - CloudFoundryBootDashModel target = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "my-space", false)); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - final String yaml = "applications:\n" + - "- name: "+appName+"\n"; - IFile manifest = createFile(project, "manifest.yml", yaml); - harness.answerDeploymentPrompt(ui(), new DeploymentAnswerer(yaml) { - @Override - public void apply(CloudApplicationDeploymentProperties properties) throws Exception { - properties.setManifestFile(manifest); - properties.setEnableJmxSshTunnel(true); - } - }); - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(target, appName); - CloudAppDashElement app = getApplication(target, project); - waitForState(app, RunState.RUNNING, 10_000); - - assertTrue(app.getEnableJmxSshTunnel()); - JmxSshTunnelManager tunnels = harness.getJmxSshTunnelManager(); - ACondition.waitFor("sshtunnel creation", 2_000, () -> { - int jmxPort = app.getCfJmxPort(); - assertTrue(jmxPort>0); - assertEquals( - ImmutableSet.of(remoteAppData(ImmutableMap.of( - "jmxurl", "service:jmx:rmi://localhost:"+jmxPort+"/jndi/rmi://localhost:"+jmxPort+"/jmxrmi", - "host", "tunneled-jmx-app.cfmockapps.io", - "keepChecking", false, - "processId", app.getAppGuid().toString() - ))), - tunnels.getUrls().getValues() - ); - }); - - ACondition.waitFor("stop hammering", 20000, () -> { - app.stopAsync(); - assertEquals(RunState.INACTIVE, app.getRunState()); - }); - } - - @Test public void jmx_ssh_tunnel_created_on_eclipse_restart() throws Exception { - String appName = "tunneled-jmx-app"; - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - - { - MockCFSpace space = clientFactory.defSpace("my-org", "my-space"); - clientFactory.defDomain("tcp.domain.com", CFDomainType.TCP, CFDomainStatus.SHARED); - - CloudFoundryBootDashModel target = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "my-space", false)); - String yaml = "applications:\n" + - "- name: "+appName+"\n"; - IFile manifest = createFile(project, "manifest.yml", yaml); - harness.answerDeploymentPrompt(ui(), new DeploymentAnswerer(yaml) { - @Override - public void apply(CloudApplicationDeploymentProperties properties) throws Exception { - properties.setManifestFile(manifest); - properties.setEnableJmxSshTunnel(true); - } - }); - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(target, appName); - CloudAppDashElement app = getApplication(target, project); - waitForState(app, RunState.RUNNING, 10_000); - - assertTrue(app.getEnableJmxSshTunnel()); - int jmxPort = app.getCfJmxPort(); - JmxSshTunnelManager tunnels = harness.getJmxSshTunnelManager(); - ACondition.waitFor("sshtunnel creation", 2_000, () -> { - assertEquals( - ImmutableSet.of(remoteAppData(ImmutableMap.of( - "jmxurl", "service:jmx:rmi://localhost:"+jmxPort+"/jndi/rmi://localhost:"+jmxPort+"/jmxrmi", - "host", "tunneled-jmx-app.cfmockapps.io", - "keepChecking", false, - "processId", app.getAppGuid().toString() - ))), - tunnels.getUrls().getValues() - ); - }); - } - - harness.reload(); - - { - CloudFoundryBootDashModel target = harness.getCfTargetModel(); - waitForApps(target, appName); - CloudAppDashElement app = getApplication(target, project); - waitForState(app, RunState.RUNNING, 10_000); - - assertTrue(app.getEnableJmxSshTunnel()); - int jmxPort = app.getCfJmxPort(); - JmxSshTunnelManager tunnels = harness.getJmxSshTunnelManager(); - ACondition.waitFor("sshtunnel creation", 2_000, () -> { - assertEquals( - ImmutableSet.of(remoteAppData(ImmutableMap.of( - "jmxurl", "service:jmx:rmi://localhost:"+jmxPort+"/jndi/rmi://localhost:"+jmxPort+"/jmxrmi", - "host", "tunneled-jmx-app.cfmockapps.io", - "keepChecking", false, - "processId", app.getAppGuid().toString() - ))), - tunnels.getUrls().getValues() - ); - }); - } - - - } - - @Test public void deploy_app_with_jmx_ssh_tunnel_disabled() throws Exception { - String appName = "tunneled-jmx-app"; - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - MockCFSpace space = clientFactory.defSpace("my-org", "my-space"); - clientFactory.defDomain("tcp.domain.com", CFDomainType.TCP, CFDomainStatus.SHARED); - - CloudFoundryBootDashModel target = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "my-space", false)); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - IFile manifest = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" - ); - harness.answerDeploymentPrompt(ui(), manifest); //Note: don't need to disable explictly because its the default. - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(target, appName); - CloudAppDashElement app = getApplication(target, project); - waitForState(app, RunState.RUNNING, 10_000); - - assertFalse(app.getEnableJmxSshTunnel()); - assertEquals(-1, app.getCfJmxPort()); - } - - @Test public void pushTcpRouteWithFixedPort() throws Exception { - String appName = "moriarty-app"; - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - MockCFSpace space = clientFactory.defSpace("my-org", "my-space"); - clientFactory.defDomain("tcp.domain.com", CFDomainType.TCP, CFDomainStatus.SHARED); - - CloudFoundryBootDashModel target = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "my-space", false)); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - IFile manifest = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " routes: \n" + - " - route: tcp.domain.com:61001\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 11.+}}'\n" - ); - harness.answerDeploymentPrompt(ui(), manifest); - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(target, appName); - CloudAppDashElement app = getApplication(target, project); - waitForState(app, RunState.RUNNING, 10_000); - - MockCFApplication deployedApp = space.getApplication(appName); - List uris = deployedApp.getBasicInfo().getUris(); //Note: this info isn't retrieved via client! - assertEquals(ImmutableList.of("tcp.domain.com:61001"), uris); //Note: this info wasn't retrieved via client! Check if client info agrees - assertEquals(uris, target.getClient().getApplication(appName).getUris()); //Note: this info wasn't retrieved via client! Check if client info agrees - - doUnchangedAppRestartTest(app, deployedApp); - } - - @Test public void pushHttpRouteWithRandomRoute() throws Exception { - String appName = "moriarty-app"; - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - MockCFSpace space = clientFactory.defSpace("my-org", "my-space"); - clientFactory.defDomain("tcp.domain.com", CFDomainType.TCP, CFDomainStatus.SHARED); - - assertEquals("cfmockapps.io", clientFactory.getDefaultDomain()); - - CloudFoundryBootDashModel target = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "my-space", false)); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - IFile manifest = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " random-route: true\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 11.+}}'\n" - ); - harness.answerDeploymentPrompt(ui(), manifest); - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(target, appName); - CloudAppDashElement app = getApplication(target, project); - waitForState(app, RunState.RUNNING, 10_000); - - MockCFApplication deployedApp = space.getApplication(appName); - List uris = deployedApp.getBasicInfo().getUris(); - assertTrue(uris.size() == 1); - assertTrue(uris.get(0).length() > ".cfmockapps.io".length()); - assertTrue(uris.get(0).endsWith(".cfmockapps.io")); - - doUnchangedAppRestartTest(app, deployedApp); - } - - @Test - public void customizeTargetLabelAction() throws Exception { - clientFactory.defSpace("my-org", "foo"); - clientFactory.defSpace("your-org", "bar"); - - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - LocalBootDashModel local = harness.getLocalModel(); - AbstractBootDashModel fooSpace = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "foo", false)); - AbstractBootDashModel barSpace = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "your-org", "bar", false)); - CustmomizeTargetLabelAction action = actions.getCustomizeTargetLabelAction(); - - //////////// not applicable for local targets: - - harness.sectionSelection.setValue(local); - assertFalse(action.isEnabled()); - assertFalse(action.isVisible()); - - //////////// for cf targets ////////////////////////////////////////////////// - - harness.sectionSelection.setValue(fooSpace); - assertTrue(action.isEnabled()); - assertTrue(action.isVisible()); - - ModelStateListener modelStateListener = mock(ModelStateListener.class); - fooSpace.addModelStateListener(modelStateListener); - barSpace.addModelStateListener(modelStateListener); - - doAnswer(editSetTemplate("%s - %o @ %a")) - .when(ui()).openEditTemplateDialog(any(EditTemplateDialogModel.class)); - - action.run(); - - //Changing the template should result in modelStateListener firing on all the affected models - verify(modelStateListener).stateChanged(same(fooSpace)); - verify(modelStateListener).stateChanged(same(barSpace)); - - assertEquals("foo - my-org @ https://api.some-cloud.com", fooSpace.getDisplayName()); - assertEquals("bar - your-org @ https://api.some-cloud.com", barSpace.getDisplayName()); - - //Let's also try a user interaction that involves the 'Restore Defaults' button... - - reset(ui(), modelStateListener); - - doAnswer(restoreDefaultTemplate()) - .when(ui()).openEditTemplateDialog(any(EditTemplateDialogModel.class)); - - action.run(); - - verify(modelStateListener).stateChanged(same(fooSpace)); - verify(modelStateListener).stateChanged(same(barSpace)); - - assertEquals("my-org : foo - [https://api.some-cloud.com]", fooSpace.getDisplayName()); - assertEquals("your-org : bar - [https://api.some-cloud.com]", barSpace.getDisplayName()); - } - - @Test - public void customizeTargetLabelDialog() throws Exception { - EditTemplateDialogModel dialog; - clientFactory.defSpace("my-org", "foo"); - clientFactory.defSpace("your-org", "bar"); - - String apiUrl = "https://api.some-cloud.com"; - String username = "freddy"; String password = MockCloudFoundryClientFactory.FAKE_PASSWORD; - - AbstractBootDashModel fooSpace = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "my-org", "foo", false)); - AbstractBootDashModel barSpace = harness.createCfTarget(new CFClientParams(apiUrl, username, - CFCredentials.fromLogin(LoginMethod.PASSWORD, password), false, "your-org", "bar", false)); - - ModelStateListener modelStateListener = mock(ModelStateListener.class); - fooSpace.addModelStateListener(modelStateListener); - barSpace.addModelStateListener(modelStateListener); - - // Check initial state of the dialog when no custom labels have yet been set at all: - dialog = CustomizeTargetLabelDialogModel.create(fooSpace); - - assertTrue(dialog.applyToAll.getValue()); - assertEquals("%o : %s - [%a]", dialog.template.getValue()); - - //Check performOk only changes the one label when 'apply to all' is disabled. - dialog.applyToAll.setValue(false); - dialog.template.setValue("CHANGED %s -> %o"); - dialog.performOk(); - - assertEquals("CHANGED foo -> my-org", fooSpace.getDisplayName()); - assertEquals("your-org : bar - [https://api.some-cloud.com]", barSpace.getDisplayName()); - - verify(modelStateListener).stateChanged(same(fooSpace)); - verify(modelStateListener, never()).stateChanged(same(barSpace)); - - //Opening the dialog now should have 'apply to all' disabled to avoid accidentally overwriting - // existing individually customized labels... - dialog = CustomizeTargetLabelDialogModel.create(fooSpace); - assertFalse(dialog.applyToAll.getValue()); - assertEquals("CHANGED %s -> %o", dialog.template.getValue()); - - //Also if we open the dialog on the other element!!! - dialog = CustomizeTargetLabelDialogModel.create(barSpace); - assertFalse(dialog.applyToAll.getValue()); - assertEquals("%o : %s - [%a]", dialog.template.getValue()); - - //Selecting 'apply to all' should set the template on the type and erase custom templates on the - // individual targets. - dialog.applyToAll.setValue(true); - dialog.template.setValue("DIFFERENT %s -> %o"); - dialog.performOk(); - - assertEquals("DIFFERENT %s -> %o", harness.getCfTargetType().getNameTemplate()); - for (BootDashModel target : harness.getCfRunTargetModels()) { - assertFalse(target.hasCustomNameTemplate()); - assertEquals("DIFFERENT %s -> %o", target.getNameTemplate()); - } - - assertEquals("DIFFERENT foo -> my-org", fooSpace.getDisplayName()); - assertEquals("DIFFERENT bar -> your-org", barSpace.getDisplayName()); - } - - @Test - public void testPushWithHttpHealthCheckType() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - final CloudFoundryBootDashModel model = harness.getCfTargetModel(); - - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - final String appName = appHarness.randomAppName(); - - IFile manifest = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " health-check-type: http\n" + - " health-check-http-endpoint: /health\n" - ); - harness.answerDeploymentPrompt(ui(), manifest); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - ACondition.waitFor("wait for app '"+ appName +"'to be RUNNING", 30000, () -> { - CloudAppDashElement app = model.getApplication(appName); - assertEquals(RunState.RUNNING, app.getRunState()); - assertEquals("http", app.getHealthCheck()); - assertEquals("/health", app.getHealthCheckHttpEndpoint()); - }); - } - - @Test - public void testEnvVarsSetOnFirstDeploy() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - final CloudFoundryBootDashModel model = harness.getCfTargetModel(); - - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - final String appName = appHarness.randomAppName(); - - Map env = new HashMap<>(); - env.put("FOO", "something"); - harness.answerDeploymentPrompt(ui(), appName, appName, env); - - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - new ACondition("wait for app '"+ appName +"'to be RUNNING", 30000) { //why so long? JDT searching for main type. - public boolean test() throws Exception { - CloudAppDashElement element = model.getApplication(appName); - assertEquals(RunState.RUNNING, element.getRunState()); - return true; - } - }; - - Map actualEnv = harness.fetchEnvironment(target, appName); - - assertEquals("something", actualEnv.get("FOO")); - } - - @Test public void appToProjectBindingsPersisted() throws Exception { - final String appName = "foo"; - String projectName = "to-deploy"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - final IProject project = projects.createBootProject(projectName, withStarters("actuator", "web")); - - harness.createCfTarget(targetParams); - { - final CloudFoundryBootDashModel model = harness.getCfTargetModel(); - - deployApp(model, appName, project); - - CloudAppDashElement appByProject = getApplication(model, project); - CloudAppDashElement appByName = model.getApplication(appName); - assertNotNull(appByProject); - assertEquals(appByProject, appByName); - } - - harness.reload(); - { - final CloudFoundryBootDashModel model = harness.getCfTargetModel(); - waitForApps(model, appName); - CloudAppDashElement appByName = model.getApplication(appName); - CloudAppDashElement appByProject = getApplication(model, project); - assertNotNull(appByProject); - assertEquals(appByProject, appByName); - } - } - - @Test public void appToProjectBindingsPersistedAfterDisconnectConnect() throws Exception { - final String appName = "foo"; - String projectName = "to-deploy"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - final IProject project = projects.createBootProject(projectName, withStarters("actuator", "web")); - - final CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - deployApp(model, appName, project); - assertAppToProjectBinding(model, project, appName); - - IAction toggleConnectionAction = toggleTargetConnectionAction(); - harness.sectionSelection.setValue(model); - - toggleConnectionAction.run(); - waitForElements(model /*none*/); - toggleConnectionAction.run(); - waitForElements(model, appName); - - assertAppToProjectBinding(model, project, appName); - } - - @Test public void appToProjectBindingChangedAfterProjectRename() throws Exception { - final String appName = "foo"; - String projectName = "to-deploy"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - space.defApp(appName); - final IProject project = projects.createProject(projectName); - - final CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - waitForApps(target, appName); - CloudAppDashElement app = target.getApplication(appName); - app.setProject(project); - - assertAppToProjectBinding(target, project, appName); - - - ElementStateListener elementStateListener = mock(ElementStateListener.class); - target.addElementStateListener(elementStateListener); - - final IProject newProject = projects.rename(project, projectName+"-RENAMED"); - // resource listeners called synchronously by eclipse so we don't need ACondition - - assertAppToProjectBinding(target, newProject, appName); - - //state change event should have been fired (to update label of element in view) - verify(elementStateListener).stateChanged(same(app)); - } - - @Test public void appToProjectBindingForgottenAfterDelete() throws Exception { - final String appName = "foo"; - String projectName = "to-deploy"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - space.defApp(appName); - final IProject project = projects.createProject(projectName); - - final CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - waitForApps(target, appName); - CloudAppDashElement app = target.getApplication(appName); - app.setProject(project); - - assertAppToProjectBinding(target, project, appName); - - ElementStateListener elementStateListener = mock(ElementStateListener.class); - target.addElementStateListener(elementStateListener); - - project.delete(true, new NullProgressMonitor()); - - assertNull(app.getProject(true)); - verify(elementStateListener).stateChanged(same(app)); - } - - @Test public void runstateBecomesUnknownWhenStartOperationFails() throws Exception { - final String appName = "foo"; - String projectName = "to-deploy"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - MockCFApplication app = space.defApp(appName); - final IProject project = projects.createProject(projectName); - - final CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - waitForApps(target, appName); - CloudAppDashElement appElement = target.getApplication(appName); - appElement.setProject(project); - - //The state refressh is asynch so until state becomes 'INACTIVE' it will be unknown. - waitForState(appElement, RunState.INACTIVE, 3000); - IAction restartAction = restartOnlyApplicationAction(); - - RunStateHistory runstateHistory = new RunStateHistory(); - - appElement.getBaseRunStateExp().addListener(runstateHistory); - doThrow(IOException.class).when(app).start(any()); - - System.out.println("restarting application..."); - harness.selection.setElements(appElement); - restartAction.run(); - - waitForState(appElement, RunState.UNKNOWN, 3000); - - runstateHistory.assertHistoryContains( - RunState.INACTIVE, - RunState.STARTING - ); - runstateHistory.assertLast( - RunState.UNKNOWN - ); - } - - @Test public void refreshClearsErrorState() throws Exception { - final String appName = "foo"; - String projectName = "to-deploy"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - space.defApp(appName); - final IProject project = projects.createProject(projectName); - - final CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - waitForApps(target, appName); - CloudAppDashElement appElement = target.getApplication(appName); - appElement.setProject(project); - - waitForState(appElement, RunState.INACTIVE, 3000); - //The state refressh is asynch so until state becomes 'INACTIVE' it will be unknown. - appElement.setError(new IOException("Something bad happened")); - waitForState(appElement, RunState.UNKNOWN, 3000); - - target.refresh(ui()); - - waitForState(appElement, RunState.INACTIVE, 3000); - } - - @Test public void pushSimple() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - final String appName = appHarness.randomAppName(); - - harness.answerDeploymentPrompt(ui(), appName, appName); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(model, appName); - - CloudAppDashElement app = model.getApplication(appName); - - waitForState(app, RunState.RUNNING, 10000); - - assertEquals((Integer)1, space.getPushCount(appName).getValue()); - - MockCFApplication deployedApp = space.getApplication(appName); - doUnchangedAppRestartTest(app, deployedApp); - } - - @Test public void pushSimpleWithManifest() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - final String appName = appHarness.randomAppName(); - - String yaml = "applications:\n" + - "- name: "+appName+"\n" + - " memory: 512M\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 11.+}}'\n"; - IFile manifestFile = createFile(project, "manifest.yml", yaml); - - harness.answerDeploymentPrompt(ui(), manifestFile); - - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - waitForApps(model, appName); - - CloudAppDashElement app = model.getApplication(appName); - - waitForState(app, RunState.RUNNING, 10000); - - assertEquals((Integer)1, space.getPushCount(appName).getValue()); - assertEquals(manifestFile, app.getDeploymentManifestFile()); - assertEquals(512, (int) app.getMemory()); - - - MockCFApplication deployedApp = space.getApplication(appName); - CFApplication appInfo = deployedApp.getBasicInfo(); - List uris = appInfo.getUris(); - assertTrue(uris.size() == 1); - assertEquals(ImmutableList.of(appName+".cfmockapps.io"), uris); - - doUnchangedAppRestartTest(app, deployedApp); - } - - protected void doUnchangedAppRestartTest(CloudAppDashElement app, MockCFApplication deployedApp) throws Exception { - //Try to restart app. Nothing should change because we haven't changed the manifest - CFApplication appInfo = deployedApp.getBasicInfo(); - app.restart(RunState.RUNNING, ui()); - waitForJobsToComplete(); - waitForState(app, RunState.RUNNING, 10_000); - - CFApplication newAppInfo = deployedApp.getBasicInfo(); - assertSameAppState(appInfo, newAppInfo); - //If no change was detected the manifest compare dialog shouldn't have popped. - verify(ui(), never()).openManifestDiffDialog(any()); - } - - private void assertSameAppState(CFApplication appInfo, CFApplication newAppInfo) { - assertEquals(appInfoCompareString(appInfo), appInfoCompareString(newAppInfo)); - } - - private String appInfoCompareString(CFApplication app) { - StringBuilder buf = new StringBuilder(); - buf.append("name = " + app.getName()); - buf.append("instances = " + app.getInstances()); - buf.append("runningInstances = " + app.getRunningInstances()); - buf.append("memory = " + app.getMemory()); - buf.append("memory = " + app.getMemory()); - buf.append("guid = " + app.getGuid()); - buf.append("services = " + app.getServices()); - buf.append("buildpack = " + app.getBuildpackUrl()); - buf.append("uris = " + app.getUris()); - buf.append("state = " + app.getState()); - buf.append("diskQuota = " + app.getDiskQuota()); - buf.append("timeout = " + app.getTimeout()); - buf.append("command = " + app.getCommand()); - buf.append("stack = " + app.getStack()); - return buf.toString(); - } - - - @Test public void pushSimpleWithDefaultManualManifest() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - final String appName = project.getName(); - - harness.answerDeploymentPrompt(ui(), new DeploymentAnswerer()); - - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - waitForApps(model, appName); - - CloudAppDashElement app = model.getApplication(appName); - - waitForState(app, RunState.RUNNING, 10000); - - assertEquals((Integer)1, space.getPushCount(appName).getValue()); - assertNull(app.getDeploymentManifestFile()); - assertEquals(1024, (int) app.getMemory()); - assertEquals(appName, app.getName()); - - MockCFApplication deployedApp = space.getApplication(appName); - doUnchangedAppRestartTest(app, deployedApp); - } - - @Test public void warDeploy() throws Exception { - MavenSpringBootProject.DUMP_MAVEN_OUTPUT = true; - try { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - IProject project = projects.createBootProject("to-deploy-war", - withStarters("actuator", "web"), - withPackaging("war") - ); - assertEquals("war", springBootCore.project(project).getPackaging()); - - String appName = project.getName(); - harness.answerDeploymentPrompt(ui(), new DeploymentAnswerer()); - - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(model, appName); - - CloudAppDashElement app = model.getApplication(appName); - waitForState(app, RunState.RUNNING, 10000); - - assertEquals((Integer)1, space.getPushCount(appName).getValue()); - assertNull(app.getDeploymentManifestFile()); - assertEquals(1024, (int) app.getMemory()); - assertEquals(appName, app.getName()); - - File projectLocation = project.getLocation().toFile(); - File warFile = new File(projectLocation, "target/"+project.getName()+"-0.0.1-SNAPSHOT.war"); - assertTrue("war file not found: "+warFile, warFile.exists()); - assertDeployedBytes(warFile, space.getApplication(appName)); - } finally { - MavenSpringBootProject.DUMP_MAVEN_OUTPUT = false; - } - } - - @Test public void stopCancelsDeploy() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - - final String appName = appHarness.randomAppName(); - - clientFactory.setAppStartDelay(TimeUnit.MINUTES, 2); - harness.answerDeploymentPrompt(ui(), appName, appName); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(model, appName); - - CloudAppDashElement app = model.getApplication(appName); - - waitForState(app, RunState.STARTING, 3000); - - ACondition.waitFor("stop hammering", 20000, () -> { - app.stopAsync(); - assertEquals(RunState.INACTIVE, app.getRunState()); - }); - - //TODO: can we check that deployment related jobs are really canceled/finished somehow? - // can we check that they didn't pop errors? - } - - - - @Test public void stopCancelsStart() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - final String appName = "foo"; - space.defApp(appName); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForApps(model, appName); - CloudAppDashElement app = model.getApplication(appName); - app.setProject(project); - - waitForApps(model, appName); - - clientFactory.setAppStartDelay(TimeUnit.MINUTES, 2); - - app.getBaseRunStateExp().addListener(new ValueListener() { - @Override - public void gotValue(LiveExpression exp, RunState value) { - System.out.println("Runstate -> "+value); - } - }); - System.out.println("Restaring app..."); - app.restart(RunState.RUNNING, ui()); - waitForState(app, RunState.STARTING, 30000); - - System.out.println("Stopping app..."); - app.stopAsync(); - - waitForState(app, RunState.INACTIVE, 20000); - System.out.println("Stopped!"); - } - - @Test public void stopCancelsRestartOnly() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - IProject project = projects.createProject("to-deploy"); - final String appName = "foo"; - space.defApp(appName); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForApps(model, appName); - CloudAppDashElement app = model.getApplication(appName); - app.setProject(project); - - waitForApps(model, appName); - - clientFactory.setAppStartDelay(TimeUnit.MINUTES, 2); - app.restartOnlyAsynch(ui(), app.createCancelationToken()); - waitForState(app, RunState.STARTING, 3000); - - app.stopAsync(); - waitForState(app, RunState.INACTIVE, 20000); - } - - @Test public void acceptDeployOfExistingApp() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - IProject project = projects.createBootProject("to-deploy", withStarters("actuator", "web")); - final String appName = "foo"; - MockCFApplication deployedApp = space.defApp(appName); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForApps(model, appName); - CloudAppDashElement app = model.getApplication(appName); - app.setProject(null); - assertNull(app.getProject()); - waitForState(app, RunState.INACTIVE, 3000); - - harness.answerDeploymentPrompt(ui(), appName, appName); - Mockito.doReturn(ManifestDiffDialogModel.Result.USE_MANIFEST).when(ui()).confirmReplaceApp(any(), any(), any(), any()); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - System.out.println(app.getRunState()); - waitForJobsToComplete(); - System.out.println(app.getRunState()); - assertEquals(project, app.getProject()); - assertEquals(1, deployedApp.getPushCount()); - - verify(ui()).confirmReplaceApp(any(), any(), any(), any()); - } - - - @Test public void cancelDeployOfExistingApp() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - final String appName = "foo"; - MockCFApplication deployedApp = space.defApp(appName); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForApps(model, appName); - CloudAppDashElement app = model.getApplication(appName); - app.setProject(null); - assertNull(app.getProject()); - - harness.answerDeploymentPrompt(ui(), appName, appName); - doReturn(ManifestDiffDialogModel.Result.CANCELED).when(ui()).confirmReplaceApp(any(), any(), any(), any()); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - waitForJobsToComplete(); - assertNull(app.getProject()); // since op was canceled it should not have set the project on the app. - assertEquals(0, deployedApp.getPushCount()); // since op was canceled it should not have deployed the app. - - verify(ui()).confirmReplaceApp(any(), any(), any(), any()); - } - - @Test public void manifestDiffDialogNotShownWhenNothingChanged() throws Exception { - final String appName = "foo"; - - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - IFile manifest = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 11.+}}'\n" - ); - harness.answerDeploymentPrompt(ui(), manifest); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(model, appName); - CloudAppDashElement app = model.getApplication(appName); - waitForState(app, RunState.RUNNING, 10_000); - assertEquals(1, app.getActualInstances()); - -// deployedApp.scaleInstances(2); // change it 'externally' - assertEquals(1, app.getActualInstances()); //The model doesn't know yet that it has changed! - -// harness.answerDeploymentPrompt(ui(), appName, appName); - app.restart(RunState.RUNNING, ui()); - waitForJobsToComplete(); - - //If no change was detected the manifest compare dialog shouldn't have popped. - verify(ui(), never()).openManifestDiffDialog(any()); - } - - @Test public void manifestDiffDialogShownWhenInstancesChangedExternally() throws Exception { - final String appName = "foo"; - - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" - ); - - harness.answerManifestDiffDialog(ui(), (ManifestDiffDialogModel dialog) -> { - //??? code to check what's in the dialog??? - return ManifestDiffDialogModel.Result.CANCELED; - }); - - MockCFApplication deployedApp = space.defApp(appName); - deployedApp.start(CancelationTokens.NULL); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForApps(model, appName); - waitForJobsToComplete(); - - CloudAppDashElement app = model.getApplication(appName); - app.setDeploymentManifestFile(project.getFile("manifest.yml")); - app.setProject(project); - assertEquals(1, app.getActualInstances()); - - deployedApp.scaleInstances(2); // change it 'externally' - assertEquals(1, app.getActualInstances()); //The model doesn't know yet that it has changed! - - app.restart(RunState.RUNNING, ui()); - - waitForJobsToComplete(); - - //If the change was detected the deployment props dialog should have popped exactly once. - verify(ui()).openManifestDiffDialog(any()); - } - - @Test public void manifestDiffDialogChooseUseManfifest() throws Exception { - //Setup initial state for our test - final String appName = "foo"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - IFile manifest = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " memory: 1111M\n" - ); - - harness.answerDeploymentPrompt(ui(), manifest); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - waitForApps(model, appName); - CloudAppDashElement app = model.getApplication(appName); - waitForState(app, RunState.RUNNING, APP_DEPLOY_TIMEOUT); - - { - MockCFApplication appInCloud = space.getApplication(appName); - assertEquals(1111, appInCloud.getMemory()); - Mockito.reset(ui()); - - //// real test begins here - - appInCloud.setMemory(2222); - } - - harness.answerManifestDiffDialog(ui(), (ManifestDiffDialogModel dialog) -> { - //??? code to check what's in the dialog??? - return ManifestDiffDialogModel.Result.USE_MANIFEST; - }); - - app.restart(RunState.RUNNING, ui()); - - waitForJobsToComplete(); - { - MockCFApplication appInCloud = space.getApplication(appName); - assertEquals(2, appInCloud.getPushCount()); - assertEquals(RunState.RUNNING, app.getRunState()); - assertEquals(1111, appInCloud.getMemory()); - assertEquals(1111, (int)app.getMemory()); - } - } - - @Test public void manifestDiffDialogChooseForgetManfifest() throws Exception { - //Setup initial state for our test - final String appName = "foo"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - IProject project = projects.createBootProject("to-deploy", withStarters("web", "actuator")); - IFile manifest = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " memory: 1111M\n" - ); - - harness.answerDeploymentPrompt(ui(), manifest); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - waitForApps(model, appName); - CloudAppDashElement app = model.getApplication(appName); - waitForState(app, RunState.RUNNING, APP_DEPLOY_TIMEOUT); - - MockCFApplication appInCloud = space.getApplication(appName); - assertEquals(1111, appInCloud.getMemory()); - Mockito.reset(ui()); - - //// real test begins here - - appInCloud.setMemory(2222); - - harness.answerManifestDiffDialog(ui(), (ManifestDiffDialogModel dialog) -> { - //??? code to check what's in the dialog??? - return ManifestDiffDialogModel.Result.FORGET_MANIFEST; - }); - - app.restart(RunState.RUNNING, ui()); - - waitForJobsToComplete(); - - assertEquals(2, appInCloud.getPushCount()); - assertEquals(RunState.RUNNING, app.getRunState()); - assertEquals(2222, appInCloud.getMemory()); - assertEquals(2222, (int)app.getMemory()); - } - - @Test public void testDeployManifestWithAbsolutePathAttribute() throws Exception { - final String appName = "foo"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - IProject project = projects.createProject("to-deploy"); - - File zipFile = getTestZip("testapp"); - - IFile manifestFile = createFile(project, "manifest.yml", - "applications:\n" + - "- name: foo\n" + - " path: "+zipFile.getAbsolutePath() + "\n" + - " buildpack: staticfile_buildpack" - ); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - harness.answerDeploymentPrompt(ui(), manifestFile); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - waitForApps(model, "foo"); - - CloudAppDashElement app = model.getApplication("foo"); - waitForState(app, RunState.RUNNING, APP_DELETE_TIMEOUT); - - assertEquals(project, app.getProject()); - - assertEquals("some content here\n", space.getApplication(appName).getFileContents("test.txt")); - - verify(ui()).promptApplicationDeploymentProperties(any()); - verifyNoMoreInteractions(ui()); - } - - - @Test public void testDeployManifestWithRelativePathAttribute() throws Exception { - final String appName = "foo"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - IProject project = projects.createProject("to-deploy"); - - File zipFile = getTestZip("testapp"); - project.getFolder("zips").create(true, true, new NullProgressMonitor()); - project.getFolder("manifests").create(true, true, new NullProgressMonitor()); - createFile(project, "zips/testapp.zip", zipFile); - - IFile manifestFile = createFile(project, "manifests/manifest.yml", - "applications:\n" + - "- name: foo\n" + - " path: ../zips/testapp.zip\n" + - " buildpack: staticfile_buildpack" - ); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - harness.answerDeploymentPrompt(ui(), manifestFile); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - waitForApps(model, "foo"); - - CloudAppDashElement app = model.getApplication("foo"); - waitForState(app, RunState.RUNNING, APP_DEPLOY_TIMEOUT); - - assertEquals(project, app.getProject()); - - assertEquals("some content here\n", space.getApplication(appName).getFileContents("test.txt")); - - verify(ui()).promptApplicationDeploymentProperties(any()); - verifyNoMoreInteractions(ui()); - } - - @Test public void testDeployManifestWithoutPathAttribute() throws Exception { - String appName = "foo"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - IProject project = projects.createBootWebProject("empty-web-app"); - IFile manifestFile = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" - ); - File referenceJar = BootJarPackagingTest.packageAsJar(project, ui()); - - harness.answerDeploymentPrompt(ui(), manifestFile); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(model, appName); - - CloudAppDashElement app = model.getApplication(appName); - waitForState(app, RunState.RUNNING, APP_DEPLOY_TIMEOUT); - - System.out.println("platform location = '"+Platform.getLocation()+"'"); - assertDeployedBytes(referenceJar, space.getApplication(appName)); - } - - @Test public void testSelectManifestActionEnablement() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - IProject project1 = projects.createProject("pr1"); - IProject project2 = projects.createProject("pr2"); - - final String appName1 = "app1"; - final String appName2 = "app2"; - - MockCFApplication cfApp1 = space.defApp(appName1); - MockCFApplication cfApp2 = space.defApp(appName2); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForApps(model, appName1, appName2); - - CloudAppDashElement app1 = model.getApplication(appName1); - CloudAppDashElement app2 = model.getApplication(appName2); - - app1.setProject(project1); - app2.setProject(project2); - - IAction action = selectManifestAction(); - - assertTrue(harness.selection.getElements().isEmpty()); - assertFalse(action.isEnabled()); - - harness.selection.setElements(ImmutableSet.of(app1)); - assertNotNull(app1.getProject()); - assertTrue(action.isEnabled()); - - harness.selection.setElements(ImmutableSet.of(app1, app2)); - assertFalse(action.isEnabled()); - - app1.setProject(null); - harness.selection.setElements(ImmutableSet.of(app1)); - assertFalse(action.isEnabled()); - - harness.selection.setElements(ImmutableSet.of(app2)); - assertTrue(action.isEnabled()); - action.run(); - - } - - @Test public void testSelectManifestAction() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - IProject project = projects.createProject("pr"); - - final String appName = "app"; - - IFile manifestFile = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" - ); - - space.defApp(appName); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForApps(model, appName); - - CloudAppDashElement app = model.getApplication(appName); - app.setProject(project); - - harness.selection.setElements(ImmutableSet.of(app)); - - harness.answerDeploymentPrompt(ui(), manifestFile); - - assertNull(app.getDeploymentManifestFile()); - selectManifestAction().run(); - waitForJobsToComplete(); - assertEquals(manifestFile, app.getDeploymentManifestFile()); - - verify(ui()).promptApplicationDeploymentProperties(any()); - verifyNoMoreInteractions(ui()); - } - - @Test public void disconnectTarget() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - String appName = "someApp"; - space.defApp(appName); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForApps(model, appName); - assertEquals(1, clientFactory.instanceCount()); - - harness.sectionSelection.setValue(model); - IAction disconnectAction = toggleTargetConnectionAction(); - assertTrue(disconnectAction.isEnabled()); - disconnectAction.run(); - waitForApps(model); - assertFalse(model.isConnected()); - waitForModelReady(model); - assertEquals(0, clientFactory.instanceCount()); - } - - @Test public void updateTargetPasswordInvalid() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - String appName = "someApp"; - space.defApp(appName); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - waitForApps(model, appName); - - harness.sectionSelection.setValue(model); - IAction updatePassword = updatePasswordAction(); - assertTrue(updatePassword.isEnabled()); - - harness.answerPasswordPrompt(ui(), (d) -> { - d.getPasswordVar().setValue(targetParams.getCredentials().getSecret()); - d.validateCredentials().block(); - d.performOk(); - }); - - updatePassword.run(); - - waitForJobsToComplete(); - - assertNotNull(model.getApplication(appName)); - assertTrue(model.isConnected()); - waitForModelReady(model); - - // Clear out any mocks on the ui object set above - reset(ui()); - - CompletableFuture passwordValidation = new CompletableFuture<>(); - - harness.answerPasswordPrompt(ui(), (d) -> { - d.getPasswordVar().setValue("wrong password"); - ReactorUtils.completeWith(passwordValidation, d.validateCredentials()); - //d.performOk(); //shouldn't perform ok because we are expecting passwordValidation to fail - }); - - updatePassword.run(); - - ValidationResult validationResult = passwordValidation.get(); - assertEquals(IStatus.ERROR, validationResult.status); - assertContains("Invalid credentials", validationResult.msg); - - } - - @Test public void pushWithHealthCheckProcess() throws Exception { - doPushWithHealthCheckType("process", "process"); - } - - @Test public void pushWithHealthCheckDefault() throws Exception { - doPushWithHealthCheckType(null, "port"); - } - - @Test public void pushWithHealthCheckPort() throws Exception { - doPushWithHealthCheckType("port", "port"); - } - - private void doPushWithHealthCheckType(String specified, String expected) throws Exception { - String appName = "someApp"; - final IProject project = projects.createBootProject(appName, withStarters("actuator", "web")); - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - - final String yaml = "applications:\n" + - "- name: "+appName+"\n" + - (specified==null?"":" health-check-type: "+specified+"\n"); - - harness.answerDeploymentPrompt(ui(), new DeploymentAnswerer(yaml)); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(model, appName); - waitForState(model.getApplication(appName), RunState.RUNNING, 4000); - waitForJobsToComplete(); - - assertEquals(expected,space.getApplication(appName).getHealthCheckType()); - ACondition.waitFor("hcType in model", 3000, () -> { - assertEquals(expected, model.getApplication(appName).getHealthCheck()); - }); - - MockCFApplication deployedApp = space.getApplication(appName); - doUnchangedAppRestartTest(model.getApplication(appName), deployedApp); - } - - @Test public void updateTargetSsoAndStoreNothing() throws Exception { - String appName = "someApp"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - space.defApp(appName); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_TOKEN); - waitForApps(model, appName); - - harness.sectionSelection.setValue(model); - IAction updatePassword = updatePasswordAction(); - assertTrue(updatePassword.isEnabled()); - - // Clear out any mocks on the ui object - reset(ui()); - - String newToken=clientFactory.getSsoToken(); - harness.answerPasswordPrompt(ui(), (d) -> { - d.getMethodVar().setValue(LoginMethod.TEMPORARY_CODE); - d.getPasswordVar().setValue(newToken); - d.getStoreVar().setValue(StoreCredentialsMode.STORE_NOTHING); - d.validateCredentials().block(); - d.performOk(); - }); - - updatePassword.run(); - - waitForJobsToComplete(); - - assertTrue(model.isConnected()); - assertNotNull(model.getApplication(appName)); - waitForModelReady(model); - - { - assertNull(harness.getCredentialsStore().getCredentials(harness.secureStoreKey(model))); - assertNull(harness.getPrivateStore().get(harness.privateStoreKey(model))); - } - - toggleTargetConnectionAction().run(); - - waitForJobsToComplete(); - assertFalse(model.isConnected()); - - // Clear out any mocks on the ui object to get the right count below - reset(ui()); - - toggleTargetConnectionAction().run(); - waitForJobsToComplete(); - - assertTrue(model.isConnected()); - waitForModelReady(model); - waitForApps(model, appName); - - verifyNoMoreInteractions(ui()); - } - - @Test public void updateTargetSsoAndStorePassword() throws Exception { - // In real PWS this scenario would use a 'single use' password that can be obtained - // from https://login.run.pivotal.io/passcode - String appName = "someApp"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - space.defApp(appName); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_TOKEN); - waitForApps(model, appName); - - harness.sectionSelection.setValue(model); - IAction updatePassword = updatePasswordAction(); - assertTrue(updatePassword.isEnabled()); - - // Clear out any mocks on the ui object - reset(ui()); - - LiveVariable capturedStoreValidator = new LiveVariable<>(null); - - String newToken=clientFactory.getSsoToken(); - harness.answerPasswordPrompt(ui(), (d) -> { - d.getMethodVar().setValue(LoginMethod.TEMPORARY_CODE); - d.getPasswordVar().setValue(newToken); - d.getStoreVar().setValue(StoreCredentialsMode.STORE_PASSWORD); - capturedStoreValidator.setValue(d.getStoreValidator().getValue()); - d.validateCredentials().block(); - d.performOk(); - }); - - updatePassword.run(); - - waitForJobsToComplete(); - - assertContains("'Store Password' is useless for a 'Temporary Code'", capturedStoreValidator.getValue().msg); - - assertTrue(model.isConnected()); - assertNotNull(model.getApplication(appName)); - waitForModelReady(model); - //store password is ignored and treated as 'STORE_NOTHING' - assertEquals(StoreCredentialsMode.STORE_NOTHING, model.getRunTarget().getTargetProperties().getStoreCredentials()); - { - assertNull(harness.getCredentialsStore().getCredentials(harness.secureStoreKey(model))); - assertNull(harness.getPrivateStore().get(harness.privateStoreKey(model))); - } - - toggleTargetConnectionAction().run(); - - waitForJobsToComplete(); - assertFalse(model.isConnected()); - - // Clear out any mocks on the ui object to get the right count below - reset(ui()); - - toggleTargetConnectionAction().run(); - waitForJobsToComplete(); - - assertTrue(model.isConnected()); - waitForModelReady(model); - waitForApps(model, appName); - - verifyNoMoreInteractions(ui()); - } - - @Test public void updateTargetSsoAndStoreToken() throws Exception { - String appName = "someApp"; - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - space.defApp(appName); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams, StoreCredentialsMode.STORE_PASSWORD); - waitForApps(model, appName); - - harness.sectionSelection.setValue(model); - IAction updatePassword = updatePasswordAction(); - assertTrue(updatePassword.isEnabled()); - - // Clear out any mocks on the ui object - reset(ui()); - - String newToken=clientFactory.getSsoToken(); - harness.answerPasswordPrompt(ui(), (d) -> { - d.getMethodVar().setValue(LoginMethod.TEMPORARY_CODE); - d.getPasswordVar().setValue(newToken); - d.getStoreVar().setValue(StoreCredentialsMode.STORE_TOKEN); - d.validateCredentials().block(); - d.performOk(); - }); - - updatePassword.run(); - - waitForJobsToComplete(); - - assertTrue(model.isConnected()); - assertNotNull(model.getApplication(appName)); - waitForModelReady(model); - - assertEquals(StoreCredentialsMode.STORE_TOKEN, model.getRunTarget().getTargetProperties().getStoreCredentials()); - { - assertNull(harness.getCredentialsStore().getCredentials(harness.secureStoreKey(model))); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, harness.getPrivateStore().get(harness.privateStoreKey(model))); - } - - toggleTargetConnectionAction().run(); - - waitForJobsToComplete(); - assertFalse(model.isConnected()); - - // Clear out any mocks on the ui object to get the right count below - reset(ui()); - - toggleTargetConnectionAction().run(); - waitForJobsToComplete(); - - assertTrue(model.isConnected()); - waitForModelReady(model); - assertNotNull(model.getApplication(appName)); - - verifyZeroInteractions(ui()); //should have used stored token so no pw dialog! - } - - @Test public void updateTargetPasswordAndStoreNothing() throws Exception { - /* - -store.put(new Key(element, key), value); - - key = from constant org.springframework.ide.eclipse.boot.dash.model.RunTargetPropertiesManager.RUN_TARGET_KEY - element = CloudFoundrryRuntargetTupe instance - value = array (vai ArrayEncoder of serialed CloudRuntargetProperties for example: - - { - "storeCredentials":"STORE_PASSWORD", - "runTargetID":"kdevolder@gopivotal.com : https://api.run.pivotal.io : application-platform-testing : sts-20200309-kdvolder-xbctakulkwcy", - "selfsigned":"false","organization":"application-platform-testing", - "skipSslValidation":"false", - "organization_guid":"7508f3b4-ec6f-459a-b1e1-e209f72f6fe3", - "space_guid":"97124746-5c09-4e23-adda-7ed43410c0d4", - "url":"https://api.run.pivotal.io", - "space":"sts-20200309-kdvolder-xbctakulkwcy", - "username":"kdevolder@gopivotal.com" - }; - - */ - - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - String appName = "someApp"; - space.defApp(appName); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForApps(model, appName); - - assertStoredStoreMode(StoreCredentialsMode.STORE_PASSWORD, model); - - harness.sectionSelection.setValue(model); - IAction updatePassword = updatePasswordAction(); - assertTrue(updatePassword.isEnabled()); - - // Clear out any mocks on the ui object - reset(ui()); - - harness.answerPasswordPrompt(ui(), (d) -> { - d.getPasswordVar().setValue(targetParams.getCredentials().getSecret()); - d.getStoreVar().setValue(StoreCredentialsMode.STORE_NOTHING); - d.validateCredentials().block(); - d.performOk(); - }); - - updatePassword.run(); - - waitForJobsToComplete(); - - - assertTrue(model.isConnected()); - assertNotNull(model.getApplication(appName)); - waitForModelReady(model); - - { - assertStoredStoreMode(StoreCredentialsMode.STORE_NOTHING, model); - assertNull(harness.getCredentialsStore().getCredentials(harness.secureStoreKey(model))); - assertNull(harness.getPrivateStore().get(harness.privateStoreKey(model))); - } - - toggleTargetConnectionAction().run(); - - waitForJobsToComplete(); - assertFalse(model.isConnected()); - - // Clear out any mocks on the ui object to get the right count below - reset(ui()); - - toggleTargetConnectionAction().run(); - waitForJobsToComplete(); - - assertTrue(model.isConnected()); - waitForModelReady(model); - assertNotNull(model.getApplication(appName)); - - verifyNoMoreInteractions(ui()); - } - - private void assertStoredStoreMode(StoreCredentialsMode expectedStoreMode, CloudFoundryBootDashModel model) { - CloudFoundryRunTargetType cfType = model.getRunTarget().getType(); - String[] runTargetsJson = ArrayEncoder.decode(harness.context.getRunTargetProperties().get(cfType, RunTargetPropertiesManager.RUN_TARGET_KEY)); - assertEquals(1, runTargetsJson.length); - CloudFoundryTargetProperties storedParams = cfType.parseParams(runTargetsJson[0]); - assertEquals(expectedStoreMode, storedParams.getStoreCredentials()); - } - - @Test public void updateTargetPasswordAndStorePassword() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - String appName = "someApp"; - space.defApp(appName); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - waitForApps(model, appName); - - harness.sectionSelection.setValue(model); - IAction updatePassword = updatePasswordAction(); - assertTrue(updatePassword.isEnabled()); - - // Clear out any mocks on the ui object - reset(ui()); - - harness.answerPasswordPrompt(ui(), (d) -> { - d.getPasswordVar().setValue(targetParams.getCredentials().getSecret()); - d.getStoreVar().setValue(StoreCredentialsMode.STORE_PASSWORD); - d.validateCredentials().block(); - d.performOk(); - }); - - updatePassword.run(); - - waitForJobsToComplete(); - - toggleTargetConnectionAction().run(); - - waitForJobsToComplete(); - assertFalse(model.isConnected()); - - // Clear out any mocks on the ui object to get the right count below - reset(ui()); - - toggleTargetConnectionAction().run(); - waitForJobsToComplete(); - - assertTrue(model.isConnected()); - waitForModelReady(model); - assertNotNull(model.getApplication(appName)); - - verifyNoMoreInteractions(ui()); - } - - @Test public void updateTargetPasswordAndStoreToken() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - String appName = "someApp"; - space.defApp(appName); - CloudFoundryBootDashModel target = harness.createCfTarget(targetParams); - waitForApps(target, appName); - - harness.sectionSelection.setValue(target); - IAction updatePassword = updatePasswordAction(); - assertTrue(updatePassword.isEnabled()); - - // Clear out any mocks on the ui object - reset(ui()); - - harness.answerPasswordPrompt(ui(), (d) -> { - d.getPasswordVar().setValue(targetParams.getCredentials().getSecret()); - d.getStoreVar().setValue(StoreCredentialsMode.STORE_TOKEN); - d.validateCredentials().block(); - d.performOk(); - }); - - updatePassword.run(); - waitForJobsToComplete(); - assertTrue(target.isConnected()); - assertEquals(1, target.activeRefreshTokenListeners.get()); - - toggleTargetConnectionAction().run(); //disconnect - - waitForJobsToComplete(); - assertFalse(target.isConnected()); - assertEquals(0, target.activeRefreshTokenListeners.get()); - - // Clear out any mocks on the ui object to get the right count below - reset(ui()); - - toggleTargetConnectionAction().run(); - waitForJobsToComplete(); - - assertTrue(target.isConnected()); - CFCredentials creds = target.getRunTarget().getTargetProperties().getCredentials(); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, creds.getSecret()); - assertEquals(CFCredentialType.REFRESH_TOKEN, creds.getType()); - assertEquals(MockCloudFoundryClientFactory.FAKE_REFRESH_TOKEN, harness.getPrivateStore().get(harness.privateStoreKey(target))); - assertNull(harness.getCredentialsStore().getCredentials(harness.secureStoreKey(target))); - assertEquals(RefreshState.READY, target.getRefreshState()); - assertNotNull(target.getApplication(appName)); - - verifyNoMoreInteractions(ui()); - - clientFactory.changeRefrestToken("another-1"); - clientFactory.changeRefrestToken("another-2"); - ACondition.waitFor("changed stored token", 300, () -> { - assertEquals("another-2", getStoredToken(target)); - }); - } - - @Test public void apiVersionCheck() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - - clientFactory.setApiVersion("1.1.0"); - clientFactory.setSupportedApiVersion("1.1.1"); - - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - ACondition.waitFor("connected to target", 10_000, () -> model.isConnected()); - - waitForJobsToComplete(); - - assertTrue(model.getRefreshState().isWarning()); - String msg = model.getRefreshState().getMessage(); - assertContains("may not work as expected", msg); - assertContains("1.1.1", msg); - assertContains("1.1.0", msg); - } - - @Test public void clientDisposedWhenTargetRemoved() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - space.defApp("bonkers"); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - ACondition.waitFor("connected to target", 10_000, () -> { - assertTrue(model.isConnected()); - assertEquals(RefreshState.READY, model.getRefreshState()); - }); - waitForApps(model, "bonkers"); - - assertEquals(1, clientFactory.instanceCount()); - - harness.sectionSelection.setValue(model); - when(ui().confirmOperation(contains("Deleting"), any())) - .thenReturn(true); - actions.getRemoveRunTargetAction().run(); - - ACondition.waitFor("target removed", 10_000, () -> { - harness.model.getSectionModels().getValue().isEmpty(); - }); - assertEquals(0, clientFactory.instanceCount()); - } - - @Test public void oldClientDisposedWhenClientCredentialsUpdated() throws Exception { - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - MockCFSpace space = clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - space.defApp("bonkers"); - CloudFoundryBootDashModel model = harness.createCfTarget(targetParams); - ACondition.waitFor("connected to target", 10_000, () -> { - assertTrue(model.isConnected()); - assertEquals(RefreshState.READY, model.getRefreshState()); - }); - waitForApps(model, "bonkers"); - assertEquals(1, clientFactory.instanceCount()); - - clientFactory.setPassword("something-else"); - - harness.sectionSelection.setValue(model); - harness.answerPasswordPrompt(ui(), (PasswordDialogModel passwordDialog) -> { - passwordDialog.getPasswordVar().setValue("something-else"); - assertEquals(ValidationResult.OK, passwordDialog.validateCredentials().block()); - passwordDialog.performOk(); - }); - harness.sectionSelection.setValue(model); - UpdatePasswordAction updatePW = updatePasswordAction(); - updatePW.run(); - updatePW.waitFor(); - - ACondition.waitFor("connected to target", 10_000, () -> { - assertTrue(model.isConnected()); - assertEquals(RefreshState.READY, model.getRefreshState()); - }); - assertEquals(1, clientFactory.instanceCount()); - } - - @Test public void openAppWithPathInBrowser() throws Exception { - final String appName = "to-deploy"; - final String appPath = "/the-path"; - String projectName = "to-deploy"; - final String host = "foo-host"; - - CFClientParams targetParams = CfTestTargetParams.fromEnv(); - clientFactory.defSpace(targetParams.getOrgName(), targetParams.getSpaceName()); - final IProject project = projects.createBootProject(projectName, withStarters("actuator", "web")); - harness.createCfTarget(targetParams); - final CloudFoundryBootDashModel target = harness.getCfTargetModel(); - IFile manifest = createFile(project, "manifest.yml", - "applications:\n" + - "- name: "+appName+"\n" + - " routes:\n" + - " - route: "+host+".cfmockapps.io"+appPath - ); - harness.answerDeploymentPrompt(ui(), manifest); - target.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - waitForApps(target, appName); - - CloudAppDashElement app = target.getApplication(appName); - ACondition.waitFor("uri update", 5_000, () -> { - assertEquals("foo-host.cfmockapps.io", app.getLiveHost()); - assertEquals("https://foo-host.cfmockapps.io/the-path", app.getUrl()); - }); - - app.setDefaultRequestMappingPath("/hello"); - ACondition.waitFor("uri update", 5_000, () -> { - assertEquals("foo-host.cfmockapps.io", app.getLiveHost()); - assertEquals("https://foo-host.cfmockapps.io/the-path/hello", app.getUrl()); - }); - - app.setDefaultRequestMappingPath("/"); - ACondition.waitFor("uri update", 5_000, () -> { - assertEquals("foo-host.cfmockapps.io", app.getLiveHost()); - assertEquals("https://foo-host.cfmockapps.io/the-path/", app.getUrl()); - }); - - app.setDefaultRequestMappingPath("hello"); - ACondition.waitFor("uri update", 5_000, () -> { - assertEquals("foo-host.cfmockapps.io", app.getLiveHost()); - assertEquals("https://foo-host.cfmockapps.io/the-path/hello", app.getUrl()); - }); - - app.setDefaultRequestMappingPath(""); - ACondition.waitFor("uri update", 5_000, () -> { - assertEquals("foo-host.cfmockapps.io", app.getLiveHost()); - assertEquals("https://foo-host.cfmockapps.io/the-path", app.getUrl()); - }); - - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - - //Stuff below is 'cruft' intended to make the tests above more readable. Maybe this code could be - // moved to some kind of 'harness' (if there is a case where it can be reused). - - private void assertDeployedBytes(File referenceJar, MockCFApplication app) throws IOException { - try (InputStream actualBits = app.getBits()) { - try (InputStream expectedBits = new BufferedInputStream(new FileInputStream(referenceJar))) { - ZipDiff zipDiff = new ZipDiff(expectedBits); - try { - zipDiff.assertEqual(actualBits); - } catch (Throwable e) { - System.out.println("Failed: "+ExceptionUtil.getMessage(e)); - saveArtefacts(referenceJar, app); - throw e; - } - } - } - } - - private void saveArtefacts(File referenceJar, MockCFApplication app) throws IOException { - System.out.println("Trying to save jars..."); - File targetDir = getSaveDir(); - System.out.println("targetDir = "+targetDir); - if (targetDir!=null) { - int id = uniqueId++; - File referenceJarCopy = new File(targetDir, "deployed-reference-"+id+".jar"); - File faultyJarCopy = new File(targetDir, "deployed-faulty-"+id+".jar"); - FileUtils.copyFile(referenceJar, referenceJarCopy); - System.out.println("Reference jar saved: "+referenceJarCopy); - IOUtil.pipe(app.getBits(), faultyJarCopy); - System.out.println("Faulty jar saved: "+faultyJarCopy); - } - } - - private static int uniqueId = 0; - - private File getSaveDir() { - IPath targetDirPath = Platform.getLocation(); - while (targetDirPath.segmentCount()>0 && !targetDirPath.lastSegment().equals("target")) { - targetDirPath = targetDirPath.removeLastSegments(1); - } - if (targetDirPath.segmentCount()>0) { - return targetDirPath.toFile(); - } - return new File(System.getProperty("user.home")); - } - - private File getTestZip(String fileName) { - File sourceWorkspace = new File( - StsTestUtil.getSourceWorkspacePath("org.springframework.ide.eclipse.boot.dash.test")); - File file = new File(sourceWorkspace, fileName + ".zip"); - Assert.isTrue(file.exists(), ""+ file); - return file; - } - - private void assertAppToProjectBinding(CloudFoundryBootDashModel target, IProject project, String appName) throws Exception { - CloudAppDashElement appByProject = getApplication(target, project); - CloudAppDashElement appByName = target.getApplication(appName); - assertNotNull(appByProject); - assertEquals(appByProject, appByName); - } - - private CloudAppDashElement getApplication(CloudFoundryBootDashModel model, IProject project) { - for (CloudAppDashElement app : model.getApplicationValues()) { - IProject p = app.getProject(); - if (project.equals(p)) { - return app; - } - } - return null; - } - - protected CloudAppDashElement deployApp(final CloudFoundryBootDashModel model, final String appName, IProject project) - throws Exception { - harness.answerDeploymentPrompt(ui(), appName, appName); - model.performDeployment(ImmutableSet.of(project), RunState.RUNNING); - - waitForApps(model, appName); - - new ACondition("wait for app '"+ appName +"'to be RUNNING", 30000) { //why so long? JDT searching for main type. - public boolean test() throws Exception { - CloudAppDashElement element = model.getApplication(appName); - assertEquals(RunState.RUNNING, element.getRunState()); - return true; - } - }; - return model.getApplication(appName); - } - - protected void waitForModelReady(CloudFoundryBootDashModel model) throws Exception { - ACondition.waitFor("Ready refresh state", 2_000, () -> { - assertEquals(RefreshState.READY, model.getRefreshState()); - }); - } - - protected void waitForApps(final CloudFoundryBootDashModel target, final String... names) throws Exception { - new ACondition("wait for apps to appear", 120_000) { - @Override - public boolean test() throws Exception { - ImmutableSet appNames = getNames(target.getApplications().getValues()); - assertEquals(ImmutableSet.copyOf(names), appNames); - return true; - } - }; - } - - protected void waitForServices(final CloudFoundryBootDashModel target, final String... names) throws Exception { - new ACondition("wait for services to appear", 3000) { - @Override - public boolean test() throws Exception { - ImmutableSet serviceNames = getNames(target.getServices().getValues()); - assertEquals(ImmutableSet.copyOf(names), serviceNames); - return true; - } - }; - } - - protected void waitForElements(final CloudFoundryBootDashModel target, final String... names) throws Exception { - new ACondition("wait for elements to appear", 3000) { - @Override - public boolean test() throws Exception { - ImmutableSet elements = getNames(target.getElements().getValues()); - assertEquals(ImmutableSet.copyOf(names), elements); - return true; - } - }; - } - - private Answer restoreDefaultTemplate() { - return new Answer() { - @Override - public Void answer(InvocationOnMock invocation) throws Throwable { - EditTemplateDialogModel dialog = (EditTemplateDialogModel) invocation.getArguments()[0]; - dialog.restoreDefaultsHandler.call(); - dialog.performOk(); - return null; - } - }; - } - - /** - * Create a mockito {@link Answer} that interacts with EditTemplateDialog by setting the template value and then - * clicking the OK button. - */ - private Answer editSetTemplate(final String newText) { - return new Answer() { - @Override - public Void answer(InvocationOnMock invocation) throws Throwable { - EditTemplateDialogModel dialog = (EditTemplateDialogModel) invocation.getArguments()[0]; - dialog.template.setValue(newText); - dialog.performOk(); - return null; - } - }; - } - - private void assertSorted(ImmutableList actions) { - String[] actionNames = new String[actions.size()]; - for (int i = 0; i < actionNames.length; i++) { - actionNames[i] = actions.get(i).getText(); - } - - String actual = StringUtils.arrayToDelimitedString(actionNames, "\n"); - - Arrays.sort(actionNames); - String expected = StringUtils.arrayToDelimitedString(actionNames, "\n"); - - assertEquals(expected, actual); - } - - private void debugListener(final String name, ObservableSet set) { - set.addListener(new ValueListener>() { - - @Override - public void gotValue(LiveExpression> exp, ImmutableSet value) { - StringBuilder elements = new StringBuilder(); - for (BootDashElement e : exp.getValue()) { - elements.append(e.getName()); - elements.append(" "); - } - System.out.println(name+" -> "+elements); - } - }); - } - - private void assertNames(ArrayList elements, String... expectNames) { - String[] actualNames = new String[elements.size()]; - for (int i = 0; i < actualNames.length; i++) { - actualNames[i] = elements.get(i).getName(); - } - assertArrayEquals(expectNames, actualNames); - } - - private ImmutableSet getNames(ImmutableSet values) { - Builder builder = ImmutableSet.builder(); - for (BootDashElement e : values) { - builder.add(e.getName()); - } - return builder.build(); - } - - public static void waitForState(final BootDashElement element, final RunState state, long timeOut) throws Exception { - new ACondition("Wait for state "+state, timeOut) { - @Override - public boolean test() throws Exception { - assertEquals(state, element.getRunState()); - return true; - } - }; - } - - private ToggleBootDashModelConnection toggleTargetConnectionAction() { - return actions.getConnectAction(); - } - - private UpdatePasswordAction updatePasswordAction() { - return getInjectedAction(UpdatePasswordAction.class); - } - - private EnableJmxSshTunnelAction enableJmxSshTunnel() { - return getInjectedAction(EnableJmxSshTunnelAction.class); - } - - private SelectManifestAction selectManifestAction() { - return getInjectedAction(SelectManifestAction.class); - } - - private IAction restartOnlyApplicationAction() { - return getInjectedAction(RestartApplicationOnlyAction.class); - } - - @SuppressWarnings("unchecked") - private T getInjectedAction(Class klass) { - return (T) actions.getAllInjectedActions().stream() - .filter(action -> klass.isAssignableFrom(action.getClass())) - .findFirst() - .get(); - } - - /////////////////////////////////////////////////////////////////////////////////// - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryClientTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryClientTest.java deleted file mode 100644 index 558eebc36..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryClientTest.java +++ /dev/null @@ -1,1162 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2019 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.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.springframework.ide.eclipse.boot.dash.test.CloudFoundryTestHarness.APP_DEPLOY_TIMEOUT; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.time.Duration; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.apache.commons.io.IOUtils; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runners.MethodSorters; -import org.mockito.Mockito; -import org.osgi.framework.Version; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFAppState; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFBuildpack; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFServiceInstance; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFStack; -import org.springframework.ide.eclipse.boot.dash.cf.client.HealthChecks; -import org.springframework.ide.eclipse.boot.dash.cf.client.SshClientSupport; -import org.springframework.ide.eclipse.boot.dash.cf.client.SshHost; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFCloudDomainData; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFDomainStatus; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFPushArguments; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.DefaultClientRequestsV2; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.DefaultCloudFoundryClientFactoryV2; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.ReactorUtils; -import org.springframework.ide.eclipse.boot.dash.console.IApplicationLogConsole; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.test.util.SslValidationDisabler; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens; -import org.springframework.ide.eclipse.boot.test.BootProjectTestHarness; -import org.springframework.ide.eclipse.boot.test.util.TestBracketter; -import org.springframework.ide.eclipse.boot.util.RetryUtil; -import org.springframework.ide.eclipse.boot.util.Thunk; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; -import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; -import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -import junit.framework.AssertionFailedError; -import reactor.core.Disposable; -import reactor.core.publisher.Flux; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class CloudFoundryClientTest { - - private static final String WDC_06_PCF2 = "wdc-06-pcf2-system.oc.vmware.com"; - - public String CFAPPS_IO() { - return get_CFAPPS_IO(clientParams); - } - - public static String get_CFAPPS_IO(CFClientParams clientParams) { - String org = clientParams.getOrgName(); - String api = clientParams.getApiUrl(); - if (org.equals("application-platform-testing")) { - //PWS test space/org - return "cfapps.io"; - } else if (org.equals("pivot-kdevolder")) { - //PEZ - return "cfapps.pez.pivotal.io"; - } else if (api.contains("api.tan.")) { - //TAN - return "tan.springapps.io"; - } else if (api.contains(WDC_06_PCF2)) { - //vmware pws spring/sts-test space - return "wdc-06-pcf2-apps.oc.vmware.com"; - } - throw new AssertionFailedError("unknown test environment, not sure what to expect here"); - } - - public CFCloudDomain[] getExpectedDomains() { - String org = clientParams.getOrgName(); - String api = clientParams.getApiUrl(); - if (org.equals("application-platform-testing")) { - //PWS test space/org - return new CFCloudDomain[] { - new CFCloudDomainData("cfapps.io") - }; - } else if (org.equals("pivot-kdevolder")) { - //PEZ - return new CFCloudDomain[] { - new CFCloudDomainData("cfapps.pez.pivotal.io"), - new CFCloudDomainData("pezapp.io") - }; - } else if (api.contains("api.tan.")) { - //TAN - return new CFCloudDomain[] { - new CFCloudDomainData("tan.springapps.io") - }; - } else if (api.contains(WDC_06_PCF2)) { - //vmware pws spring/sts-test space - return new CFCloudDomain[] { - new CFCloudDomainData("wdc-06-pcf2-apps.oc.vmware.com") - }; - } - throw new AssertionFailedError("unknown test environment, not sure what to expect here"); - } - - public String[] getExectedBuildpacks() { - String org = clientParams.getOrgName(); - String api = clientParams.getApiUrl(); - if (org.equals("application-platform-testing")) { - //PWS test space/org - return new String[] { - "staticfile_buildpack", - "java_buildpack", - "ruby_buildpack" - }; - } else if (org.equals("pivot-kdevolder")) { - //PEZ - return new String[] { - "staticfile_buildpack", - "java_buildpack_offline", - "ruby_buildpack" - }; - } else if (api.contains("api.tan.")) { - //TAN - return new String[] { - "staticfile_buildpack", - "java_buildpack_offline", - "ruby_buildpack" - }; - } else if (api.contains(WDC_06_PCF2)) { - return new String[] { - "staticfile_buildpack", - "java_buildpack_offline", - "ruby_buildpack" - }; - } - throw new AssertionFailedError("unknown test environment, not sure what to expect here"); - } - - public String getExpectedSshHost() { - String org = clientParams.getOrgName(); - String api = clientParams.getApiUrl(); - if (org.equals("application-platform-testing")) { - //PWS - return "ssh.run.pivotal.io"; - } else if (api.contains("api.tan.")) { - //TAN - return "ssh.tan.springapps.io"; - } else if (api.contains(WDC_06_PCF2)) { - return "ssh."+WDC_06_PCF2; - } - throw new AssertionFailedError("unknown test environment, not sure what to expect here"); - } - - public static final Predicate FLAKY_SERVICE_BROKER = (e) -> { - String msg = ExceptionUtil.getMessage(e).toLowerCase(); - return msg.contains("500") - || msg.contains("502") - ; - }; - - private CFClientParams clientParams = CfTestTargetParams.fromEnv(); - private DefaultClientRequestsV2 client = createClient(clientParams); - - public TestBracketter bracketer = new TestBracketter(); - public CloudFoundryServicesHarness services = new CloudFoundryServicesHarness(clientParams, client); - public CloudFoundryApplicationHarness appHarness = new CloudFoundryApplicationHarness(client); - - @Before - public void setup() throws Exception { - SslValidationDisabler.disableSslValidation(); - ReactorUtils.DUMP_STACK_ON_TIMEOUT = true; - } - - @After - public void teardown() throws Exception { - appHarness.dispose(); //apps first because services still bound to apps can't be deleted! - services.dispose(); - if (client!=null) { - client.close(); - } - StsTestUtil.cleanUpProjects(); - ReactorUtils.DUMP_STACK_ON_TIMEOUT = false; - } - - public BootProjectTestHarness projects = new BootProjectTestHarness(ResourcesPlugin.getWorkspace()); - - private UserInteractions ui = Mockito.mock(UserInteractions.class); - - public static DefaultClientRequestsV2 createClient(CFClientParams params) { - try { - DefaultCloudFoundryClientFactoryV2 factory = DefaultCloudFoundryClientFactoryV2.INSTANCE; - return (DefaultClientRequestsV2) factory.getClient(params); - } catch (Exception e) { - throw new Error(e); - } - } - - @Rule - public TestBracketter testBrack = new TestBracketter(); - - @Test - public void testGetApiVersion() throws Exception { - Version version = client.getApiVersion(); - System.out.println("Api version = "+version); - assertNotNull(version); - } - - @Test - public void testGetSpaces() throws Exception { - int success = 0; - int failed = 0; - - Exception error = null; - for (int i = 0; i < 5; i++) { - try { - long start = System.currentTimeMillis(); - List spaces = client.getSpaces(); - long duration = System.currentTimeMillis() - start; - System.out.println("getSpaces -> "+spaces.size()+" spaces in "+ duration + " ms"); - success++; - } catch (Exception e) { - error = e; - failed++; - System.out.println("getSpaces -> "+ExceptionUtil.getMessage(e)); - } - } - System.out.println("getSpaces failure rate = "+failed + "/" +(success+failed)); - if (failed>0) { - throw new IOException("getSpaces failure rate = "+failed + "/" +(success+failed), error); - } - } - - @Test - public void testGetApplicationDetails() throws Exception { - String appName = appHarness.randomAppName(); - - try (CFPushArguments params = new CFPushArguments()) { - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setNoStart(true); - push(params); - } - - { - CFApplicationDetail appDetails = client.getApplication(appName); - assertEquals(0, appDetails.getRunningInstances()); - assertEquals(CFAppState.STOPPED, appDetails.getState()); - assertEquals(ImmutableList.of(), appDetails.getInstanceDetails()); - } - - client.restartApplication(appName, CancelationTokens.NULL); - { - CFApplicationDetail appDetails = client.getApplication(appName); - assertEquals(1, appDetails.getRunningInstances()); - assertEquals(CFAppState.STARTED, appDetails.getState()); - assertEquals(1, appDetails.getInstanceDetails().size()); - } - } - - @Test - public void testPushAndBindServices() throws Exception { - //This test fails occasionally because service binding is 'unreliable'. Had a long discussion - // with Ben Hale. The gist is errors happen and should be expected in distributed world. - //They are coming from 'AppDirect' which manages the services. The errors are mediated through cloudfoundry - // which doesn't knwow how it should handle them. So it passed the buck onto the its callers. - //In this case.... cf-java-client which does the same thing and passes them to us. - //All the reasons why they can't handle these errors also apply to us, which means that - //the operation is simply unreliable and so failure is an expected outcome even when everything - //works correctly. - //To avoid this test case from failing too often we retry it a few times. - RetryUtil.retryTimes("testPushAndBindServices", 4, () -> { - - System.out.println("Executing full test scenario."); - String service1 = services.createTestService(); - String service2 = services.createTestService(); - String service3 = services.createTestService(); //An extra unused service (makes this a better test). - - String appName = appHarness.randomAppName(); - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setServices(ImmutableList.of(service1, service2)); - push(params); - - assertEquals(ImmutableSet.of(service1, service2), getBoundServiceNames(appName)); - - client.bindAndUnbindServices(appName, ImmutableList.of(service1)).block(); - assertEquals(ImmutableSet.of(service1), getBoundServiceNames(appName)); - - client.bindAndUnbindServices(appName, ImmutableList.of(service2)).block(); - assertEquals(ImmutableSet.of(service2), getBoundServiceNames(appName)); - - client.bindAndUnbindServices(appName, ImmutableList.of()).block(); - assertEquals(ImmutableSet.of(), getBoundServiceNames(appName)); - }); - } - - private Set getBoundServiceNames(String appName) throws Exception { - return client.getBoundServicesSet(appName).block(); - } - - @Test - public void testPushAndBindHostAndDomain() throws Exception { - String appName = appHarness.randomAppName(); - - for (int i = 0; i < 2; i++) { - //Why this loop? Because there was bug which CF V2 that made second push fail to bind to - // map a host that was previously mapped. - if (i>0) { - System.out.println("Delete app"); - client.deleteApplication(appName); - } - - System.out.println("Pushing "+(i+1)); - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setRoutes(ImmutableList.of(appName+"."+CFAPPS_IO())); - - push(params); - } - - System.out.println("Pushing SUCCESS"); - - CFApplicationDetail app = client.getApplication(appName); - assertNotNull("Expected application to exist after push: " + appName, app); - - assertEquals(ImmutableSet.of(appName+"."+CFAPPS_IO()), ImmutableSet.copyOf(app.getUris())); - } - - @Test - public void testPushAndBindMultipleHosts() throws Exception { - String[] hostNames = { - appHarness.randomAppName(), - appHarness.randomAppName() - }; - String appName = hostNames[0]; - - CFPushArguments params = new CFPushArguments(); - params.setAppName(hostNames[0]); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - - Set routes = ImmutableSet.copyOf(Stream.of(hostNames) - .map((host) -> host + "." + CFAPPS_IO()) - .collect(Collectors.toList()) - ); - params.setRoutes(routes); - - push(params); - - System.out.println("Pushing SUCCESS"); - - CFApplicationDetail app = client.getApplication(appName); - assertNotNull("Expected application to exist after push: " + appName, app); - - assertEquals(routes, ImmutableSet.copyOf(app.getUris())); - } - - @Test - public void testPushAndSetRoutes() throws Exception { - String[] hostNames = { - appHarness.randomAppName(), - appHarness.randomAppName() - }; - String appName = hostNames[0]; - - CFPushArguments params = new CFPushArguments(); - params.setAppName(hostNames[0]); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - - Set routes = ImmutableSet.copyOf(Stream.of(hostNames) - .map((host) -> host + "." + CFAPPS_IO()) - .collect(Collectors.toList()) - ); - params.setRoutes(routes); - - push(params); - - System.out.println("Pushing SUCCESS"); - - { - CFApplicationDetail app = client.getApplication(appName); - assertNotNull("Expected application to exist after push: " + appName, app); - assertEquals(routes, ImmutableSet.copyOf(app.getUris())); - } - - doSetRoutesTest(appName, ImmutableSet.of(), params.getRandomRoute()); - - for (String route : routes) { - doSetRoutesTest(appName, ImmutableSet.of(route), params.getRandomRoute()); - } - - } - - private void doSetRoutesTest(String appName, ImmutableSet routes, boolean randomRoute) throws Exception { - ReactorUtils.get(client.setRoutes(appName, routes, randomRoute)); - CFApplicationDetail app = client.getApplication(appName); - assertEquals(routes, ImmutableSet.copyOf(app.getUris())); - } - - @Test - public void testPushWithBasicHealthcheckTypes() throws Exception { - //This test is to make sure that hc info is properly passed on by push operation - // to the 'real' cf client. - //Since the push works different on firt push and repush we have to check both! - - String appName = appHarness.randomAppName(); - - String[] HC_TYPES = { - HealthChecks.HC_PORT, - HealthChecks.HC_PROCESS - }; - - for (String hcType : HC_TYPES) { - try (CFPushArguments params = new CFPushArguments()) { - params.setAppName(appName); - params.setRoutes(appName+"."+CFAPPS_IO()); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setHealthCheckType(hcType); - push(params); - CFApplicationDetail app = client.getApplication(appName); - assertNotNull("Expected application to exist after push: " + appName, app); - assertEquals(hcType, app.getHealthCheckType()); - } - } - } - - @Test - public void testPushAndSetHealthcheckHttpEndpoint() throws Exception { - String appName = appHarness.randomAppName(); - - try (CFPushArguments params = new CFPushArguments()) { - params.setAppName(appName); - params.setRoutes(appName+"."+CFAPPS_IO()); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setHealthCheckHttpEndpoint("/test.txt"); - params.setHealthCheckType(HealthChecks.HC_HTTP); - push(params); - CFApplicationDetail app = client.getApplication(appName); - assertNotNull("Expected application to exist after push: " + appName, app); - assertEquals(HealthChecks.HC_HTTP, app.getHealthCheckType()); - assertEquals("/test.txt", app.getHealthCheckHttpEndpoint()); - } - } - - @Test - public void testPushAndSetEnv() throws Exception { - String appName = appHarness.randomAppName(); - - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setRoutes(appName+"."+CFAPPS_IO()); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setEnv(ImmutableMap.of( - "foo", "foo_value", - "bar", "bar_value" - )); - push(params); - - CFApplicationDetail app = client.getApplication(appName); - assertNotNull("Expected application to exist after push: " + appName, app); - ACondition.waitFor("app content to be availabe", 10_000, () -> { - String content = IOUtils.toString(new URI("https://" + appName + '.' + CFAPPS_IO() + "/test.txt")); - assertTrue(content.length() > 0); - assertTrue(content.contains("content")); - }); - - { - Map env = client.getEnv(appName).block(); - assertEquals("foo_value", env.get("foo")); - assertEquals("bar_value", env.get("bar")); - assertEquals(2, env.size()); - } - - client.setEnvVars(appName, ImmutableMap.of("other", "value")).block(); - { - Map env = client.getEnv(appName).block(); - assertEquals("value", env.get("other")); - assertEquals(1, env.size()); - } - - //This last piece is commented because it fails. - //See: https://www.pivotaltracker.com/story/show/116804259 - - // The last var doesn't get removed. Not sure how to fix it. - // But eventually we won't even be using 'setEnvVars' it will be part of the push. - // and its not going to be our problem to fix that. -// client.updateApplicationEnvironment(appName, ImmutableMap.of()).get(); -// { -// Map env = client.getEnv(appName).get(); -// assertEquals(0, env.size()); -// } - } - - @Test - public void testDeleteApplication() throws Exception { - String appName = appHarness.randomAppName(); - - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - push(params); - - CFApplicationDetail app = client.getApplication(appName); - assertTrue(client.applicationExists(appName)); - assertNotNull("Expected application to exist after push: " + appName, app); - - client.deleteApplication(appName); - app = client.getApplication(appName); - assertNull("Expected application to be deleted after delete: " + appName, app); - assertFalse(client.applicationExists(appName)); - } - - @Test - public void testStopApplication() throws Exception { - String appName = appHarness.randomAppName(); - - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - push(params); - - final CFApplicationDetail runningApp = client.getApplication(appName); - assertNotNull("Expected application to exist after push: " + appName, runningApp); - - new ACondition("wait for app '"+ appName +"'to be RUNNING", APP_DEPLOY_TIMEOUT) { - public boolean test() throws Exception { - assertAppRunState(1, runningApp.getRunningInstances(), CFAppState.STARTED, runningApp.getState()); - return true; - } - }; - - client.stopApplication(appName); - final CFApplicationDetail stoppedApp = client.getApplication(appName); - - new ACondition("wait for app '"+ appName +"'to be STOPPED", APP_DEPLOY_TIMEOUT) { - public boolean test() throws Exception { - assertAppRunState(0, stoppedApp.getRunningInstances(), CFAppState.STOPPED, stoppedApp.getState()); - return true; - } - }; - } - - @Test - public void getServices() throws Exception { - RetryUtil.retryWhen("getServices", 5, FLAKY_SERVICE_BROKER, - () -> { - String[] serviceNames = new String[3]; - Set userProvided = new HashSet<>(); - for (int i = 0; i < serviceNames.length; i++) { - if (i%2==0) { - serviceNames[i] = services.createTestService(); - } else { - serviceNames[i] = services.createTestUserProvidedService(); - userProvided.add(serviceNames[i]); - } - } - - List actualServices = client.getServices(); - ImmutableSet actualServiceNames = ImmutableSet.copyOf( - actualServices.stream() - .map(CFServiceInstance::getName) - .collect(Collectors.toList()) - ); - - - for (CFServiceInstance s : actualServices) { - //Note: because these test on CI host run in parallel with others using same space... - // we should assume there might be 'extra stuff' on the space than what we just created here. - //So only check that 'our stuff' exists and looks right and ignore the rest. - String name = s.getName(); - if (ImmutableSet.copyOf(serviceNames).contains(name)) { - System.out.println("Verifying service: "+name); - if (userProvided.contains(name)) { - assertEquals("user-provided", s.getService()); - System.out.println(" user provided => OK"); - } else { - assertEquals(services.getTestServiceAndPlan()[0], s.getService()); - System.out.println(" getService() => OK"); - String expectPlan = services.getTestServiceAndPlan()[1]; - assertEquals(expectPlan, s.getPlan()); - System.out.println(" getPlan() => OK"); - assertIsURL(s.getDashboardUrl()); - System.out.println(" getDashboardUrl() => OK"); - assertIsURL(s.getDocumentationUrl()); - System.out.println(" getDocumentationUrl() => OK"); - assertText(s.getDescription()); - System.out.println(" getDescription() => OK"); - } - } - } - - for (String s : serviceNames) { - assertTrue(s+" not found in "+actualServiceNames, actualServiceNames.contains(s)); - } - } - ); - } - - @Test - public void testServiceCreateAndDelete() throws Exception { - RetryUtil.retryWhen("testServiceCreateAndDelete", 5, FLAKY_SERVICE_BROKER, () -> { - String[] serviceNames = new String[2]; - for (int i = 0; i < serviceNames.length; i++) { - serviceNames[i] = services.randomServiceName(); - }; - for (int i = 0; i < serviceNames.length; i++) { - String serviceName = serviceNames[i]; - if (i%2==0) { - System.out.println("Create service: "+serviceName); - String[] serviceInfo = services.getTestServiceAndPlan(); - client.createService(serviceName, serviceInfo[0], serviceInfo[1]) - .block(CloudFoundryServicesHarness.CREATE_SERVICE_TIMEOUT); - } else { - System.out.println("Create user-provided service: "+serviceName); - client.createUserProvidedService(serviceName, ImmutableMap.of()) - .block(); - } - } - - List services = client.getServices(); - assertServices(services, serviceNames); - for (String serviceName : serviceNames) { - client.deleteServiceAsync(serviceName).block(); - System.out.println("Deleted service: "+serviceName); - } - - assertNoServices(client.getServices(), serviceNames); - }); - } - - @Test - public void testGetBoundServices() throws Exception { - RetryUtil.retryWhen("testGetBoundServices", 5, FLAKY_SERVICE_BROKER, () -> { - String service1 = services.createTestService(); - String service2 = services.createTestService(); - String service3 = services.createTestService(); - - String appName = appHarness.randomAppName(); - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setServices(ImmutableList.of(service1, service2)); - push(params); - - List allApps = client.getApplicationsWithBasicInfo(); - CFApplication app = null; - for (CFApplication a : allApps) { - if (a.getName().equals(appName)) { - app = a; - } - } - assertEquals(ImmutableSet.of(service1, service2), ImmutableSet.copyOf(app.getServices())); - - app = client.getApplication(appName); - assertEquals(ImmutableSet.of(service1, service2), ImmutableSet.copyOf(app.getServices())); - }); - } - - - @Test - public void testGetDomains() throws Exception { - CFClientParams params = CfTestTargetParams.fromEnv(); - client = createClient(params); - List domains = client.getDomains(); - - for (CFCloudDomain d : domains) { - System.out.println(d.getName()+"\t"+d.getType()); - } - - assertContains(domains, getExpectedDomains()); - - assertEquals(CFAPPS_IO(), domains.stream() - .filter(d -> d.getStatus()==CFDomainStatus.SHARED && d.getType()==CFDomainType.HTTP) - .map(d -> d.getName()) - .findFirst() - .orElse(null) - ); - } - - @Test - public void testGetBuildpacks() throws Exception { - client = createClient(CfTestTargetParams.fromEnv()); - List buildpacks = client.getBuildpacks(); - - Set names = Flux.fromIterable(buildpacks) - .map(CFBuildpack::getName) - .collectList() - .map(ImmutableSet::copyOf) - .block(); - - assertContains(names, getExectedBuildpacks()); - } - - @Test - public void testGetStacks() throws Exception { - client = createClient(CfTestTargetParams.fromEnv()); - List stacks = client.getStacks(); - - Set names = Flux.fromIterable(stacks) - .map(CFStack::getName) - .collectList() - .map(ImmutableSet::copyOf) - .block(); - - assertContains(names, - "cflinuxfs3" - ); - } - - @Test - public void testApplicationLogConnection() throws Exception { - client = createClient(CfTestTargetParams.fromEnv()); - - String appName = appHarness.randomAppName(); - IApplicationLogConsole listener = mock(IApplicationLogConsole.class); - Disposable token = client.streamLogs(appName, listener); - assertNotNull(token); - - Future pushResult = doAsync(() -> { - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - push(params); - }); - - ACondition.waitFor("push", TimeUnit.MINUTES.toMillis(4), () -> { - assertTrue(pushResult.isDone()); - }); - pushResult.get(); - - BootDashModelTest.waitForJobsToComplete(); - verify(listener, atLeastOnce()).onMessage(any()); - } - -// @Test -// public void testGetExistingRoutes() throws Exception { -// String appName = "foo";//appHarness.randomAppName(); -// -//// CFPushArguments params = new CFPushArguments(); -//// params.setAppName(appName); -//// params.setApplicationData(getTestZip("testapp")); -//// params.setBuildpack("staticfile_buildpack"); -//// push(params); -// -// for (int i = 0; i < 3; i++) { -// System.out.println("===================="); -// assertTrue(client.getExistingRoutes(appName).toList().get().isEmpty()); -// } -// } - - - - @Test - public void testGetApplicationBuildpack() throws Exception { - String appName = appHarness.randomAppName(); - - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - push(params); - - //Note we try to get the app two different ways because retrieving the info in - // each case is slightly different. - - { - CFApplicationDetail app = client.getApplication(appName); - assertEquals("staticfile_buildpack", app.getBuildpackUrl()); - } - - { - List allApps = client.getApplicationsWithBasicInfo(); - CFApplication app = null; - for (CFApplication a : allApps) { - if (a.getName().equals(appName)) { - app = a; - } - } - assertEquals("staticfile_buildpack", app.getBuildpackUrl()); - } - } - - - @Test - public void testGetApplicationStack() throws Exception { - String appName = appHarness.randomAppName(); - String stackName = "cflinuxfs3"; - - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setStack(stackName); - push(params); - - //Note we try to get the app two different ways because retrieving the info in - // each case is slightly different. - - { - CFApplicationDetail app = client.getApplication(appName); - assertEquals(stackName, app.getStack()); - } - - { - List allApps = client.getApplicationsWithBasicInfo(); - CFApplication app = null; - for (CFApplication a : allApps) { - if (a.getName().equals(appName)) { - app = a; - } - } - assertEquals(stackName, app.getStack()); - } - } - - @Test - public void testGetApplicationTimeout() throws Exception { - String appName = appHarness.randomAppName(); - int timeout = 67; - - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setTimeout(timeout); - push(params); - - //Note we try to get the app two different ways because retrieving the info in - // each case is slightly different. - - { - CFApplicationDetail app = client.getApplication(appName); - assertEquals(timeout, (int)app.getTimeout()); - } - - { - List allApps = client.getApplicationsWithBasicInfo(); - CFApplication app = null; - for (CFApplication a : allApps) { - if (a.getName().equals(appName)) { - app = a; - } - } - assertEquals(timeout, (int)app.getTimeout()); - } - } - - @Test - public void testRandomHost() throws Exception { - //It is now the responsibility of the client to interpret the 'random route' attribute and - // generate random host or port. This test checks if it does that. - String appName = appHarness.randomAppName(); - - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setRoutes(CFAPPS_IO()); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setRandomRoute(true); - push(params); - - CFApplicationDetail app = client.getApplication(appName); - List uris = app.getUris(); - assertEquals(1, uris.size()); - String uri = uris.get(0); - String host = uri.split("\\.")[0]; - String domain = uri.substring(host.length()+1); - assertEquals(CFAPPS_IO(), domain); - assertTrue(StringUtil.hasText(host)); - } - - @Test - public void testGetApplicationCommand() throws Exception { - String appName = appHarness.randomAppName(); - String command = "something interesting"; - - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - params.setCommand(command); - params.setNoStart(true); // Our command is bogus so starting won't work - push(params); - - //Note we try to get the app two different ways because retrieving the info in - // each case is slightly different. - - { - CFApplicationDetail app = client.getApplication(appName); - assertEquals(command, app.getCommand()); - } - - { - List allApps = client.getApplicationsWithBasicInfo(); - CFApplication app = null; - for (CFApplication a : allApps) { - if (a.getName().equals(appName)) { - app = a; - } - } - assertEquals(command, app.getCommand()); - } - } - - @Test public void testSshSupport() throws Exception { - String appName = appHarness.randomAppName(); - - CFPushArguments params = new CFPushArguments(); - params.setAppName(appName); - params.setApplicationData(getTestZip("testapp")); - params.setBuildpack("staticfile_buildpack"); - push(params); - - SshClientSupport sshSupport = client.getSshClientSupport(); - SshHost sshHost = sshSupport.getSshHost(); - System.out.println(sshHost); - assertEquals(getExpectedSshHost(), sshHost.getHost()); - assertEquals(2222, sshHost.getPort()); - assertTrue(StringUtil.hasText(sshHost.getFingerPrint())); - - assertTrue(StringUtil.hasText(sshSupport.getSshCode())); - UUID appGuid = client.getApplication(appName).getGuid(); - String sshUser = sshSupport.getSshUser(appGuid, 0); - System.out.println("sshUser = "+sshUser); - assertTrue(StringUtil.hasText(sshUser)); - - String code = sshSupport.getSshCode(); - System.out.println("sshCode = "+code); - assertTrue(StringUtil.hasText(code)); - } - - @Test public void testGetServiceDashboardUrl() throws Exception { - String serviceName = services.createTestService(); - CFServiceInstance service = null; - for (CFServiceInstance s : client.getServices()) { - if (s.getName().equals(serviceName)) { - service = s; - } - } - String dashUrl = service.getDashboardUrl(); - assertNotNull(dashUrl); - assertTrue(dashUrl.startsWith("https")); - } - - @Test public void startCanBeCanceled() throws Exception { - IProject project = projects.createBootWebProject("slow-starter"); - File jarFile = BootJarPackagingTest.packageAsJar(project, ui); - System.out.println(); - - String appName = appHarness.randomAppName(); - try (CFPushArguments params = new CFPushArguments()) { - params.setAppName(appName); - params.setRoutes(appName+"."+CFAPPS_IO()); - params.setApplicationData(jarFile); - params.setNoStart(true); - - long starting = System.currentTimeMillis(); - System.out.println("Pushing..."); - push(params); - long duration = System.currentTimeMillis() - starting; - System.out.println("Pushing took: "+duration+ " ms"); - } - - CancelationTokens cancelationTokens = new CancelationTokens(); - long starting = System.currentTimeMillis(); - System.out.println("Starting..."); - Future startResult = doAsync(() -> { - client.restartApplication(appName, cancelationTokens.create()); - long duration = System.currentTimeMillis() - starting; - System.out.println("started in "+duration+" ms"); - }); - - Thread.sleep(5000); - long cancelTime = System.currentTimeMillis(); - cancelationTokens.cancelAll(); - try { - startResult.get(5, TimeUnit.SECONDS); - } catch (ExecutionException e) { - e.printStackTrace(); - long duration = System.currentTimeMillis() - cancelTime; - assertEquals(OperationCanceledException.class, ExceptionUtil.getDeepestCause(e).getClass()); - System.out.println("\nRestart Canceled after "+duration+" ms"); - } - } - - @Test public void pushCanBeCanceled() throws Exception { - String appName = appHarness.randomAppName(); - IProject project = projects.createBootWebProject("slow-starter"); - File jarFile = BootJarPackagingTest.packageAsJar(project, ui); - - CancelationTokens cancelationTokens = new CancelationTokens(); - try (CFPushArguments params = new CFPushArguments()) { - params.setAppName(appName); - params.setRoutes(appName+"."+CFAPPS_IO()); - params.setApplicationData(jarFile); - - long starting = System.currentTimeMillis(); - Future pushResult = doAsync(() -> { - System.out.println("Pushing..."); - client.push(params, cancelationTokens.create()); - long duration = System.currentTimeMillis() - starting; - System.out.println("Pushing took: "+duration+ " ms"); - }); - Thread.sleep(Duration.ofSeconds(10).toMillis()); - long cancelTime = System.currentTimeMillis(); - System.out.println("Canceling..."); - cancelationTokens.cancelAll(); - - try { - pushResult.get(5, TimeUnit.SECONDS); // Cancel should happen pretty 'fast'! - fail("push completed but it should have been canceled"); - } catch (ExecutionException e) { // real exception is wrapped in EE by Future.get - e.printStackTrace(); - long duration = System.currentTimeMillis() - cancelTime; - assertEquals(OperationCanceledException.class, ExceptionUtil.getDeepestCause(e).getClass()); - System.out.println("\nPush Canceled after: "+duration +" ms"); - } - } - } - - - ///////////////////////////////////////////////////////////////////////////// - - private void assertText(String s) { - if (!StringUtil.hasText(s)) { - fail("Found no text, but expected some"); - } - } - - private void assertIsURL(String url) throws URISyntaxException { - assertText(url); - new URI(url); //parse it - } - - private Future doAsync(Thunk task) { - CompletableFuture result = new CompletableFuture<>(); - Job job = new Job("Async task") { - protected IStatus run(IProgressMonitor monitor) { - try { - task.call(); - result.complete(null); - } catch (Throwable e) { - result.completeExceptionally(e); - } - return Status.OK_STATUS; - } - }; - job.schedule(); - return result; - } - - private void push(CFPushArguments _params) throws Exception { - if (_params.getMemory() == null) { - _params.setMemory(1024); - } - try (CFPushArguments params = _params) { - client.push(params, CancelationTokens.NULL); - } - } - - private void assertContains(Collection strings, @SuppressWarnings("unchecked") T... expecteds) { - for (T e : expecteds) { - assertContains(e, strings); - } - } - - private void assertContains(T expected, Collection set) { - assertTrue("Expected '"+expected+"' not found in: "+set, set.contains(expected)); - } - - private void assertNoServices(List services, String... serviceNames) throws Exception { - Set names = services.stream().map(CFServiceInstance::getName).collect(Collectors.toSet()); - for (String serviceName : serviceNames) { - assertFalse("Service exists but shouldn't: "+serviceName, names.contains(serviceName)); - } - } - - private void assertServices(List services, String... serviceNames) throws Exception { - Set names = services.stream().map(CFServiceInstance::getName).collect(Collectors.toSet()); - assertContains(names, serviceNames); - } - - private void assertAppRunState(int expectedInstances, int actualInstances, CFAppState expectedRequestedState, CFAppState actualRequestedState) { - assertEquals("Expected running instances does not match actual running instances: ", expectedInstances, actualInstances); - assertEquals("Expected requested app state does not match actual requested app state: ", expectedRequestedState, actualRequestedState); - } - - private File getTestZip(String fileName) { - File sourceWorkspace = new File( - StsTestUtil.getSourceWorkspacePath("org.springframework.ide.eclipse.boot.dash.test")); - File file = new File(sourceWorkspace, fileName + ".zip"); - Assert.isTrue(file.exists(), ""+ file); - return file; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryServicesHarness.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryServicesHarness.java deleted file mode 100644 index 7ea4e1230..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryServicesHarness.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.springframework.ide.eclipse.boot.dash.test.CloudFoundryClientTest.FLAKY_SERVICE_BROKER; - -import java.time.Duration; -import java.util.HashSet; -import java.util.Set; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.DefaultClientRequestsV2; -import org.springframework.ide.eclipse.boot.util.RetryUtil; -import org.springsource.ide.eclipse.commons.core.util.StringUtil; -import org.springsource.ide.eclipse.commons.livexp.ui.Disposable; -import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; - -import com.google.common.collect.ImmutableMap; - -public class CloudFoundryServicesHarness implements Disposable { - - public static final Duration CREATE_SERVICE_TIMEOUT = Duration.ofMinutes(1); - - private static final Duration DELETE_SERVICE_TIMEOUT = Duration.ofMinutes(1); - - private DefaultClientRequestsV2 client; - - private CFClientParams clientParams; - - public CloudFoundryServicesHarness(CFClientParams clientParams, DefaultClientRequestsV2 client) { - this.client = client; - this.clientParams = clientParams; - } - private Set ownedServiceNames = new HashSet<>(); - - public String[] getTestServiceAndPlan() { - String org = clientParams.getOrgName(); - String api = clientParams.getApiUrl(); - if (org.equals("application-platform-testing")) { - //PWS test space/org - return new String[] {"cloudamqp", "lemur"}; - } else if (api.contains("api.run.pez.")) { - //PEZ - return new String[] {"p-rabbitmq", "standard"}; - } else if (api.contains("api.tan.")) { - //TAN RGB - //return new String[] {"app-autoscaler", "bronze"}; //Warning not good enough for some tests! - return new String[] {"p-rabbitmq", "standard"}; - } else if (api.contains("wdc-06-pcf2-system.oc.vmware.com")) { - return new String[] {"p-rabbitmq", "standard"}; - } - return null; - } - - public String randomServiceName() { - String name = StringUtil.datestamp()+"-"+randomAlphabetic(10); - ownedServiceNames.add(name); - return name; - } - - public String createTestUserProvidedService() { - String name = randomServiceName(); - client.createUserProvidedService(name, ImmutableMap.of()).block(CREATE_SERVICE_TIMEOUT); - return name; - } - - public String createTestService() throws Exception { - String name = randomServiceName(); - RetryUtil.retryWhen("createTestService["+name+"]", 5, FLAKY_SERVICE_BROKER, () -> { - String[] serviceParams = getTestServiceAndPlan(); - client.createService(name, serviceParams[0], serviceParams[1]).block(CREATE_SERVICE_TIMEOUT); - }); - return name; - } - - protected void deleteOwnedServices() { - if (!ownedServiceNames.isEmpty()) { - System.out.println("owned services: "+ownedServiceNames); - try { - for (String serviceName : ownedServiceNames) { - System.out.println("delete service: "+serviceName); - try { - RetryUtil.retryTimes("delete sercice "+serviceName, 3, () -> { - this.client.deleteServiceAsync(serviceName).block(DELETE_SERVICE_TIMEOUT); - }); - } catch (Exception e) { - System.out.println("Failed to delete ["+serviceName+"]: "+ExceptionUtil.getMessage(e)); - - // May get 404 or other 400 errors if it is alrready - // gone so don't prevent other owned apps from being - // deleted - } - } - - } catch (Exception e) { - fail("failed to cleanup owned services: " + e.getMessage()); - } - } - } - - @Override - public void dispose() { - assertTrue(!client.isLoggedOut()); - deleteOwnedServices(); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryTestHarness.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryTestHarness.java deleted file mode 100644 index b000f57e3..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/CloudFoundryTestHarness.java +++ /dev/null @@ -1,387 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2019 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.test; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.when; - -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; - -import org.apache.commons.io.IOUtils; -import org.eclipse.core.resources.IFile; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; -import org.springframework.ide.eclipse.boot.dash.cf.client.CloudFoundryClientFactory; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.CloudFoundryTargetWizardModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.PasswordDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.StoreCredentialsMode; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.JmxSshTunnelManager; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudFoundryBootDashModel; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTargetType; -import org.springframework.ide.eclipse.boot.dash.cf.ui.CfUserInteractions; -import org.springframework.ide.eclipse.boot.dash.dialogs.ManifestDiffDialogModel; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.LocalBootDashModel; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springframework.ide.eclipse.boot.dash.model.SecuredCredentialsStore; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.RunTargetTypes; -import org.springframework.ide.eclipse.boot.dash.test.mocks.MockRunnableContext; -import org.springsource.ide.eclipse.commons.core.pstore.IPropertyStore; -import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition; -import org.springsource.ide.eclipse.commons.frameworks.test.util.Asserter1; - -import com.google.common.collect.ImmutableSet; - -/** - * @author Kris De Volder - */ -public class CloudFoundryTestHarness extends BootDashViewModelHarness { - - @FunctionalInterface - public interface MultipleChoiceAnswerer { - int apply(String title, String msg, String[] choices, int defaultIndex); - } - - public static class DeploymentAnswerer { - String yaml; - String appName; - - public DeploymentAnswerer(String yaml, String appName) { - this.yaml = yaml; - this.appName = appName; - } - - public DeploymentAnswerer(String yaml) { - this(yaml, null); - } - - public DeploymentAnswerer() { - this(null, null); - } - - public void apply(CloudApplicationDeploymentProperties deploymentProperties) throws Exception {}; - } - - @FunctionalInterface - public interface PasswordAnswerer { - void apply(PasswordDialogModel model) throws Exception; - } - - /** - * How long to wait for deleted app to disapear from the model. - */ - public static final long APP_DELETE_TIMEOUT = TimeUnit.MINUTES.toMillis(1); - - /** - * How long to wait for deleted app to disapear from the model. - */ - public static final long SERVICE_DELETE_TIMEOUT = TimeUnit.MINUTES.toMillis(1); - - /** - * How long to wait for a deployed app to show up in the model? This should - * be relatively short. - */ - public static final long APP_IS_VISIBLE_TIMEOUT = 20_000; - - /** - * How long to wait for a deployed app to transition to running state. - */ - public static final long APP_DEPLOY_TIMEOUT = TimeUnit.MINUTES.toMillis(6); - - /** - * How long to wait on retrieving request mappings from a CF app. - */ - public static final long FETCH_REQUEST_MAPPINGS_TIMEOUT = 5_000; - /** - * How long to wait for runtarget to become 'connected'. - */ - public static final long CONNECT_TARGET_TIMEOUT = 30_000; - - public static CloudFoundryTestHarness create(TestBootDashModelContext context) throws Exception { - context.injections.assertDefinitionFor(CloudFoundryClientFactory.class); - context.injections.assertNoDefinitionFor(RunTargetType.class); - context.injections.defInstance(RunTargetType.class, RunTargetTypes.LOCAL); - context.injections.def(CloudFoundryRunTargetType.class, CloudFoundryRunTargetType::new); - return new CloudFoundryTestHarness(context); - } - - - public CloudFoundryBootDashModel getCfTargetModel() { - return (CloudFoundryBootDashModel) getRunTargetModel(cfTargetType()); - } - - private RunTargetType cfTargetType() { - List types = context.injections.getBeans(RunTargetType.class); - for (RunTargetType t : types) { - if (t instanceof CloudFoundryRunTargetType) { - return t; - } - } - throw new NoSuchElementException("No cf target type"); - } - - private CloudFoundryClientFactory clientFactory() { - return context.injections.getBean(CloudFoundryClientFactory.class); - } - - public CloudFoundryBootDashModel createCfTarget( - CFClientParams params, - StoreCredentialsMode storePassword - ) throws Exception { - return createCfTarget(params, storePassword, (wizard) -> assertOk(wizard.getValidator())); - } - - public CloudFoundryBootDashModel createCfTarget( - CFClientParams params, - StoreCredentialsMode storePassword, - Asserter1 wizardAsserter - ) throws Exception { - CloudFoundryTargetWizardModel wizard = new CloudFoundryTargetWizardModel(cfTargetType(), clientFactory(), NO_TARGETS, context); - - wizard.setUrl(params.getApiUrl()); - wizard.setUsername(params.getUsername()); - wizard.setStoreCredentials(storePassword); - wizard.setMethod(params.getCredentials().getType().toLoginMethod()); - wizard.setPassword(params.getCredentials().getSecret()); - wizard.setSelfsigned(params.isSelfsigned()); - wizard.skipSslValidation(params.skipSslValidation()); - wizard.resolveSpaces(new MockRunnableContext()); - assertNotNull(wizard.getRefreshToken()); - wizard.setSpace(getSpace(wizard, params.getOrgName(), params.getSpaceName())); - wizardAsserter.execute(wizard); - final CloudFoundryRunTarget newTarget = wizard.finish(); - if (newTarget!=null) { - model.getRunTargets().add(newTarget); - } - final CloudFoundryBootDashModel targetModel = getCfModelFor(newTarget); - //The created targetModel automatically connected, but this happens asynchly. - new ACondition("Wait for connected state", CONNECT_TARGET_TIMEOUT) { - public boolean test() throws Exception { - return targetModel.isConnected(); - } - }; - return targetModel; - } - - public CloudFoundryBootDashModel createCfTarget(CFClientParams params) throws Exception { - return createCfTarget(params, StoreCredentialsMode.STORE_PASSWORD); - } - - public CloudFoundryBootDashModel getCfModelFor(CloudFoundryRunTarget cfTarget) { - return (CloudFoundryBootDashModel) model.getSectionByTargetId(cfTarget.getId()); - } - - private static final ImmutableSet NO_TARGETS = ImmutableSet.of(); - - private CloudFoundryTestHarness(TestBootDashModelContext context) throws Exception { - super(context); - context.injections.assertDefinitionFor(CloudFoundryRunTargetType.class); - context.injections.assertDefinitionFor(CloudFoundryClientFactory.class); - } - - private static CFSpace getSpace(CloudFoundryTargetWizardModel wizard, String orgName, String spaceName) { - for (CFSpace space : wizard.getSpaces().getOrgSpaces(orgName)) { - if (space.getName().equals(spaceName)) { - return space; - } - } - fail("Not found org/space = "+orgName+"/"+spaceName); - return null; - } - - public void answerDeploymentPrompt(CfUserInteractions ui, final String appName, final String hostName) throws Exception { - final String yaml = "applications:\n" + - "- name: "+appName+"\n" + - " host: "+hostName+"\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ \"jre\": { version: 11.+ } }'\n"; - answerDeploymentPrompt(ui, new DeploymentAnswerer(yaml)); - } - - public void answerConfirmationMultipleChoice(UserInteractions ui, MultipleChoiceAnswerer answerer) { - doAnswer(new Answer() { - @Override - public Integer answer(InvocationOnMock invocation) throws Throwable { - // int confirmOperation(String title, String message, String[] buttonLabels, int defaultButtonIndex); - String title = (String) invocation.getArguments()[0]; - String msg = (String) invocation.getArguments()[1]; - String[] choices = (String[]) invocation.getArguments()[2]; - int defaultIndex = (int) invocation.getArguments()[3]; - return answerer.apply(title, msg, choices, defaultIndex); - } - }) - .when(ui) - .confirmOperation(any(), any(), any(), anyInt()); - } - - - - public void answerDeploymentPrompt(CfUserInteractions ui, final String appName, final String hostName, final List bindServices) throws Exception { - //TODO: replace this method with something more 'generic' that accepts a function which is passed the deploymentProperties - // so that it can add additional infos to it. - final String yaml = "applications:\n" + - "- name: "+appName+"\n" + - " host: "+hostName+"\n" + - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ \"jre\": { version: 11.+ } }'\n" + - createServicesBlock(bindServices); - - answerDeploymentPrompt(ui, new DeploymentAnswerer(yaml)); - } - - private String createServicesBlock(List bindServices) { - if (bindServices==null || bindServices.isEmpty()) { - return ""; - } - StringBuilder buf = new StringBuilder(" services:\n"); - for (String s : bindServices) { - buf.append(" - "+s+"\n"); - } - return buf.toString(); - } - - private String createEnvBlock(Map env) { - if (env==null || env.isEmpty()) { - return " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ \"jre\": { version: 11.+ } }'\n"; - } - StringBuilder buf = new StringBuilder( - " env:\n" + - " JBP_CONFIG_OPEN_JDK_JRE: '{ \"jre\": { version: 11.+ } }'\n" - ); - for (Entry e : env.entrySet()) { - buf.append(" "+e.getKey()+": "+e.getValue()); - } - return buf.toString(); - } - - public void answerDeploymentPrompt(CfUserInteractions ui, final String appName, final String hostName, final Map env) throws Exception { - String yaml = "applications:\n" + - "- name: "+appName+"\n" + - " host: "+hostName+"\n" + - createEnvBlock(env); - answerDeploymentPrompt(ui, new DeploymentAnswerer(yaml)); - } - - /** - * Does the same thing as what would happen if a user answered the deployment props dialog by selecting an - * existing manifest file. - */ - public void answerDeploymentPrompt(CfUserInteractions ui, IFile manifestToSelect) throws Exception { - String yaml = IOUtils.toString(manifestToSelect.getContents(), manifestToSelect.getCharset()); - answerDeploymentPrompt(ui, new DeploymentAnswerer(yaml) { - @Override - public void apply(CloudApplicationDeploymentProperties properties) throws Exception { - properties.setManifestFile(manifestToSelect); - } - }); - - } - - public void answerDeploymentPrompt(CfUserInteractions ui, DeploymentAnswerer answerer) throws Exception { - when(ui.promptApplicationDeploymentProperties(any(DeploymentPropertiesDialogModel.class))) - .thenAnswer(new Answer() { - @Override - public CloudApplicationDeploymentProperties answer(InvocationOnMock invocation) throws Throwable { - DeploymentPropertiesDialogModel dialog = (DeploymentPropertiesDialogModel) invocation.getArguments()[0]; - CloudApplicationDeploymentProperties deploymentProperties = dialog.getDeploymentProperties(answerer.yaml, answerer.appName); - answerer.apply(deploymentProperties); - return deploymentProperties; - } - - }); - } - - public String privateStoreKey(CloudFoundryBootDashModel target) { - return secureStoreKey(target)+":token"; - } - - public String secureStoreKey(CloudFoundryBootDashModel target) { - return target.getRunTarget().getType().getName()+":"+target.getRunTarget().getId(); - } - - public void answerPasswordPrompt(CfUserInteractions ui, PasswordAnswerer answerer) { - doAnswer(new Answer() { - @Override - public Boolean answer(InvocationOnMock invocation) throws Throwable { - PasswordDialogModel dialog = (PasswordDialogModel) invocation.getArguments()[0]; - answerer.apply(dialog); - return dialog.isOk(); - } - }).when(ui).openPasswordDialog(any(PasswordDialogModel.class)); - } - - public List getCfRunTargetModels() { - return getRunTargetModels(cfTargetType()); - } - - public CloudFoundryRunTargetType getCfTargetType() { - for (RunTargetType type : model.getRunTargetTypes()) { - if (type instanceof CloudFoundryRunTargetType) { - return (CloudFoundryRunTargetType) type; - } - } - return null; - } - - /** - * Raw fetch of environment variables (makes a request through the CF client, rather then get the cached data - * from the model). - */ - public Map fetchEnvironment(CloudFoundryBootDashModel model, String appName) throws Exception { - return model.getRunTarget().getClient().getApplication(appName).getEnvAsMap(); - } - - public LocalBootDashModel getLocalModel() { - return (LocalBootDashModel) getRunTargetModel(RunTargetTypes.LOCAL); - } - - public void answerManifestDiffDialog(CfUserInteractions ui, Function answerer) throws Exception { - when(ui.openManifestDiffDialog(any())) - .thenAnswer(new Answer() { - @Override - public ManifestDiffDialogModel.Result answer(InvocationOnMock invocation) throws Throwable { - Object[] args = invocation.getArguments(); - ManifestDiffDialogModel dialog = (ManifestDiffDialogModel) args[0]; - return answerer.apply(dialog); - } - }); - } - - public SecuredCredentialsStore getCredentialsStore() { - return context.getSecuredCredentialsStore(); - } - - public IPropertyStore getPrivateStore() { - return context.getPrivatePropertyStore(); - } - - public JmxSshTunnelManager getJmxSshTunnelManager() { - return context.injections.getBean(JmxSshTunnelManager.class); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/DeploymentPropertiesDialogModelTests.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/DeploymentPropertiesDialogModelTests.java deleted file mode 100644 index 1bfb5942c..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/DeploymentPropertiesDialogModelTests.java +++ /dev/null @@ -1,1237 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 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.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.springframework.ide.eclipse.boot.dash.test.BootDashModelTest.waitForJobsToComplete; -import static org.springsource.ide.eclipse.commons.tests.util.StsTestCase.createFile; - -import java.io.ByteArrayInputStream; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.UUID; -import java.util.stream.Collectors; - -import org.eclipse.core.filebuffers.FileBuffers; -import org.eclipse.core.filebuffers.ITextFileBufferManager; -import org.eclipse.core.filebuffers.LocationKind; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.source.Annotation; -import org.eclipse.lsp4e.LanguageServerWrapper; -import org.eclipse.lsp4e.LanguageServiceAccessor; -import org.eclipse.lsp4j.services.LanguageServer; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IFileEditorInput; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.editors.text.TextFileDocumentProvider; -import org.eclipse.ui.part.FileEditorInput; -import org.eclipse.ui.texteditor.DocumentProviderRegistry; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; -import org.mockito.Mockito; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFAppState; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFCloudDomainData; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFDomainStatus; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudData; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialog; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialogModel; -import org.springframework.ide.eclipse.boot.dash.cf.dialogs.DeploymentPropertiesDialogModel.ManifestType; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.model.UserInteractions; -import org.springframework.ide.eclipse.boot.test.BootProjectTestHarness; -import org.springframework.ide.eclipse.boot.test.util.TestBracketter; -import org.springsource.ide.eclipse.commons.frameworks.core.util.IOUtil; -import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition; -import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult; -import org.springsource.ide.eclipse.commons.livexp.util.Log; -import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil; - -import com.google.common.collect.ImmutableList; - -import junit.framework.AssertionFailedError; - - -/** - * Tests for {@link DeploymentPropertiesDialogModel} - * - * @author Alex Boyko - * - */ -@SuppressWarnings("restriction") -public class DeploymentPropertiesDialogModelTests { - - private static final String CF_SERVER_ID = "org.eclipse.languageserver.languages.cloudfoundrymanifest"; - - private static final long DISCONNECT_TIMEOUT = 10000; - - private static final long TIMEOUT = 3000; - - private static final int DONT_SAVE_BUTTON_ID = 1; - - private static final int SAVE_BUTTON_ID = 0; - - private static final String UNKNOWN_DEPLOYMENT_MANIFEST_TYPE_MUST_BE_EITHER_FILE_OR_MANUAL = "Unknown deployment manifest type. Must be either 'File' or 'Manual'."; - private static final String MANIFEST_DOES_NOT_CONTAIN_DEPLOYMENT_PROPERTIES_FOR_APPLICATION_WITH_NAME = "Manifest does not contain deployment properties for application with name ''{0}''."; - private static final String MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED = "Manifest does not have any application defined."; - private static final String ENTER_DEPLOYMENT_MANIFEST_YAML_MANUALLY = "Enter deployment manifest YAML manually."; - private static final String CURRENT_GENERATED_DEPLOYMENT_MANIFEST = "Current generated deployment manifest."; - private static final String CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM = "Choose an existing deployment manifest YAML file from the local file system."; - private static final String DEPLOYMENT_MANIFEST_FILE_NOT_SELECTED = "Deployment manifest file not selected."; - private static final String MANIFEST_YAML_ERRORS = "Deployment manifest YAML has errors."; - - public static final String DEFAULT_BUILDPACK = "java_buildpack_offline"; - - public static final List SPRING_CLOUD_DOMAINS = Arrays.asList(new CFCloudDomainData("springsource.org", CFDomainType.HTTP, CFDomainStatus.SHARED)); - - public static CloudData createCloudData() { - return new CloudData(SPRING_CLOUD_DOMAINS, DEFAULT_BUILDPACK, ImmutableList.of()); - } - - private static BootProjectTestHarness projects; - private static IProject dumbProject; - private UserInteractions ui; - private DeploymentPropertiesDialogModel model; - - private Shell shell; - - //////////////////////////////////////////////////////////// - - @Rule public TestName name = new TestName(); - @Rule public TestBracketter bracketer = new TestBracketter(); - - @BeforeClass - public static void beforeAll() throws Exception { - StsTestUtil.deleteAllProjects(); - waitForJobsToComplete(); - projects = new BootProjectTestHarness(ResourcesPlugin.getWorkspace()); - dumbProject = projects.createProject("dumbProject"); - IFile manifest = dumbProject.getFile("manifest.yml"); - manifest.create(new ByteArrayInputStream(new byte[0]), true, new NullProgressMonitor()); - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(new FileEditorInput(manifest), "CfManifestYMLEditor"); - waitForJobsToComplete(); - waitUntilFileConnected(manifest); - } - - @AfterClass - public static void afterAll() throws Exception { - StsTestUtil.deleteAllProjects(); - waitForJobsToComplete(); - waitForServerShutdown(); - } - - @Before - public void setup() throws Exception { - Log.info("STARTED test: " + name.getMethodName()); - StsTestUtil.deleteAllProjectsExcept(dumbProject.getName()); -// StsTestUtil.deleteAllProjects(); - this.ui = mock(UserInteractions.class); - } - - @After - public void tearDown() throws Exception { - if (shell != null) { - shell.dispose(); - } - waitForJobsToComplete(); - disposeModel(); -// LanguageServiceAccessor.clearStartedServers(); - waitForJobsToComplete(); -// Thread.sleep(3000); - Log.info("FINISHED test: " + name.getMethodName()); - } - - private static void waitForServerShutdown() throws Exception { - ACondition.waitFor("ls servers shutdown", DISCONNECT_TIMEOUT, () -> { - List servers = LanguageServiceAccessor.getActiveLanguageServers(x -> true); - assertTrue("still running server: "+servers, servers.isEmpty()); - }); - } - - private void disposeModel() throws Exception { - if (model != null) { - IEditorInput fileInput = model.getFileYamlEditor().getEditorInput(); - IEditorInput manualInput = model.getManualYamlEditor().getEditorInput(); - model.dispose(); - if (fileInput instanceof IFileEditorInput) { - List servers = getCfLanguageServers(((IFileEditorInput) fileInput).getFile(), null); - if (!servers.isEmpty()) { - waitUntilFileDisconnedted(((IFileEditorInput)fileInput).getFile()); - } - } - if (manualInput instanceof IFileEditorInput) { - List servers = getCfLanguageServers(((IFileEditorInput) manualInput).getFile(), null); - if (!servers.isEmpty()) { - waitUntilFileDisconnedted(((IFileEditorInput)manualInput).getFile()); - } - } - model = null; - waitForJobsToComplete(); - } - } - - private void waitUntilFileDisconnedted(IFile file) throws Exception { - waitForJobsToComplete(); - if (file.exists()) { - ACondition.waitFor(file.toString() + " disconnected from LS", DISCONNECT_TIMEOUT, () -> { - LanguageServerWrapper wrapper = getCfLanguageServer(file); - assertFalse(wrapper.isConnectedTo(file.getLocationURI())); - }); - } - FileEditorInput editorInput = new FileEditorInput(file); - TextFileDocumentProvider docProvider = (TextFileDocumentProvider) DocumentProviderRegistry.getDefault().getDocumentProvider(editorInput); - assertNull(docProvider.getDocument(editorInput)); - waitForJobsToComplete(); - ITextFileBufferManager textFileBufferManager = FileBuffers.getTextFileBufferManager(); -// textFileBufferManager.disconnect(file.getFullPath(), LocationKind.LOCATION, new NullProgressMonitor()); - assertNull(textFileBufferManager.getFileBuffer(file.getFullPath(), LocationKind.LOCATION)); - waitForJobsToComplete(); - } - - private static void waitUntilFileConnected(IFile file) throws Exception { - waitForJobsToComplete(); - ACondition.waitFor(file.toString() + " connected to LS", DISCONNECT_TIMEOUT, () -> { - LanguageServerWrapper wrapper = getCfLanguageServer(file); - assertTrue(wrapper.isConnectedTo(file.getLocationURI())); - }); - waitForJobsToComplete(); - } - - private static List getCfLanguageServers(IFile file, StringBuilder available ) throws Exception { - Collection wrappers = LanguageServiceAccessor.getLSWrappers(file, cap -> true); - List found = new ArrayList<>(); - for (LanguageServerWrapper wrapper : wrappers) { - if (CF_SERVER_ID.equals(wrapper.serverDefinition.id)) { - found.add(wrapper); - } - if (available!=null) { - available.append(wrapper.serverDefinition.id+" "); - } - } - return found; - } - - private static LanguageServerWrapper getCfLanguageServer(IFile file) throws Exception { - StringBuilder available = new StringBuilder(); - List found = getCfLanguageServers(file, available); - if (found.isEmpty()) { - throw new NoSuchElementException("No CF language server wrapper found in: [ "+available+"]"); - } else if (found.size()>1) { - throw new AssertionFailedError( - "Found more than one ls: "+ - found.stream() - .map(w -> w.serverDefinition.id) - .collect(Collectors.toList()) - ); - } - return found.get(0); - } - - private void createDialogModel(IProject project, CFApplication deployedApp) throws Exception { - model = new DeploymentPropertiesDialogModel(ui, createCloudData(), project, deployedApp, true); - model.initFileModel(); - model.initManualModel(); - shell = new Shell(PlatformUI.getWorkbench().getDisplay()); - shell.setSize(400, 400); - shell.open(); - try { - model.getFileYamlEditor().setContext(DeploymentPropertiesDialog.CONTEXT_DEPLOYMENT_PROPERTIES_DIALOG); - model.getManualYamlEditor().setContext(DeploymentPropertiesDialog.CONTEXT_DEPLOYMENT_PROPERTIES_DIALOG); - model.getFileYamlEditor().createControl(shell); - model.fileYamlEditorControlCreated(); - model.getManualYamlEditor().createControl(shell); - model.manualYamlEditorControlCreated(); - waitUntilFileConnected(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - waitUntilFileConnected(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_MANUAL_MANIFEST_YML)); - } catch (CoreException e) { - Log.log(e); - } - } - - private static CFApplication createCfApp(String name, int memory) { - CFApplication cfApp = mock(CFApplication.class); - Mockito.when(cfApp.getName()).thenReturn(name); - Mockito.when(cfApp.getMemory()).thenReturn(memory); - Mockito.when(cfApp.getBuildpackUrl()).thenReturn(DEFAULT_BUILDPACK); - Mockito.when(cfApp.getCommand()).thenReturn(null); - Mockito.when(cfApp.getDiskQuota()).thenReturn(DeploymentProperties.DEFAULT_MEMORY); - Mockito.when(cfApp.getEnvAsMap()).thenReturn(Collections.emptyMap()); - Mockito.when(cfApp.getGuid()).thenReturn(UUID.randomUUID()); - Mockito.when(cfApp.getInstances()).thenReturn(DeploymentProperties.DEFAULT_INSTANCES); - Mockito.when(cfApp.getRunningInstances()).thenReturn(DeploymentProperties.DEFAULT_INSTANCES); - Mockito.when(cfApp.getServices()).thenReturn(Collections.emptyList()); - Mockito.when(cfApp.getStack()).thenReturn(null); - Mockito.when(cfApp.getState()).thenReturn(CFAppState.STARTED); - Mockito.when(cfApp.getTimeout()).thenReturn(null); - Mockito.when(cfApp.getUris()).thenReturn(Arrays.asList(new String[] {"myapp." + SPRING_CLOUD_DOMAINS.get(0).getName()})); - return cfApp; - } - - - /** - * Select manifest in the model and wait for cf editor to connect, - */ - private void selectAndWait(IFile manifest) throws Exception { - model.setSelectedManifest(manifest); - waitUntilFileConnected(manifest); - } - - //////////////////////////////////////////////////////////////////// - - @Test public void testNoTypeSelected() throws Exception { - IProject project = projects.createProject("p1"); - createDialogModel(project, null); - - assertFalse(model.isManualManifestType()); - assertFalse(model.isFileManifestType()); - - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(UNKNOWN_DEPLOYMENT_MANIFEST_TYPE_MUST_BE_EITHER_FILE_OR_MANUAL, validationResult.msg); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertTrue(deploymentProperties == null); - } - - @Test public void testManualTypeSelected() throws Exception { - IProject project = projects.createProject("p1"); - createDialogModel(project, null); - model.type.setValue(ManifestType.MANUAL); - - assertTrue(model.isManualManifestType()); - assertFalse(model.isManualManifestReadOnly()); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(ENTER_DEPLOYMENT_MANIFEST_YAML_MANUALLY, validationResult.msg); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(project.getName(), model.getManualSelectedAppName())); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertNotNull(deploymentProperties); - assertEquals(project.getName(), deploymentProperties.getAppName()); - } - - @Test public void testManualTypeForDeployedApp() throws Exception { - IProject project = projects.createProject("p1"); - CFApplication deployedApp = createCfApp("my-test-app", 512); - - createDialogModel(project, deployedApp); - model.type.setValue(ManifestType.MANUAL); - - assertTrue(model.isManualManifestType()); - assertTrue(model.isManualManifestReadOnly()); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CURRENT_GENERATED_DEPLOYMENT_MANIFEST, validationResult.msg); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(deployedApp.getName(), model.getManualSelectedAppName())); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertNotNull(deploymentProperties); - assertEquals(deploymentProperties.getAppName(), deployedApp.getName()); - assertEquals(deployedApp.getMemory(), deploymentProperties.getMemory()); - } - - @Test(expected = IllegalStateException.class) - public void testManualTypeManifestTextWhenAppDeployed() throws Exception { - IProject project = projects.createProject("p1"); - CFApplication deployedApp = createCfApp("my-test-app", 512); - - createDialogModel(project, deployedApp); - model.type.setValue(ManifestType.MANUAL); - - assertTrue(model.isManualManifestType()); - assertTrue(model.isManualManifestReadOnly()); - - model.setManualManifest("some text"); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED, validationResult.msg); - assertEquals(IStatus.ERROR, validationResult.status); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(null, model.getManualSelectedAppName())); - } - - @Test public void testManualTypeSetManifestText() throws Exception { - IProject project = projects.createProject("p1"); - createDialogModel(project, null); - model.type.setValue(ManifestType.MANUAL); - - assertTrue(model.isManualManifestType()); - assertFalse(model.isManualManifestReadOnly()); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(ENTER_DEPLOYMENT_MANIFEST_YAML_MANUALLY, validationResult.msg); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(project.getName(), model.getManualSelectedAppName())); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertNotNull(deploymentProperties); - assertEquals(project.getName(), deploymentProperties.getAppName()); - assertNull(deploymentProperties.getManifestFile()); - - String newText = "Some text"; - model.setManualManifest(newText); - assertEquals(newText, model.getManualDocument().get()); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED, validationResult.msg); - }); - } - - @Test public void testFileManifestFileNotSelected() throws Exception { - IProject project = projects.createProject("p1"); - createDialogModel(project, null); - model.type.setValue(ManifestType.FILE); - // With LS approach there would be annotation model for dumb manifest yaml file - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(DEPLOYMENT_MANIFEST_FILE_NOT_SELECTED, validationResult.msg); - }); - } - - @Test public void testFileManifestNonYamlFileSelected() throws Exception { - IProject project = projects.createProject("p1"); - IFile file = createFile(project, "manifest.yml", "Some text content!"); - createDialogModel(project, null); - model.type.setValue(ManifestType.FILE); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - - ACondition.waitFor("reconcile to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED, validationResult.msg); - }); - } - - @Test public void testFileManifestFolderSelected() throws Exception { - IProject project = projects.createProject("p1"); - createDialogModel(project, null); - model.type.setValue(ManifestType.FILE); - model.setSelectedManifest(project); - - ACondition.waitFor("reconcile to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(DEPLOYMENT_MANIFEST_FILE_NOT_SELECTED, validationResult.msg); - }); - } - - @Test public void testFileManifestFileSelected() throws Exception { - IProject project = projects.createProject("p1"); - String appNameFromFile = "app-name-from-file"; - IFile file = createFile(project, "manifest.yml", - "applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: 512M\n" - ); - createDialogModel(project, null); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - model.type.setValue(ManifestType.FILE); - - ACondition.waitFor("reconcile to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - System.out.println("DOC: " + model.getFileDocument().get()); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - assertEquals(IStatus.INFO, validationResult.status); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(appNameFromFile, model.getFileSelectedAppName())); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertNotNull(deploymentProperties); - assertEquals(appNameFromFile, deploymentProperties.getAppName()); - IFile manifestFile = deploymentProperties.getManifestFile(); - assertNotNull(manifestFile); - assertEquals("manifest.yml", manifestFile.getName()); - } - - @Test public void testSwitchingManifestTypeAndFiles() throws Exception { - IProject project = projects.createProject("p1"); - String appNameFromFile = "app-name-from-file"; - IFile validFile = createFile(project, "manifest.yml", - "applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: 512M\n" - ); - IFile invalidFile = createFile(project, "text.yml", "Some text"); - - createDialogModel(project, null); - model.type.setValue(ManifestType.MANUAL); - waitForJobsToComplete(); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(ENTER_DEPLOYMENT_MANIFEST_YAML_MANUALLY, validationResult.msg); - }); - - model.type.setValue(ManifestType.FILE); - waitForJobsToComplete(); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(DEPLOYMENT_MANIFEST_FILE_NOT_SELECTED, validationResult.msg); - }); - - selectAndWait(validFile); - waitForJobsToComplete(); - System.out.println("New manifest set"); - System.out.println(model.getFileYamlEditor().getViewer().getDocument().get()); - System.out.println("Before conditional wait"); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - System.out.println(model.getFileYamlEditor().getViewer().getDocument().get()); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - }); - - model.type.setValue(ManifestType.MANUAL); - waitForJobsToComplete(); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(ENTER_DEPLOYMENT_MANIFEST_YAML_MANUALLY, validationResult.msg); - }); - - model.type.setValue(ManifestType.FILE); - waitForJobsToComplete(); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - }); - - model.setSelectedManifest(project); - waitForJobsToComplete(); - waitUntilFileDisconnedted(validFile); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(DEPLOYMENT_MANIFEST_FILE_NOT_SELECTED, validationResult.msg); - }); - - model.setSelectedManifest(invalidFile); - waitForJobsToComplete(); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED, validationResult.msg); - }); - } - - @Test public void testValidSingleAppFileSelectedForDeployedApp() throws Exception { - String appName = "my-test-app"; - IProject project = projects.createProject("p1"); - CFApplication deployedApp = createCfApp(appName, 512); - - IFile validFileSingleName = createFile(project, "manifest.yml", - "applications:\n" + - "- name: " + appName + "\n" + - " memory: 512M\n" - ); - - createDialogModel(project, deployedApp); - model.type.setValue(ManifestType.FILE); - waitForJobsToComplete(); - - selectAndWait(validFileSingleName); - waitForJobsToComplete(); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - }); - } - - @Test public void testInvalidSingleAppFileSelectedForDeployedApp() throws Exception { - String appName = "my-test-app"; - IProject project = projects.createProject("p1"); - CFApplication deployedApp = createCfApp(appName, 512); - - IFile invalidFileSingleName = createFile(project, "manifest.yml", - "applications:\n" + - "- name: someApp\n" + - " memory: 512M\n" - ); - - createDialogModel(project, deployedApp); - model.type.setValue(ManifestType.FILE); - - selectAndWait(invalidFileSingleName); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MessageFormat.format(MANIFEST_DOES_NOT_CONTAIN_DEPLOYMENT_PROPERTIES_FOR_APPLICATION_WITH_NAME, appName), validationResult.msg); - }); - } - - @Test public void testValidMultiAppFileSelectedForDeployedApp() throws Exception { - String appName = "my-test-app"; - IProject project = projects.createProject("p1"); - CFApplication deployedApp = createCfApp(appName, 512); - - IFile validFileMultiName = createFile(project, "manifest.yml", - "applications:\n" + - "- name: " + project.getName() + "\n" + - " memory: 512M\n" + - "- name: " + appName + "\n" + - " memory: 512M\n" + - "- name: someApp\n" + - " memory: 512M\n" - ); - - createDialogModel(project, deployedApp); - model.type.setValue(ManifestType.FILE); - - selectAndWait(validFileMultiName); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(deployedApp.getName(), model.getFileSelectedAppName())); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertNotNull(deploymentProperties); - assertEquals(deployedApp.getName(), deploymentProperties.getAppName()); - } - - @Test public void testInvalidMultiAppFileSelectedForDeployedApp() throws Exception { - String appName = "my-test-app"; - IProject project = projects.createProject("p1"); - CFApplication deployedApp = createCfApp(appName, 512); - - IFile invalidFileMultiName = createFile(project, "manifest.yml", - "applications:\n" + - "- name: " + project.getName() + "\n" + - " memory: 512M\n" + - "- name: anotherApp\n" + - " memory: 512M\n" + - "- name: someApp\n" + - " memory: 512M\n" - ); - - createDialogModel(project, deployedApp); - model.type.setValue(ManifestType.FILE); - - selectAndWait(invalidFileMultiName); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MessageFormat.format(MANIFEST_DOES_NOT_CONTAIN_DEPLOYMENT_PROPERTIES_FOR_APPLICATION_WITH_NAME, appName), validationResult.msg); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(null, model.getFileSelectedAppName())); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertNull(deploymentProperties); - } - - @Test public void testSwitchingWithDeployedApp() throws Exception { - String appName = "my-test-app"; - IProject project = projects.createProject("p1"); - CFApplication deployedApp = createCfApp(appName, 512); - - IFile validFileMultiName = createFile(project, "valid-manifest.yml", - "applications:\n" + - "- name: " + project.getName() + "\n" + - " memory: 512M\n" + - "- name: " + appName + "\n" + - " memory: 512M\n" + - "- name: someApp\n" + - " memory: 512M\n" - ); - - IFile invalidFileMultiName = createFile(project, "invalid-manifest.yml", - "applications:\n" + - "- name: " + project.getName() + "\n" + - " memory: 512M\n" + - "- name: anotherApp\n" + - " memory: 512M\n" + - "- name: someApp\n" + - " memory: 512M\n" - ); - - createDialogModel(project, deployedApp); - - model.type.setValue(ManifestType.FILE); - selectAndWait(validFileMultiName); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(appName, model.getFileSelectedAppName())); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - }); - - selectAndWait(invalidFileMultiName); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(null, model.getFileSelectedAppName())); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MessageFormat.format(MANIFEST_DOES_NOT_CONTAIN_DEPLOYMENT_PROPERTIES_FOR_APPLICATION_WITH_NAME, appName), validationResult.msg); - }); - - model.setSelectedManifest(project); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(DEPLOYMENT_MANIFEST_FILE_NOT_SELECTED, validationResult.msg); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(null, model.getFileSelectedAppName())); - - model.type.setValue(ManifestType.MANUAL); - assertTrue(model.isManualManifestReadOnly()); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(appName, model.getManualSelectedAppName())); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CURRENT_GENERATED_DEPLOYMENT_MANIFEST, validationResult.msg); - }); - - selectAndWait(invalidFileMultiName); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(null, model.getFileSelectedAppName())); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CURRENT_GENERATED_DEPLOYMENT_MANIFEST, validationResult.msg); - }); - - model.type.setValue(ManifestType.FILE); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MessageFormat.format(MANIFEST_DOES_NOT_CONTAIN_DEPLOYMENT_PROPERTIES_FOR_APPLICATION_WITH_NAME, appName), validationResult.msg); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(null, model.getFileSelectedAppName())); - } - - @Test(expected = OperationCanceledException.class) - public void testCancel() throws Exception { - IProject project = projects.createProject("p1"); - createDialogModel(project, null); - model.type.setValue(ManifestType.MANUAL); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(ENTER_DEPLOYMENT_MANIFEST_YAML_MANUALLY, validationResult.msg); - }); - - model.cancelPressed(); - - assertTrue(model.isCanceled()); - - model.getDeploymentProperties(); - } - - @Test public void testManifestFileLabel() throws Exception { - IProject project = projects.createProject("p1"); - String appNameFromFile = "app-name-from-file"; - IFile file = createFile(project, "manifest.yml", - "applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: 512M\n" - ); - createDialogModel(project, null); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - model.setManifestType(ManifestType.FILE); - - assertEquals(file.getFullPath().toOSString(), model.getFileLabel().getValue()); - - model.getFileDocument().set("some text"); - - assertEquals(file.getFullPath().toOSString() + "*", model.getFileLabel().getValue()); - } - - @Test public void testDiscardCancelWithDirtyManifestFile() throws Exception { - IProject project = projects.createProject("p1"); - String appNameFromFile = "app-name-from-file"; - String text = "applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: 512M\n"; - IFile file = createFile(project, "manifest.yml", text); - createDialogModel(project, null); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - - model.setManifestType(ManifestType.FILE); - - model.getFileDocument().set("some text"); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED, validationResult.msg); - }); - - Mockito.when(ui.confirmOperation(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.anyInt())).thenReturn(DONT_SAVE_BUTTON_ID); - - model.cancelPressed(); - waitForJobsToComplete(); - - assertTrue(model.isCanceled()); - assertEquals(text, IOUtil.toString(file.getContents())); - - /* - * Test document provider is not connected to the file input anymore - */ -// disposeModel(); -// FileEditorInput editorInput = new FileEditorInput(file); -// TextFileDocumentProvider docProvider = (TextFileDocumentProvider) DocumentProviderRegistry.getDefault().getDocumentProvider(editorInput); -// assertNull(docProvider.getDocument(editorInput)); - } - - @Test public void testErrorsInYaml() throws Exception { - IProject project = projects.createProject("p1"); - String appNameFromFile = "app-name-from-file"; - String text = "applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: 512M\n"; - IFile file = createFile(project, "manifest.yml", text); - createDialogModel(project, null); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - model.setManifestType(ManifestType.FILE); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - }); - - model.getFileDocument().set("applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: 512MXX\n"); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MANIFEST_YAML_ERRORS, validationResult.msg); - }); - - } - - @Test public void testSaveCancelWithDirtyManifestFile() throws Exception { - IProject project = projects.createProject("p1"); - String appNameFromFile = "app-name-from-file"; - String text = "applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: 512M\n"; - IFile file = createFile(project, "manifest.yml", text); - createDialogModel(project, null); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - model.setManifestType(ManifestType.FILE); - - String newText = "some text"; - model.getFileDocument().set(newText); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED, validationResult.msg); - assertEquals(IStatus.ERROR, validationResult.status); - }); - - Mockito.when(ui.confirmOperation(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.anyInt())).thenReturn(SAVE_BUTTON_ID); - - model.cancelPressed(); - - assertTrue(model.isCanceled()); - assertEquals(newText, IOUtil.toString(file.getContents())); - - /* - * Test document provider is not connected to the file input anymore - */ -// disposeModel(); -// FileEditorInput editorInput = new FileEditorInput(file); -// TextFileDocumentProvider docProvider = (TextFileDocumentProvider) DocumentProviderRegistry.getDefault().getDocumentProvider(editorInput); -// assertNull(docProvider.getDocument(editorInput)); - } - - @Test public void testDiscardOkWithDirtyManifestFile() throws Exception { - IProject project = projects.createProject("p1"); - String appNameFromFile = "app-name-from-file"; - int memory = 512; - String text = "applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: " + memory + "M\n"; - IFile file = createFile(project, "manifest.yml", text); - createDialogModel(project, null); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - model.setManifestType(ManifestType.FILE); - - int newMemory = 256; - String newText = "applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: " + newMemory + "M\n"; - model.getFileDocument().set(newText); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - assertEquals(IStatus.INFO, validationResult.status); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(appNameFromFile, model.getFileSelectedAppName())); - - Mockito.when(ui.confirmOperation(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.anyInt())).thenReturn(DONT_SAVE_BUTTON_ID); - - model.okPressed(); - - assertFalse(model.isCanceled()); - assertEquals(text, IOUtil.toString(file.getContents())); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertNotNull(deploymentProperties); - assertEquals(appNameFromFile, deploymentProperties.getAppName()); - assertEquals(newMemory, deploymentProperties.getMemory()); - - - /* - * Test document provider is not connected to the file input anymore - */ -// disposeModel(); -// FileEditorInput editorInput = new FileEditorInput(file); -// TextFileDocumentProvider docProvider = (TextFileDocumentProvider) DocumentProviderRegistry.getDefault().getDocumentProvider(editorInput); -// assertNull(docProvider.getDocument(editorInput)); - } - - @Test public void testSaveOkWithDirtyManifestFile() throws Exception { - IProject project = projects.createProject("p1"); - String appName = "app-name-from-file"; - int memory = 512; - String text = "applications:\n" + - "- name: " + appName + "\n" + - " memory: " + memory + "M\n"; - String newAppName = "new-app"; - int newMemory = 768; - String newText = "applications:\n" + - "- name: " + newAppName + "\n" + - " memory: " + newMemory + "M\n"; - - IFile file = createFile(project, "manifest.yml", text); - createDialogModel(project, null); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - model.setManifestType(ManifestType.FILE); - - model.getFileDocument().set(newText); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - assertEquals(IStatus.INFO, validationResult.status); - }); - - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(newAppName, model.getFileSelectedAppName())); - - Mockito.when(ui.confirmOperation(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.anyInt())).thenReturn(SAVE_BUTTON_ID); - - model.okPressed(); - - assertFalse(model.isCanceled()); - assertEquals(newText, IOUtil.toString(file.getContents())); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertNotNull(deploymentProperties); - assertEquals(newAppName, deploymentProperties.getAppName()); - assertEquals(newMemory, deploymentProperties.getMemory()); - - /* - * Test document provider is not connected to the file input anymore - */ -// disposeModel(); -// FileEditorInput editorInput = new FileEditorInput(file); -// TextFileDocumentProvider docProvider = (TextFileDocumentProvider) DocumentProviderRegistry.getDefault().getDocumentProvider(editorInput); -// assertNull(docProvider.getDocument(editorInput)); - - } - - @Test public void testDiscardOnDirtyManifestFileSwitch() throws Exception { - IProject project = projects.createProject("p1"); - String appNameFromFile = "app-name-from-file"; - int memory = 512; - String text = "applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: " + memory + "M\n"; - IFile file = createFile(project, "manifest.yml", text); - createDialogModel(project, null); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - model.setManifestType(ManifestType.FILE); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - assertEquals(IStatus.INFO, validationResult.status); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(appNameFromFile, model.getFileSelectedAppName())); - - model.getFileDocument().set("some text"); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(MANIFEST_DOES_NOT_HAVE_ANY_APPLICATION_DEFINED, validationResult.msg); - assertEquals(IStatus.ERROR, validationResult.status); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(null, model.getFileSelectedAppName())); - - Mockito.when(ui.confirmOperation(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.anyInt())).thenReturn(DONT_SAVE_BUTTON_ID); - - model.setSelectedManifest(project); - waitUntilFileDisconnedted(file); - - assertEquals(text, IOUtil.toString(file.getContents())); - - selectAndWait(file); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(appNameFromFile, model.getFileSelectedAppName())); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - assertEquals(IStatus.INFO, validationResult.status); - }); - - assertEquals(text, model.getFileDocument().get()); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertNotNull(deploymentProperties); - assertEquals(appNameFromFile, deploymentProperties.getAppName()); - assertEquals(memory, deploymentProperties.getMemory()); - } - - @Test public void testSaveOnDirtyManifestFileSwitch() throws Exception { - IProject project = projects.createProject("p1"); - String appName = "app-name-from-file"; - int memory = 512; - String text = "applications:\n" + - "- name: " + appName + "\n" + - " memory: " + memory + "M\n"; - String newAppName = "new-app"; - int newMemory = 768; - String newText = "applications:\n" + - "- name: " + newAppName + "\n" + - " memory: " + newMemory + "M\n"; - - IFile file = createFile(project, "manifest.yml", text); - createDialogModel(project, null); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - model.setManifestType(ManifestType.FILE); - - model.getFileDocument().set(newText); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - assertEquals(IStatus.INFO, validationResult.status); - }); - - Mockito.when(ui.confirmOperation(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.anyInt())).thenReturn(SAVE_BUTTON_ID); - - model.setSelectedManifest(project); - waitUntilFileDisconnedted(file); - - assertEquals(newText, IOUtil.toString(file.getContents())); - - selectAndWait(file); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - assertEquals(IStatus.INFO, validationResult.status); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(newAppName, model.getFileSelectedAppName())); - - assertEquals(newText, model.getFileDocument().get()); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertNotNull(deploymentProperties); - assertEquals(newAppName, deploymentProperties.getAppName()); - assertEquals(newMemory, deploymentProperties.getMemory()); - } - - @Test public void testRecoverFromInvalidManifest() throws Exception { - IProject project = projects.createProject("p1"); - String newAppName = "new-app"; - int newMemory = 768; - String newText = "applications:\n" + - "- name: " + newAppName + "\n" + - " memory: " + newMemory + "M\n"; - - IFile file = createFile(project, "manifest.yml", ""); - createDialogModel(project, null); - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - model.setManifestType(ManifestType.FILE); - - model.getFileDocument().set(newText); - assertTrue(model.getFileLabel().getValue().endsWith("*")); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - assertEquals(IStatus.INFO, validationResult.status); - }); - - Mockito.when(ui.confirmOperation(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.anyInt())).thenReturn(DONT_SAVE_BUTTON_ID); - - model.okPressed(); - - assertFalse(model.isCanceled()); - assertEquals("", IOUtil.toString(file.getContents())); - assertTrue(model.getFileLabel().getValue().endsWith("*")); - - - // Input disconnect at this point - needs to be reset as well. - model.setSelectedManifest(null); - waitUntilFileDisconnedted(file); - selectAndWait(file); - model.getFileDocument().set(newText); - assertTrue(model.getFileLabel().getValue().endsWith("*")); - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - assertEquals(IStatus.INFO, validationResult.status); - }); - ACondition.waitFor("app name reconcile", TIMEOUT, () -> assertEquals(newAppName, model.getFileSelectedAppName())); - - Mockito.reset(ui); - Mockito.when(ui.confirmOperation(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.anyInt())).thenReturn(SAVE_BUTTON_ID); - - model.okPressed(); - - assertFalse(model.isCanceled()); - assertEquals(newText, IOUtil.toString(file.getContents())); - - CloudApplicationDeploymentProperties deploymentProperties = model.getDeploymentProperties(); - assertEquals(newAppName, deploymentProperties.getAppName()); - assertEquals(newMemory, deploymentProperties.getMemory()); - - /* - * Test document provider is not connected to the file input anymore - */ -// disposeModel(); -// FileEditorInput editorInput = new FileEditorInput(file); -// TextFileDocumentProvider docProvider = (TextFileDocumentProvider) DocumentProviderRegistry.getDefault().getDocumentProvider(editorInput); -// assertNull(docProvider.getDocument(editorInput)); - - } - - @Test public void testManualManifestYamlError() throws Exception { - IProject project = projects.createProject("p1"); - createDialogModel(project, null); - // Set resource annotation model -// model.setManualResourceAnnotationModel(new AnnotationModel()); - model.type.setValue(ManifestType.MANUAL); - - assertTrue(model.isManualManifestType()); - assertFalse(model.isManualManifestReadOnly()); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(ENTER_DEPLOYMENT_MANIFEST_YAML_MANUALLY, validationResult.msg); - }); - - Annotation resourceAnnotation = new Annotation(DeploymentPropertiesDialogModel.LSP_ERROR_ANNOTATION_TYPE, false, "Some error"); - model.getManualResourceAnnotationModel().addAnnotation(resourceAnnotation, new Position(0,0)); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MANIFEST_YAML_ERRORS, validationResult.msg); - }); - - model.getManualResourceAnnotationModel().removeAnnotation(resourceAnnotation); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(ENTER_DEPLOYMENT_MANIFEST_YAML_MANUALLY, validationResult.msg); - }); - } - - @Test public void testFileManifestYamlError() throws Exception { - IProject project = projects.createProject("p1"); - String appNameFromFile = "app-name-from-file"; - IFile file = createFile(project, "manifest.yml", - "applications:\n" + - "- name: " + appNameFromFile + "\n" + - " memory: 512M\n" - ); - createDialogModel(project, null); - // Set resource annotation model - selectAndWait(file); - waitUntilFileDisconnedted(project.getFolder(".settings").getFile(DeploymentPropertiesDialogModel.DUMMY_FILE_MANIFEST_YML)); - model.type.setValue(ManifestType.FILE); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - }); - - Annotation resourceAnnotation = new Annotation(DeploymentPropertiesDialogModel.LSP_ERROR_ANNOTATION_TYPE, false, "Some error"); - model.getFileResourceAnnotationModel().addAnnotation(resourceAnnotation, new Position(0,0)); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.ERROR, validationResult.status); - assertEquals(MANIFEST_YAML_ERRORS, validationResult.msg); - }); - - model.getFileResourceAnnotationModel().removeAnnotation(resourceAnnotation); - - ACondition.waitFor("validation to occur", TIMEOUT, () -> { - ValidationResult validationResult = model.getValidator().getValue(); - assertEquals(IStatus.INFO, validationResult.status); - assertEquals(CHOOSE_AN_EXISTING_DEPLOYMENT_MANIFEST_YAML_FILE_FROM_THE_LOCAL_FILE_SYSTEM, validationResult.msg); - }); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/JarNameGeneratorTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/JarNameGeneratorTest.java deleted file mode 100644 index 9f52ddee8..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/JarNameGeneratorTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.test; - -import java.io.File; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jdt.core.JavaCore; -import org.springframework.ide.eclipse.boot.dash.cf.packaging.JarNameGenerator; -import org.springframework.ide.eclipse.boot.util.JavaProjectUtil; -import org.springsource.ide.eclipse.commons.tests.util.StsTestCase; - -public class JarNameGeneratorTest extends StsTestCase { - - private JarNameGenerator ng = new JarNameGenerator(); - - public void testNamesForJars() { - - assertName("foo-1.2.3.jar", "/home/someplace/foo-1.2.3.jar"); - assertName("foo-1.2.3-1.jar", "/home/some-other-place/foo-1.2.3.jar"); - assertName("foo-1.2.3-2.jar", "/home/and-yet-another/foo-1.2.3.jar"); - - //counters are per-name not per JarNameGenerator instance? - assertName("bar.jar", "/home/bar.jar"); - assertName("bar-1.jar", "/away/bar.jar"); - - //Tolerate '.JAR' in upper case? - - assertName("case-nutter.jar", "/somewhere/case-nutter.JAR"); - assertName("case-nutter-1.jar", "/elsewhere/case-nutter.JAR"); - } - - public void testNamesForProjectFolders() throws Exception { - IProject p = createPredefinedProject("demo-lib"); - IContainer _outputFolder = JavaProjectUtil.getDefaultOutputFolder(JavaCore.create(p)); - File outputFolder = _outputFolder.getLocation().toFile(); - - assertName("demo-lib.jar", outputFolder); - assertName("demo-lib-1.jar", outputFolder); - assertName("demo-lib-2.jar", outputFolder); - } - - public void testNamesForNestedProjectFolders() throws Exception { - IProject p = createPredefinedProject("demo-lib"); - - String nestedName = "nested"; - IProject nested = createGeneralProject(p, nestedName, p.getLocation().append(nestedName)); - - File dep = nested.getLocation().toFile(); - - //The next bit is to check that this is actually a good test. I.e. - // We do in fact have a situation where a nested project implies that several resources in the - // workspace represent the same folder on disk. - IContainer[] containers = getWSRoot().findContainersForLocationURI(dep.toURI()); - assertEquals(2, containers.length); - - //Now check that it makes the right choice and names the jar after 'nested' not after 'demo-lib'. - assertName("nested.jar", dep); - assertName("nested-1.jar", dep); - assertName("nested-2.jar", dep); - } - - protected IProject createGeneralProject(IProject p, String name, IPath loc) throws CoreException { - IProjectDescription desc = getWorkspace().newProjectDescription(name); - IProject nested = getProject(name); - desc.setLocation(loc); - nested.create(desc, new NullProgressMonitor()); - return nested; - } - - private IProject getProject(String name) { - return getWSRoot().getProject(name); - } - - protected IWorkspaceRoot getWSRoot() { - return getWorkspace().getRoot(); - } - - protected IWorkspace getWorkspace() { - return ResourcesPlugin.getWorkspace(); - } - - private void assertName(String expectedName, File dep) { - assertEquals(expectedName, ng.createName(dep)); - } - - private void assertName(String expectedName, String depPath) { - assertName(expectedName, new File(depPath)); - } - - @Override - protected String getBundleName() { - return BootDashTestBundleConstants.BUNDLE_ID; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/JmxSupportTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/JmxSupportTest.java deleted file mode 100644 index 49d30a70f..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/JmxSupportTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 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.test; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Test; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshTunnelFactory; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.JmxSshTunnelManager; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.JmxSupport; -import org.springframework.ide.eclipse.boot.dash.cf.model.CloudAppDashElement; -import org.springframework.ide.eclipse.boot.dash.model.RunState; -import org.springframework.ide.eclipse.boot.dash.test.mocks.MockSshTunnel; -import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; - -public class JmxSupportTest { - - CloudAppDashElement cde = mock(CloudAppDashElement.class); - JmxSshTunnelManager tunnels = new JmxSshTunnelManager(); - SshTunnelFactory tunnelFactory = MockSshTunnel::new; - - @Test - public void setupEnvVars() throws Exception { - int testPort = 1234; - when(cde.getBaseRunStateExp()).thenReturn(LiveExpression.constant(RunState.INACTIVE)); - JmxSupport jmx = new JmxSupport(cde, tunnels, tunnelFactory) { - public int getPort() {return testPort; } - }; - - Map env = new HashMap<>(); - jmx.setupEnvVars(env); - - assertEquals( - "-Dcom.sun.management.jmxremote.ssl=false " - + "-Dcom.sun.management.jmxremote.authenticate=false " - + "-Dcom.sun.management.jmxremote.port=1234 " - + "-Dcom.sun.management.jmxremote.rmi.port=1234 " - + "-Djava.rmi.server.hostname=localhost " - + "-Dcom.sun.management.jmxremote.local.only=false " - + "-Dspring.jmx.enabled=true" - + "-Dmanagement.endpoints.jmx.exposure.include=*", - env.get("JAVA_OPTS")); - - jmx.setupEnvVars(env); // should erase old and recreate - assertEquals( - "-Dcom.sun.management.jmxremote.ssl=false " - + "-Dcom.sun.management.jmxremote.authenticate=false " - + "-Dcom.sun.management.jmxremote.port=1234 " - + "-Dcom.sun.management.jmxremote.rmi.port=1234 " - + "-Djava.rmi.server.hostname=localhost " - + "-Dcom.sun.management.jmxremote.local.only=false " - + "-Dspring.jmx.enabled=true" - + "-Dmanagement.endpoints.jmx.exposure.include=*", - env.get("JAVA_OPTS")); - } - - @Test - public void setupEnvVars_preserve_unrelated_java_opts() throws Exception { - int testPort = 1234; - when(cde.getBaseRunStateExp()).thenReturn(LiveExpression.constant(RunState.INACTIVE)); - JmxSupport jmx = new JmxSupport(cde, tunnels, tunnelFactory) { - public int getPort() {return testPort; } - }; - - Map env = new HashMap<>(); - env.put("JAVA_OPTS", "-Dsomething.already=here"); - jmx.setupEnvVars(env); - - assertEquals("-Dsomething.already=here " - + "-Dcom.sun.management.jmxremote.ssl=false " - + "-Dcom.sun.management.jmxremote.authenticate=false " - + "-Dcom.sun.management.jmxremote.port=1234 " - + "-Dcom.sun.management.jmxremote.rmi.port=1234 " - + "-Djava.rmi.server.hostname=localhost " - + "-Dcom.sun.management.jmxremote.local.only=false " - + "-Dspring.jmx.enabled=true" - + "-Dmanagement.endpoints.jmx.exposure.include=*", - env.get("JAVA_OPTS")); - - jmx.setupEnvVars(env); // should erase old and recreate - assertEquals("-Dsomething.already=here " - + "-Dcom.sun.management.jmxremote.ssl=false " - + "-Dcom.sun.management.jmxremote.authenticate=false " - + "-Dcom.sun.management.jmxremote.port=1234 " - + "-Dcom.sun.management.jmxremote.rmi.port=1234 " - + "-Djava.rmi.server.hostname=localhost " - + "-Dcom.sun.management.jmxremote.local.only=false " - + "-Dspring.jmx.enabled=true" - + "-Dmanagement.endpoints.jmx.exposure.include=*", - env.get("JAVA_OPTS")); - - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/RouteBuilderTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/RouteBuilderTest.java deleted file mode 100644 index 71c92f63f..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/RouteBuilderTest.java +++ /dev/null @@ -1,312 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Spring IDE Developers - * 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: - * Spring IDE Developers - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test; - -import static org.junit.Assert.assertEquals; - -import java.util.List; -import java.util.stream.Collectors; - -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.junit.Test; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFCloudDomainData; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFDomainStatus; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudData; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.YamlGraphDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.routes.RouteAttributes; -import org.springframework.ide.eclipse.boot.dash.cf.routes.RouteBinding; -import org.springframework.ide.eclipse.boot.dash.cf.routes.RouteBuilder; -import org.springframework.ide.eclipse.editor.support.yaml.ast.NodeUtil; -import org.springframework.ide.eclipse.editor.support.yaml.ast.YamlASTProvider; -import org.springframework.ide.eclipse.editor.support.yaml.ast.YamlFileAST; -import org.springframework.ide.eclipse.editor.support.yaml.path.YamlPath; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; -import org.yaml.snakeyaml.nodes.Node; - -import com.google.common.collect.ImmutableList; - -public class RouteBuilderTest { - - List TEST_DOMAINS = ImmutableList.of( - new CFCloudDomainData("tcp.cfapps.io", CFDomainType.TCP, CFDomainStatus.SHARED), - new CFCloudDomainData("testing.me", CFDomainType.HTTP, CFDomainStatus.OWNED), - new CFCloudDomainData("cfapps.io") - ); - - @Test - public void appNameOnly() throws Exception { - assertRoutes( - "applications:\n" + - "- name: my-app\n" - , //=> - "my-app@cfapps.io" - ); - } - - @Test - public void domainAndHost() throws Exception { - assertRoutes( - "applications:\n" + - "- name: my-app\n" + - " domain: testing.me\n" + - " host: some-host" - , //=> - "some-host@testing.me" - ); - } - - @Test - public void domainOnly() throws Exception { - assertRoutes( - "applications:\n" + - "- name: my-app\n" + - " domain: testing.me\n" - , //=> - "my-app@testing.me" - ); - } - - @Test - public void domainAndNoHost() throws Exception { - assertRoutes( - "applications:\n" + - "- name: my-app\n" + - " domain: testing.me\n" + - " no-hostname: true" - , //=> - "testing.me" - ); - } - - @Test - public void noHostOnly() throws Exception { - assertRoutes( - "applications:\n" + - "- name: my-app\n" + - " no-hostname: true" - , //=> - "cfapps.io" - ); - } - - @Test public void noRoute() throws Exception { - assertRoutes( - "applications:\n" + - "- name: foo\n" + - " no-route: true" - // ==> - /* NONE */ - ); - } - - @Test - public void multipleDomainsAndHosts() throws Exception { - assertRoutes( - "applications:\n" + - "- name: my-app\n" + - " domains: [testing.me, cfapps.io]\n" + - " hosts: [foo, bar]\n" - , // ==> - "foo@testing.me", - "foo@cfapps.io", - "bar@testing.me", - "bar@cfapps.io" - ); - } - - @Test - public void randomRouteNoDomain() throws Exception { - assertRoutes( - "applications:\n" + - "- name: my-app\n" + - " random-route: true\n" - , - "?@cfapps.io" - ); - } - - @Test - public void randomRouteHttpDomain() throws Exception { - assertRoutes( - "applications:\n" + - "- name: my-app\n" + - " random-route: true\n" + - " domain: testing.me\n" - , - "?@testing.me" - ); - } - @Test - public void randomRouteTcpDomain() throws Exception { - assertRoutes( - "applications:\n" + - "- name: my-app\n" + - " random-route: true\n" + - " domain: tcp.cfapps.io\n" - , - "tcp.cfapps.io:?" - ); - } - - - @Test - public void variousUriRoutes() throws Exception { - assertRoutes( - "applications:\n" + - "- name: my-app\n" + - " routes:\n" + - " - route: foo.cfapps.io/somepath\n" + - " - route: cfapps.io\n" + - " - route: tcp.cfapps.io:63111\n" + - " - route: bar.testing.me\n" + - " - route: ambiguous.tcp.cfapps.io\n" - , // => - "foo@cfapps.io/somepath", - "cfapps.io", - "tcp.cfapps.io:63111", - "bar@testing.me", - "ambiguous@tcp.cfapps.io" - ); - } - - @Test - public void noCuttingInTheMiddleOfAWord() throws Exception { - { - List domains = ImmutableList.of( - new CFCloudDomainData("irrellevant.com"), - new CFCloudDomainData("thing.com"), - new CFCloudDomainData("something.com") - ); - assertRoutes(domains, - "applications:\n" + - "- name: my-app\n" + - " routes:\n" + - " - route: foo.something.com\n" - , // ==> - "foo@something.com" - ); - } - { - List domains = ImmutableList.of( - new CFCloudDomainData("irrellevant.com"), - new CFCloudDomainData("thing.com"), - new CFCloudDomainData("com") - ); - assertRoutes(domains, - "applications:\n" + - "- name: my-app\n" + - " routes:\n" + - " - route: foo.something.com\n" - , // ==> - "foo.something@com" - ); - } - } - - /////// Some edge cases below. Their behavior isn't really that important, but the tests - // just here to formally cover the corresponding branches in the code, and make sure - // they don't behave irrationally or crash. These tests are probably 'over-specified' in - // that they test behaviors client code shouldn't have to / want to care about. - - @Test - public void noKnownDomains() throws Exception { - assertRoutes(ImmutableList.of(), - "applications:\n" + - "- name: my-app\n" + - " routes:\n" + - " - route: some.thing.com\n" - // => - /* NONE */ - ); - assertRoutes(ImmutableList.of(), - "applications:\n" + - "- name: my-app\n" - // => - /* NONE */ - ); - } - - @Test - public void bogusDomain() throws Exception { - assertRoutes(ImmutableList.of(), - "applications:\n" + - "- name: my-app\n" + - " random-route: true\n" + - " domain: bogus.com\n" + - " domains: [ bogus.me, cfapps.io]\n" - , // => - - //Rationale for the below results. When determining random-route behavior - // for unknown domain assume its http, i.e. the most common case. - "?@bogus.me" , - "?@cfapps.io", - "?@bogus.com" - ); - } - - //////////////////////////////////////////////////////////////////////////////////// - private void assertRoutes(String manifestText, String... expectedRoutes) { - assertRoutes(TEST_DOMAINS, manifestText, expectedRoutes); - } - - private void assertRoutes(List domains, String manifestText, String... expectedRoutes) { - //Why the loop? This improves test coverage. The test should pass the same repeatedly, its behavior - // should not change. It *might* change if we have some kind of bug where cached state influences the - // behavior inadvertently in a manner visible to a caller. - for (int i = 0; i < 3; i++) { - RouteBuilder rb = new RouteBuilder(domains); - List routes = rb.buildRoutes(parse(domains, - manifestText)); - StringBuilder expected = new StringBuilder(); - StringBuilder expectedUri = new StringBuilder(); - for (String r : expectedRoutes) { - expected.append(r+"\n"); - expectedUri.append(r.replace("@", ".")); - } - StringBuilder actual = new StringBuilder(); - StringBuilder actualUri = new StringBuilder(); - for (RouteBinding r : routes) { - actual.append(r+"\n"); - actualUri.append(r.toUri()); - } - assertEquals(expected.toString(), actual.toString()); - assertEquals(expectedUri.toString(), actualUri.toString()); - } - } - - /** - * Parse a manifest with a single - * @param manifestText - * @return - */ - private RouteAttributes parse(List domains, String manifestText) { - IDocument doc = new Document(manifestText); - YamlASTProvider parser = new YamlASTProvider(new Yaml(new SafeConstructor())); - YamlFileAST ast = parser.getAST(doc); - List names = YamlPath.EMPTY - .thenAnyChild() - .thenValAt("applications") - .thenAnyChild() - .thenValAt("name") - .traverseAmbiguously(ast) - .collect(Collectors.toList()); - assertEquals("Number of apps in manifest", 1, names.size()); - String appName = NodeUtil.asScalar(names.get(0)); - CloudData cloudData = new CloudData(domains, "some-buildpack", ImmutableList.of()); - YamlGraphDeploymentProperties dp = new YamlGraphDeploymentProperties(manifestText, appName, cloudData); - return new RouteAttributes(dp); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/TestBootDashModelContext.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/TestBootDashModelContext.java index 36bb0d77b..dcc9eb588 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/TestBootDashModelContext.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/TestBootDashModelContext.java @@ -25,12 +25,6 @@ import org.eclipse.debug.core.ILaunchManager; import org.springframework.ide.eclipse.boot.core.BootPreferences; import org.springframework.ide.eclipse.boot.core.cli.BootInstallManager; import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; -import org.springframework.ide.eclipse.boot.dash.cf.actions.CfBootDashActions; -import org.springframework.ide.eclipse.boot.dash.cf.client.CloudFoundryClientFactory; -import org.springframework.ide.eclipse.boot.dash.cf.debug.DebugSupport; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshDebugSupport; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshTunnelFactory; -import org.springframework.ide.eclipse.boot.dash.cf.jmxtunnel.JmxSshTunnelManager; import org.springframework.ide.eclipse.boot.dash.console.CloudAppLogManager; import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; @@ -39,9 +33,6 @@ import org.springframework.ide.eclipse.boot.dash.model.SecuredCredentialsStore; import org.springframework.ide.eclipse.boot.dash.model.remote.GenericRemoteAppElementDataContributor; import org.springframework.ide.eclipse.boot.dash.test.mocks.MockScopedPropertyStore; import org.springframework.ide.eclipse.boot.dash.test.mocks.MockSecuredCredentialStore; -import org.springframework.ide.eclipse.boot.dash.test.mocks.MockSshTunnel; -import org.springframework.ide.eclipse.boot.dash.views.BootDashActions; -import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.Contributor; import org.springsource.ide.eclipse.commons.core.pstore.IPropertyStore; import org.springsource.ide.eclipse.commons.core.pstore.IScopedPropertyStore; import org.springsource.ide.eclipse.commons.core.pstore.InMemoryPropertyStore; @@ -83,11 +74,7 @@ public class TestBootDashModelContext extends BootDashModelContext { private static SimpleDIContext createInjections() { SimpleDIContext injections = new SimpleDIContext(); injections.defInstance(AllUserInteractions.class, mock(AllUserInteractions.class)); - injections.defInstance(BootDashActions.Factory.class, CfBootDashActions.factory); - injections.defInstance(DebugSupport.class, SshDebugSupport.INSTANCE); injections.def(BootDashViewModel.class, BootDashViewModel::new); - injections.defInstance(SshTunnelFactory.class, MockSshTunnel::new); - injections.defInstance(JmxSshTunnelManager.class, new JmxSshTunnelManager()); injections.def(CloudAppLogManager.class, CloudAppLogManager::new); //TODO: replace with a mock? injections.def(GenericRemoteAppElementDataContributor.class, GenericRemoteAppElementDataContributor::new); return injections; @@ -167,11 +154,6 @@ public class TestBootDashModelContext extends BootDashModelContext { return this; } - public TestBootDashModelContext withCfClient(CloudFoundryClientFactory client) { - injections.defInstance(CloudFoundryClientFactory.class, client); - return this; - } - public RunTargetType getRargetTypeWithName(String name) { return injections.getBeans(RunTargetType.class).stream().filter(t -> t.getName().equals(name)).findFirst().orElse(null); } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/CFOrganizationData.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/CFOrganizationData.java deleted file mode 100644 index 4e0872342..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/CFOrganizationData.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test.mocks; - -import java.util.UUID; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFOrganization; - -/** - * Data object implementing {@link CFOrganization} - * - * @author Kris De Volder - */ -public class CFOrganizationData implements CFOrganization { - - private String name; - private UUID guid; - - public CFOrganizationData(String name, UUID guid) { - super(); - this.name = name; - this.guid = guid; - } - - @Override - public String getName() { - return name; - } - - @Override - public UUID getGuid() { - return guid; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/CFServiceInstanceData.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/CFServiceInstanceData.java deleted file mode 100644 index a11d2e06f..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/CFServiceInstanceData.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test.mocks; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFServiceInstance; - -public class CFServiceInstanceData implements CFServiceInstance { - - private String name; - - public CFServiceInstanceData(String name) { - this.name = name; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getPlan() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getDashboardUrl() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getService() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getDescription() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getDocumentationUrl() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/CFSpaceData.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/CFSpaceData.java deleted file mode 100644 index 75f8d3cc7..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/CFSpaceData.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test.mocks; - -import java.util.UUID; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFOrganization; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; - -/** - * @author Kris De Volder - */ -public class CFSpaceData implements CFSpace { - - private String name; - private UUID guid; - private CFOrganization org; - - public CFSpaceData(String name, UUID guid, CFOrganization org) { - super(); - this.name = name; - this.guid = guid; - this.org = org; - } - - @Override - public String getName() { - return name; - } - - @Override - public CFOrganization getOrganization() { - return org; - } - - @Override - public UUID getGuid() { - return guid; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFApplication.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFApplication.java deleted file mode 100644 index 018b34214..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFApplication.java +++ /dev/null @@ -1,434 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test.mocks; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import org.eclipse.core.runtime.Assert; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFAppState; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFInstanceState; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFInstanceStats; -import org.springframework.ide.eclipse.boot.dash.cf.client.InstanceState; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.ApplicationExtras; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFApplicationDetailData; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFApplicationSummaryData; -import org.springframework.ide.eclipse.boot.dash.cf.routes.RouteBinding; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; -import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition; - -import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableList.Builder; -import com.google.common.collect.ImmutableMap; - -import reactor.core.publisher.Mono; - -public class MockCFApplication { - - private static class MockCFInstanceStats implements CFInstanceStats { - - private CFInstanceState state; - - public MockCFInstanceStats(CFInstanceState state) { - this.state = state; - } - - @Override - public CFInstanceState getState() { - return state; - } - - @Override - public String toString() { - return "CFInstanceState("+state+")"; - } - } - - private final String name; - private final UUID guid; - private int instances; - - private Map env = new HashMap<>(); - private int memory = 1024; - private List services = new ArrayList<>(); - private String buildpackUrl = null; - private List routes = new ArrayList<>(); - private CFAppState state = CFAppState.STOPPED; - private int diskQuota = 1024; - private Integer timeout = null; - private String healthCheckType = DeploymentProperties.DEFAULT_HEALTH_CHECK_TYPE; - private String healthCheckHttpEndpoint = null; - private String command = null; - private String stack = null; - private MockCloudFoundryClientFactory owner; - private MockCFSpace space; - - public MockCFApplication(MockCloudFoundryClientFactory owner, MockCFSpace space, String name, UUID guid, int instances, CFAppState state) { - this.owner = owner; - this.space = space; - this.name = name; - this.guid = guid; - this.instances = instances; - this.state = state; - this.cancelationTokens = new CancelationTokens(); - } - - private ImmutableList stats = ImmutableList.of(); - - private CancelationTokens cancelationTokens; - private Supplier bits; - - public MockCFApplication(MockCloudFoundryClientFactory owner, MockCFSpace space, String name) { - this(owner, - space, - name, - UUID.randomUUID(), - 1, - CFAppState.STOPPED - ); - } - - public String getName() { - return name; - } - - public List getStats() { - return stats; - } - - public void start(CancelationToken cancelationToken) throws Exception { - Assert.isLegal(CFAppState.STOPPED==state); - Assert.isLegal(stats.isEmpty()); - this.state = CFAppState.UNKNOWN; - final long endTime = System.currentTimeMillis()+getStartDelay(); - new ACondition("simulated app starting (waiting)", getStartDelay()+1000) { - @Override - public boolean test() throws Exception { -// System.out.println("Checking token: "+cancelToken); - if (!cancelationToken.isCanceled() && System.currentTimeMillis() builder = ImmutableList.builder(); - for (int i = 0; i < instances; i++) { - Map values = new HashMap<>(); - values.put("state", InstanceState.RUNNING.toString()); - CFInstanceStats stat = new MockCFInstanceStats(CFInstanceState.RUNNING); - builder.add(stat); - } - if (cancelationToken.isCanceled()) { - System.out.println("Starting "+getName()+" CANCELED"); - throw new IOException("Operation Canceled"); - } - this.stats = builder.build(); - this.state = CFAppState.STARTED; - System.out.println("Starting "+getName()+" SUCCESS"); - } - - private long getStartDelay() { - return owner.getStartDelay(); - } - - public String getHealthCheckType() { - return healthCheckType; - } - - public void setHealthCheckType(String t) { - this.healthCheckType = t; - } - - public String getHealthCheckHttpEndpoint() { - return healthCheckHttpEndpoint; - } - - public void setHealthCheckHttpEndpoint(String t) { - this.healthCheckHttpEndpoint = t; - } - - public void setHealthCheckTypeMaybe(String t) { - if (t!=null) { - setHealthCheckType(t); - } - } - - -// public int getInstances() { -// return instances; -// } - - public int getRunningInstances() { - int runningInstances = 0; - for (CFInstanceStats instance : getStats()) { - if (instance.getState()==CFInstanceState.RUNNING) { - runningInstances++; - } - } - return runningInstances; - } - - public UUID getGuid() { - return guid; - } - - public void setBuildpackUrl(String buildpackUrl) { - this.buildpackUrl = buildpackUrl; - } - - public void setCommand(String command) { - this.command = command; - } - - public void setStack(String stack) { - this.stack = stack; - } - - public void setTimeout(int timeout) { - this.timeout = timeout; - } - - - public void setDiskQuota(int diskQuota) { - this.diskQuota = diskQuota; - } - - public void setMemory(int memory) { - this.memory = memory; - } - - public int getMemory() { - return this.memory; - } - - public void setRoutes(Collection routes) { - this.routes = routes==null?null:ImmutableList.copyOf(routes); - } - - public void setServices(Collection services) { - this.services = services==null?null:ImmutableList.copyOf(services); - } - - public CFApplication getBasicInfo() { - return new CFApplicationSummaryData( - name, - instances, - getRunningInstances(), - memory, - guid, - getUris(), - state, - diskQuota, - getExtras() - ); - } - - private List getUris() { - return routes.stream() - .map(RouteBinding::toUri) - .collect(Collectors.toList()); - } - - private ApplicationExtras getExtras() { - return new ApplicationExtras() { - @Override - public Mono getStack() { - return Mono.justOrEmpty(stack); - } - @Override - public Mono> getServices() { - return Mono.justOrEmpty(services); - } - - @Override - public Mono> getEnv() { - return Mono.justOrEmpty(env); - } - - @Override - public Mono getBuildpack() { - return Mono.justOrEmpty(buildpackUrl); - } - @Override - public Mono getTimeout() { - return Mono.justOrEmpty(timeout); - } - @Override - public Mono getCommand() { - return Mono.justOrEmpty(command); - } - @Override - public Mono getHealthCheckType() { - return Mono.justOrEmpty(healthCheckType); - } - @Override - public Mono getHealthCheckHttpEndpoint() { - return Mono.justOrEmpty(healthCheckHttpEndpoint); - } - - }; - } - - public CFApplicationDetail getDetailedInfo() { - return new CFApplicationDetailData( - new CFApplicationSummaryData( - name, - instances, - getRunningInstances(), - memory, - guid, - getUris(), - state, - diskQuota, - getExtras() - ), - ImmutableList.copyOf(stats) - ); -// return new CFApplicationDetailData(getBasicInfo(), ImmutableList.copyOf(stats)); - } - - @Override - public String toString() { - return "MockCFApp("+name+")"; - } - - public void stop() { - cancelationTokens.cancelAll(); - this.stats = ImmutableList.of(); - this.state = CFAppState.STOPPED; - } - - public Map getEnv() { - return env; - } - - public void setEnv(Map newEnv) { - env = ImmutableMap.copyOf(newEnv); - } - - public void restart(CancelationToken cancelationToken) throws Exception { - stop(); - start(cancelationToken); - } - - public void scaleInstances(int desiredInstances) { - Assert.isLegal(desiredInstances>0); - Builder builder = ImmutableList.builder(); - builder.addAll(stats); - for (int i = 0; i < desiredInstances; i++) { - builder.add(new MockCFInstanceStats(CFInstanceState.RUNNING)); - } - stats = builder.build(); - this.instances = desiredInstances; - } - - - public void setBuildpackUrlMaybe(String buildpack) { - if (buildpack!=null) { - setBuildpackUrl(buildpack); - } - } - - public void setCommandMaybe(String command) { - if (command!=null) { - setCommand(command); - } - } - - public void setDiskQuotaMaybe(Integer diskQuota) { - if (diskQuota!=null) { - setDiskQuota(diskQuota); - } - } - - public void setEnvMaybe(Map env) { - if (env!=null) { - setEnv(env); - } - } - - public void setMemoryMaybe(Integer memory) { - if (memory!=null) { - setMemory(memory); - } - } - - public void setServicesMaybe(List services) { - if (services!=null) { - setServices(services); - } - } - - public void setStackMaybe(String stack) { - if (stack!=null) { - setStack(stack); - } - } - - public void setTimeoutMaybe(Integer timeout) { - if (timeout!=null) { - setTimeout(timeout); - } - } - - public int getPushCount() { - return space.getPushCount(name).getValue(); - } - - public String getFileContents(String path) throws IOException { - ZipInputStream zip = new ZipInputStream(getBits()); - ZipEntry entry; - while (null != (entry = zip.getNextEntry())) { - if (!entry.isDirectory()) { - if (entry.getName().equals(path)) { - return new String(readBytes(zip)); - } - } - } - return null; - } - - private byte[] readBytes(ZipInputStream zip) throws IOException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - int nextByte; - while ((nextByte = zip.read())>=0) { - bytes.write(nextByte); - } - return bytes.toByteArray(); - } - - public void setBits(Supplier bytes) { - this.bits = bytes; - } - - public ByteArrayInputStream getBits() { - return new ByteArrayInputStream(bits.get()); - } - - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFBuildpack.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFBuildpack.java deleted file mode 100644 index 7b827e7f5..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFBuildpack.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test.mocks; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFBuildpack; - -public class MockCFBuildpack implements CFBuildpack{ - - private String name; - - public MockCFBuildpack(String name) { - this.name = name; - } - - @Override - public String getName() { - return name; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFSpace.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFSpace.java deleted file mode 100644 index a68c35897..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFSpace.java +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test.mocks; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.mockito.Mockito; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFOrganization; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFServiceInstance; -import org.springsource.ide.eclipse.commons.livexp.core.LiveCounter; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableList.Builder; - -public class MockCFSpace extends CFSpaceData { - - //TODO: the methods in this class should prolly be synchronized somehow. It manipulates mutable - // data and is called from multiple threads. - - private Map servicesByName = new HashMap<>(); - private Map appsByName = new HashMap<>(); - private MockCloudFoundryClientFactory owner; - private Map pushCounts = new HashMap<>(); - - public MockCFSpace(MockCloudFoundryClientFactory owner, String name, UUID guid, CFOrganization org) { - super(name, guid, org); - this.owner = owner; - } - - public String getDefaultDomain() { - return owner.getDefaultDomain(); - } - - public List getServices() { - return ImmutableList.copyOf(servicesByName.values()); - } - - public ImmutableList getApplicationsWithBasicInfo() { - Builder builder = ImmutableList.builder(); - for (MockCFApplication app : appsByName.values()) { - builder.add(app.getBasicInfo()); - } - return builder.build(); - } - - public MockCFApplication defApp(String name) { - MockCFApplication existing = appsByName.get(name); - if (existing==null) { - appsByName.put(name, existing = Mockito.spy(new MockCFApplication(owner, this, name))); - } - return existing; - } - - public CFServiceInstance defService(String name) { - CFServiceInstance existing = servicesByName.get(name); - if (existing==null) { - servicesByName.put(name, new CFServiceInstanceData( - name - )); - } - return existing; - } - - public MockCFApplication getApplication(UUID appGuid) { - for (MockCFApplication app : appsByName.values()) { - if (app.getGuid().equals(appGuid)) { - return app; - } - } - return null; - } - - public MockCFApplication getApplication(String appName) { - MockCFApplication app = appsByName.get(appName); - if (app!=null) { - return app; - } - return null; - } - - - public boolean removeApp(String name) { - return appsByName.remove(name)!=null; - } - - public void put(MockCFApplication app) { - appsByName.put(app.getName(), app); - } - - public synchronized LiveCounter getPushCount(String name) { - LiveCounter counter = pushCounts.get(name); - if (counter==null) { - pushCounts.put(name, counter = new LiveCounter()); - } - return counter; - } - - public void deleteService(String serviceName) throws Exception { - CFServiceInstance x = servicesByName.remove(serviceName); - if (x==null) { - throw new IOException("Service doesn't exist: "+serviceName); - } - } - - @Override - public String toString() { - return "MockCFSpace("+getName()+")"; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFStack.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFStack.java deleted file mode 100644 index d25bdc14f..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCFStack.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test.mocks; - -import org.springframework.ide.eclipse.boot.dash.cf.client.CFStack; - -/** - * @author Kris De Volder - */ -public class MockCFStack implements CFStack { - - private String name; - - public MockCFStack(String name) { - super(); - this.name = name; - } - - @Override - public String getName() { - return name; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCloudFoundryClientFactory.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCloudFoundryClientFactory.java deleted file mode 100644 index ff6b0c23a..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockCloudFoundryClientFactory.java +++ /dev/null @@ -1,667 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test.mocks; - -import java.io.IOException; -import java.nio.file.Files; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import org.apache.commons.lang.RandomStringUtils; -import org.cloudfoundry.client.CloudFoundryClient; -import org.osgi.framework.Version; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplication; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFApplicationDetail; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFBuildpack; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFClientParams; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFDomainType; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFOrganization; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFServiceInstance; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFSpace; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFStack; -import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests; -import org.springframework.ide.eclipse.boot.dash.cf.client.CloudFoundryClientFactory; -import org.springframework.ide.eclipse.boot.dash.cf.client.SshClientSupport; -import org.springframework.ide.eclipse.boot.dash.cf.client.SshHost; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCredentials.CFCredentialType; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFCloudDomainData; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFDomainStatus; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFPushArguments; -import org.springframework.ide.eclipse.boot.dash.cf.routes.ParsedUri; -import org.springframework.ide.eclipse.boot.dash.cf.routes.RouteBinding; -import org.springframework.ide.eclipse.boot.dash.console.IApplicationLogConsole; -import org.springframework.ide.eclipse.boot.dash.test.CfTestTargetParams; -import org.springframework.ide.eclipse.boot.dash.test.util.LiveExpToFlux; -import org.springframework.ide.eclipse.boot.dash.util.CancelationTokens.CancelationToken; -import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -import junit.framework.Assert; -import reactor.core.Disposable; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -public class MockCloudFoundryClientFactory extends CloudFoundryClientFactory { - - private static void debug(String string) { - System.out.println(string); - } - - private final Set instances = Collections.synchronizedSet(new HashSet<>()); - - public static final String FAKE_REFRESH_TOKEN = "fakeRefreshToken"; - public static final String FAKE_PASSWORD = CfTestTargetParams.fromEnv("CF_TEST_PASSWORD"); - private Version supportedApiVersion = new Version(CloudFoundryClient.SUPPORTED_API_VERSION); - private Version apiVersion = supportedApiVersion; - - private Map orgsByName = new LinkedHashMap<>(); - private Map spacesByName = new LinkedHashMap<>(); - private Map domainsByName = new LinkedHashMap<>(); - private Map buildpacksByName = new LinkedHashMap<>(); - private Map stacksByName = new LinkedHashMap<>(); - - private Set ssoTokens = new HashSet<>(); - - /** - * Becomes non-null if notImplementedStub is called, used to check that the tests - * only use parts of the mocking harness that are actually implemented. - */ - private Exception notImplementedStubCalled = null; - private long startDelay = 0; - - public MockCloudFoundryClientFactory() { - defDomain("cfmockapps.io"); //Lost of functionality may assume there's at least one domain so make sure we have one. - defBuildpacks("java-buildpack", "ruby-buildpack", "funky-buildpack", "another-buildpack"); - defStacks("cflinuxfs2", "windows2012R2"); - } - - synchronized public String getSsoToken() { - String token = RandomStringUtils.randomAlphabetic(8); - ssoTokens.add(token); - return token; - } - - /** - * Verfies the validity of a sso token. Sso token can only be used once - * so this check implicitly invalidates the token. - * - * @return Whether the token was valid prior to the call to this method. - */ - private synchronized boolean checkSsoToken(String token) { - return ssoTokens.remove(token); - } - - public void defStacks(String... names) { - for (String n : names) { - defStack(n); - } - } - - public MockCFStack defStack(String name) { - MockCFStack stack = new MockCFStack(name); - stacksByName.put(name, stack); - return stack; - } - - @Override - public ClientRequests getClient(CFClientParams params) { - return new MockClient(params); - } - - public CFCloudDomain defDomain(String name) { - CFCloudDomainData it = new CFCloudDomainData(name); - domainsByName.put(name, it); - return it; - } - - public CFCloudDomain defDomain(String name, CFDomainType type, CFDomainStatus status) { - CFCloudDomainData it = new CFCloudDomainData(name, type, status); - domainsByName.put(name, it); - return it; - } - - public String getDefaultDomain() { - return domainsByName.keySet().iterator().next(); - } - - public MockCFSpace defSpace(String orgName, String spaceName) { - String key = orgName+"/"+spaceName; - MockCFSpace existing = spacesByName.get(key); - if (existing==null) { - CFOrganization org = defOrg(orgName); - spacesByName.put(key, existing= new MockCFSpace(this, - spaceName, - UUID.randomUUID(), - org - )); - } - return existing; - } - - public CFOrganization defOrg(String orgName) { - CFOrganization existing = orgsByName.get(orgName); - if (existing==null) { - orgsByName.put(orgName, existing = new CFOrganizationData( - orgName, - UUID.randomUUID() - )); - } - return existing; - } - - public void assertOnlyImplementedStubsCalled() throws Exception { - if (notImplementedStubCalled!=null) { - throw notImplementedStubCalled; - } - } - - private String validPassword = FAKE_PASSWORD; - /** - * Change the current password this mock client will accept when trying to - * use password-based authentication. - */ - public void setPassword(String newPassword) { - this.validPassword = newPassword; - } - - private class MockClient implements ClientRequests { - - private class MockSshClientSupport implements SshClientSupport { - - @Override - public SshHost getSshHost() throws Exception { - return new SshHost("ssh.host.somewhere", 2222, "some-ssh-fingerprint"); - } - - @Override - public String getSshUser(String appName, int instance) throws Exception { - MockCFApplication app = getSpace().getApplication(appName); - if (app==null) { - throw new IOException("App not found"); - } - UUID guid = app.getGuid(); - Assert.assertNotNull(guid); - return getSshUser(guid, instance); - } - - @Override - public String getSshCode() throws Exception { - return "an-ssh-code"; - } - - @Override - public String getSshUser(UUID appGuid, int instance) throws Exception { - return appGuid+"/"+instance; - } - - } - - private int nextPort = 63000; - private synchronized int choosePort() { - return nextPort++; - } - - private CFClientParams params; - private boolean connected = true; - private Boolean validCredentials = null; - - - private final LiveVariable refreshToken = new LiveVariable<>(); - - public MockClient(CFClientParams params) { - this.params = params; - instances.add(this); - debug("created Mock CF Client: "+instances.size()); - refreshToken.addListener((e,v) -> debug("refreshToken <- "+v)); - refreshToken.onDispose(d -> debug("refreshToken DISPOSED")); - } - - private void notImplementedStub() { - IllegalStateException e = new IllegalStateException("CF Client Stub Not Yet Implemented"); - if (notImplementedStubCalled==null) { - notImplementedStubCalled = e; - } - throw e; - } - - @Override - public Flux getApplicationDetails(List appsToLookUp) throws Exception { - checkConnection(); - MockCFSpace space = getSpace(); - return Flux.fromIterable(appsToLookUp) - .flatMap((app) -> { - return Mono.justOrEmpty(space.getApplication(app.getGuid()).getDetailedInfo()); - }); - } - - @Override - public Disposable streamLogs(String appName, IApplicationLogConsole logConsole) throws Exception { - checkConnection(); - //TODO: This 'log streamer' is a total dummy for now. It doesn't stream any data and canceling it does nothing. - return Flux.empty().subscribe(); - } - - @Override - public void stopApplication(String appName) throws Exception { - checkConnection(); - MockCFApplication app = getSpace().getApplication(appName); - if (app==null) { - throw errorAppNotFound(appName); - } - app.stop(); - } - - @Override - public void restartApplication(String appName, CancelationToken cancelationToken) throws Exception { - checkConnection(); - MockCFApplication app = getSpace().getApplication(appName); - if (app==null) { - throw errorAppNotFound(appName); - } - app.restart(cancelationToken); - } - - @Override - public void dispose() { - connected = false; - refreshToken.dispose(); - instances.remove(this); - debug("Mock CF Client disposed: "+instances.size()); - } - - @Override - public SshClientSupport getSshClientSupport() throws Exception { - return new MockSshClientSupport(); - } - - @SuppressWarnings("unchecked") - @Override - public List getSpaces() throws Exception { - checkConnection(); - @SuppressWarnings("rawtypes") - List hack = ImmutableList.copyOf(spacesByName.values()); - return hack; - } - - @Override - public List getServices() throws Exception { - checkConnection(); - return getSpace().getServices(); - } - - private MockCFSpace getSpace() throws IOException { - if (params.getOrgName()==null) { - throw errorNoOrgSelected(); - } - if (params.getSpaceName()==null) { - throw errorNoSpaceSelected(); - } - MockCFSpace space = spacesByName.get(params.getOrgName()+"/"+params.getSpaceName()); - if (space==null) { - throw errorSpaceNotFound(params.getOrgName()+"/"+params.getSpaceName()); - } - return space; - } - - @Override - public List getDomains() throws Exception { - checkConnection(); - return ImmutableList.copyOf(domainsByName.values()); - } - - @Override - public List getBuildpacks() throws Exception { - checkConnection(); - return ImmutableList.copyOf(buildpacksByName.values()); - } - - @Override - public List getApplicationsWithBasicInfo() throws Exception { - checkConnection(); - return getSpace().getApplicationsWithBasicInfo(); - } - - @Override - public CFApplicationDetail getApplication(String appName) throws Exception { - checkConnection(); - MockCFApplication app = getSpace().getApplication(appName); - if (app!=null) { - return app.getDetailedInfo(); - } - return null; - } - - @Override - public Version getApiVersion() { - return apiVersion; - } - - @Override - public Version getSupportedApiVersion() { - return supportedApiVersion; - } - - @Override - public void deleteApplication(String name) throws Exception { - checkConnection(); - if (!getSpace().removeApp(name)) { - throw errorAppNotFound(name); - } - } - - @Override - public String getHealthCheck(UUID appGuid) throws Exception { - checkConnection(); - MockCFApplication app = getApplication(appGuid); - if (app == null) { - throw errorAppNotFound("GUID: "+appGuid.toString()); - } else { - return app.getHealthCheckType(); - } - } - - private MockCFApplication getApplication(UUID appGuid) throws IOException { - return getSpace().getApplication(appGuid); - } - - /** - * Each mock operation that does something requires access to CF should call this - * to ensure that it implicitly check whether the connection is valid. - *

- * Operations on 'invalid' connection are expected to throw Exceptions. - * Calling this method makes the operations behave as expected. For example, - * fail when logged out, or when connection was created with invalid credentials. - */ - private void checkConnection() throws Exception { - if (!connected) { - throw errorClientNotConnected(); - } - if (validCredentials==null) { - validCredentials = isValidCredentials(params.getUsername(), params.getCredentials()); - } - if (!validCredentials) { - throw errorInvalidCredentials(); - } - } - - private boolean isValidCredentials(String username, CFCredentials credentials) throws Exception { - CFCredentialType type = credentials.getType(); - String secret = credentials.getSecret(); - if (type==CFCredentialType.PASSWORD) { - if (!credentials.getSecret().equals(validPassword)) { - return false; - } - } else if (type==CFCredentialType.REFRESH_TOKEN) { - if (!secret.equals(FAKE_REFRESH_TOKEN)) { - return false; - } - } else if (type==CFCredentialType.TEMPORARY_CODE) { - if (!checkSsoToken(secret)) { - return false; - } - } else { - return false; - } - //Validation of credentials is expected to update refresh token. - refreshToken.setValue(FAKE_REFRESH_TOKEN); - return true; - } - - @Override - public void setHealthCheck(UUID guid, String hcType) throws Exception { - checkConnection(); - notImplementedStub(); - } - - @Override - public List getStacks() throws Exception { - checkConnection(); - return ImmutableList.copyOf(stacksByName.values()); - } - - @Override - public boolean applicationExists(String appName) throws Exception { - checkConnection(); - return getSpace().getApplication(appName) !=null; - } - - @Override - public void push(CFPushArguments args, CancelationToken cancelationToken) throws Exception { - checkConnection(); - System.out.println("Pushing: "+args); - //TODO: should check services exist and raise an error because non-existant services cannot be bound. - MockCFSpace space = getSpace(); - MockCFApplication app = new MockCFApplication(MockCloudFoundryClientFactory.this, space, args.getAppName()); - app.setBuildpackUrlMaybe(args.getBuildpack()); - app.setRoutes(buildRoutes(args)); - - app.setCommandMaybe(args.getCommand()); - app.setDiskQuotaMaybe(args.getDiskQuota()); - app.setEnvMaybe(args.getEnv()); - app.setMemoryMaybe(args.getMemory()); - app.setServicesMaybe(args.getServices()); - app.setStackMaybe(args.getStack()); - app.setTimeoutMaybe(args.getTimeout()); - app.setHealthCheckTypeMaybe(args.getHealthCheckType()); - app.setHealthCheckHttpEndpoint(args.getHealthCheckHttpEndpoint()); - app.setBits(() -> { - try { - return Files.readAllBytes(args.getApplicationDataAsFile().toPath()); - } catch (IOException e) { - return new byte[0]; - } - }); - space.put(app); - space.getPushCount(app.getName()).increment(); - - app.start(cancelationToken); - } - - private Collection buildRoutes(CFPushArguments args) { - List desiredUris = args.getRoutes(); - if (desiredUris!=null) { - return desiredUris.stream() - .map(uri -> buildRoute(uri, args)) - .collect(Collectors.toList()); - } - return ImmutableList.of(); - } - - private RouteBinding buildRoute(String _uri, CFPushArguments args) { - ParsedUri uri = new ParsedUri(_uri); - boolean randomRoute = args.getRandomRoute(); - CFCloudDomainData bestDomain = domainsByName.values().stream() - .filter(domain -> domainCanBeUsedFor(domain, uri)) - .max((d1, d2) -> Integer.compare(d1.getName().length(), d2.getName().length())) - .orElse(null); - if (bestDomain==null) { - throw new IllegalStateException("No domain matching the given uri '"+_uri+"' could be found"); - } - RouteBinding route = new RouteBinding(); - route.setDomain(bestDomain.getName()); - route.setHost(bestDomain.splitHost(uri.getHostAndDomain())); - route.setPath(uri.getPath()); - route.setPort(uri.getPort()); - if (randomRoute) { - if (bestDomain.getType()==CFDomainType.TCP) { - if (route.getPort()==null) { - route.setPort(choosePort()); - } - } else if (bestDomain.getType()==CFDomainType.HTTP) { - if (route.getHost()==null) { - route.setHost(chooseHost()); - } - } - } - return route; - } - - private String chooseHost() { - return RandomStringUtils.randomAlphabetic(8).toLowerCase(); - } - - private boolean domainCanBeUsedFor(CFCloudDomainData domainData, ParsedUri uri) { - String domain = domainData.getName(); - String hostAndDomain = uri.getHostAndDomain(); - String host; - if (!hostAndDomain.endsWith(domain)) { - return false; - } - if (domain.length()==hostAndDomain.length()) { - //The uri matches domain precisely - host = null; - } else if (hostAndDomain.charAt(hostAndDomain.length()-domain.length()-1)=='.') { - //THe uri matches as ${host}.${domain} - host = hostAndDomain.substring(0, hostAndDomain.length()-domain.length()-1); - } else { - //Couldn't match this domain to uri - return false; - } - if (domainData.getType()==CFDomainType.TCP) { - return host==null; //TCP routes don't allow setting a host, only a port - } else if (domainData.getType()==CFDomainType.HTTP) { - return uri.getPort()==null; //HTTP routes don't allow setting a port only a host - } else { - throw new IllegalStateException("Unknown domain type: "+domainData.getType()); - } - } - - @Override - public Map getApplicationEnvironment(String appName) throws Exception { - checkConnection(); - MockCFApplication app = getSpace().getApplication(appName); - if (app==null) { - throw errorAppNotFound(appName); - } - return ImmutableMap.copyOf(app.getEnv()); - } - - @Override - public Mono deleteServiceAsync(String serviceName) { - return Mono.defer(() -> { - try { - checkConnection(); - getSpace().deleteService(serviceName); - return Mono.empty(); - } catch (Exception e) { - return Mono.error(e); - } - }); - } - - @Override - public Mono getUserName() { - return Mono.defer(() -> { - try { - checkConnection(); - return Mono.just(params.getUsername()); - } catch (Exception e) { - return Mono.error(e); - } - }); - } - - @Override - public String getRefreshToken() { - return refreshToken.getValue(); - } - - @Override - public Flux getRefreshTokens() { - return LiveExpToFlux.toFlux(refreshToken); - } - } - - public void defBuildpacks(String... names) { - for (String n : names) { - defBuildpack(n); - } - } - - public MockCFBuildpack defBuildpack(String n) { - MockCFBuildpack it = new MockCFBuildpack(n); - buildpacksByName.put(n, it); - return it; - } - - ////////////////////////////////////////////////// - // Exception creation methods - - protected IOException errorAppNotFound(String detailMessage) throws IOException { - return new IOException("App not found: "+detailMessage); - } - - protected IOException errorClientNotConnected() { - return new IOException("CF Client not Connected"); - } - - protected IOException errorNoOrgSelected() { - return new IOException("No org selected"); - } - - protected IOException errorNoSpaceSelected() { - return new IOException("No space selected"); - } - - protected IOException errorSpaceNotFound(String detail) { - return new IOException("Space not found: "+detail); - } - - protected IOException errorAppAlreadyExists(String detail) { - return new IOException("App already exists: "+detail); - } - - protected Exception errorInvalidCredentials() { - return new Exception("Cannot connect to CF. Invalid credentials."); - } - - public void setAppStartDelay(TimeUnit timeUnit, int howMany) { - startDelay = timeUnit.toMillis(howMany); - } - - /** - * @return The delay that a simulated 'start' of an app should take before returning. Given in milliseconds. - */ - public long getStartDelay() { - return startDelay; - } - - public void setApiVersion(String string) { - apiVersion = new Version(string); - } - - public void setSupportedApiVersion(String string) { - supportedApiVersion = new Version(string); - } - - public int instanceCount() { - return instances.size(); - } - - public void changeRefrestToken(String newToken) { - for (MockClient client : instances) { - client.refreshToken.setValue(newToken); - } - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockRunTarget.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockRunTarget.java deleted file mode 100644 index 62cebf9f0..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockRunTarget.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2017 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.test.mocks; - -import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.DEFAULT_PATH; -import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.INSTANCES; -import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.NAME; -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 org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IType; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryTargetProperties; -import org.springframework.ide.eclipse.boot.dash.model.AbstractRunTarget; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; -import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; -import org.springframework.ide.eclipse.boot.dash.model.RunTargetWithProperties; -import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.TargetProperties; -import org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn; - -public class MockRunTarget extends AbstractRunTarget implements RunTargetWithProperties { - - private CloudFoundryTargetProperties properties; - private boolean requiresCredentials; - - public MockRunTarget(RunTargetType type, CloudFoundryTargetProperties properties) { - this(type, properties, false); - } - - public MockRunTarget(RunTargetType type, CloudFoundryTargetProperties properties, boolean requiresCredentials) { - super(type, properties.getRunTargetId()); - this.properties = properties; - this.requiresCredentials = requiresCredentials; - } - - private final BootDashColumn[] defaultColumns = { RUN_STATE_ICN, NAME, PROJECT, INSTANCES, DEFAULT_PATH, TAGS }; - - @Override - public BootDashColumn[] getDefaultColumns() { - return defaultColumns; - } - - @Override - public MockBootDashModel createSectionModel(BootDashViewModel viewModel) { - return new MockBootDashModel(this, viewModel.getContext(), viewModel); - } - - @Override - public boolean canRemove() { - return true; - } - - @Override - public boolean canDeployAppsFrom() { - return false; - } - - public String get(String prop) { - return properties.get(prop); - } - - @Override - public TargetProperties getTargetProperties() { - return properties; - } - - @Override - public boolean requiresCredentials() { - return requiresCredentials; - } - - @Override - public CloudFoundryTargetProperties getParams() { - return properties; - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockRunTargetType.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockRunTargetType.java deleted file mode 100644 index 1268991ff..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockRunTargetType.java +++ /dev/null @@ -1,76 +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.test.mocks; - -import java.util.Map; -import java.util.concurrent.CompletableFuture; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryTargetProperties; -import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; -import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; -import org.springframework.ide.eclipse.boot.dash.model.RunTarget; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.AbstractRunTargetType; -import org.springframework.ide.eclipse.boot.dash.model.runtargettypes.TargetProperties; -import org.springsource.ide.eclipse.commons.livexp.core.LiveSetVariable; - -import com.google.gson.Gson; - -public class MockRunTargetType extends AbstractRunTargetType { - - private boolean requiresCredentials; - - public MockRunTargetType(SimpleDIContext injections, String name) { - super(injections, name); - } - - @Override - public boolean canInstantiate() { - return true; - } - - @Override - public CompletableFuture openTargetCreationUi(LiveSetVariable targets) { - return CompletableFuture.completedFuture(null); - } - - @Override - public RunTarget createRunTarget(CloudFoundryTargetProperties properties) { - return new MockRunTarget(this, properties, requiresCredentials); - } - - @Override - public ImageDescriptor getIcon() { - return null; - } - - public void setRequiresCredentials(boolean requires) { - this.requiresCredentials = requires; - } - - @Override - public CloudFoundryTargetProperties parseParams(String serializedTargetParams) { - Gson gson = new Gson(); - @SuppressWarnings("unchecked") - Map map = gson.fromJson(serializedTargetParams, Map.class); - return new CloudFoundryTargetProperties(new TargetProperties(map, this), this, injections); - } - - @Override - public String serialize(CloudFoundryTargetProperties props) { - return props.toJson(); - } - - @Override - public ImageDescriptor getDisconnectedIcon() { - return null; - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockSshTunnel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockSshTunnel.java deleted file mode 100644 index 1e3ca0c5d..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/mocks/MockSshTunnel.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 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.test.mocks; - -import org.springframework.ide.eclipse.boot.dash.cf.client.SshHost; -import org.springframework.ide.eclipse.boot.dash.cf.debug.SshTunnel; -import org.springframework.ide.eclipse.boot.dash.util.LogSink; -import org.springsource.ide.eclipse.commons.livexp.core.AbstractDisposable; - -public class MockSshTunnel extends AbstractDisposable implements SshTunnel { - - boolean disposed = false; - private SshHost sshHost; - private String user; - private String oneTimeCode; - private int remotePort; - private LogSink log; - private int localPort; - - public MockSshTunnel( - SshHost sshHost, - String user, - String oneTimeCode, - int remotePort, - LogSink log, - int localPort - ) { - this.sshHost = sshHost; - this.user = user; - this.oneTimeCode = oneTimeCode; - this.remotePort = remotePort; - this.log = log; - this.localPort = localPort; - } - - public boolean isDisposed() { - return disposed; - } - - public SshHost getSshHost() { - return sshHost; - } - - public String getUser() { - return user; - } - - public String getOneTimeCode() { - return oneTimeCode; - } - - public int getRemotePort() { - return remotePort; - } - - public LogSink getLog() { - return log; - } - - public int getLocalPort() { - return localPort; - } - -} \ No newline at end of file diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/util/SslValidationDisabler.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/util/SslValidationDisabler.java deleted file mode 100644 index be50d02c5..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/util/SslValidationDisabler.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.springframework.ide.eclipse.boot.dash.test.util; - -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -public class SslValidationDisabler { - - private static boolean installed = false; - - public synchronized static void disableSslValidation() throws Exception { - if (installed) { - return; - } - installed = true; - // Create a trust manager that does not validate certificate chains - TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { - - @Override - public X509Certificate[] getAcceptedIssuers() { - return null; - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - } - - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - } - }}; - - // Install the all-trusting trust manager - SSLContext sc = SSLContext.getInstance("SSL"); - sc.init(null, trustAllCerts, new java.security.SecureRandom()); - HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - - // Create all-trusting host name verifier - HostnameVerifier allHostsValid = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }; - - // Install the all-trusting host verifier - HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/util/ZipDiff.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/util/ZipDiff.java deleted file mode 100644 index 69166019e..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/util/ZipDiff.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.test.util; - -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.zip.CRC32; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -/** - * Utility for comparing a given 'expected' zip file's contents with - * a 'actual' zip contents. - *

- * Two zips are considered equal if they have the same files / folders - * in their table-of contents and each of the files has identical contents. - *

- * This differ doesn't actually compare two files directly but rather computes - * a hash of the file contents instead and compares the hashes. So... - * their is a small chance that a difference may not be detected. - * - * @author Kris De Volder - */ -public class ZipDiff { - - final Map expectedHashes; - - public ZipDiff(InputStream expectedZipData) throws IOException { - expectedHashes = computeHashes(expectedZipData); - } - - public Map computeHashes(InputStream expectedZipData) throws IOException { - Map hashes = new HashMap<>(); - ZipInputStream zip = new ZipInputStream(expectedZipData); - ZipEntry ze; - byte[] buffer = new byte[1024]; - while (null != (ze = zip.getNextEntry())) { - String path = ze.getName(); - if (ze.isDirectory()) { - hashes.put(path, -1L); - } else { - CRC32 hasher = new CRC32(); - int len; - while ((len = zip.read(buffer)) > 0) { - hasher.update(buffer, 0, len); - } - hashes.put(path, hasher.getValue()); - } - } - return hashes; - } - - /** - * Read data from 'actualBits', interpret is as a ZipInputStream, - * and compare its contents to the expected contents. - *

- * Throws an exception when a difference is found. - */ - public void assertEqual(InputStream actualBits) throws IOException { - Map actualHashes = computeHashes(actualBits); - - //Check that everything that is in 'actualBits' was as expected - for (Entry actual : actualHashes.entrySet()) { - if (!expectedHashes.containsKey(actual.getKey())) { - fail("ZipEntry found but not expected: "+actual.getKey()); - } - long expectedHash = expectedHashes.get(actual.getKey()); - long actualHash = actual.getValue(); - if (expectedHash!=actualHash) { - fail("ZipEntry with different hashes: "+actual.getKey()+" "+expectedHash+"!="+actualHash); - } - } - - //Check that there's nothing that was expected but was missing from 'actual' - for (String expected : expectedHashes.keySet()) { - if (!actualHashes.containsKey(expected)) { - fail("ZipEntry expected but not found: "+expected); - } - } - } - - - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/AppNameReconcilerTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/AppNameReconcilerTest.java deleted file mode 100644 index 115d63cf4..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/AppNameReconcilerTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016, 2019 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.test.yaml; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; - -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.text.Document; -import org.junit.Test; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.AppNameAnnotation; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.AppNameAnnotationModel; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.AppNameReconciler; -import org.springframework.ide.eclipse.editor.support.yaml.ast.YamlASTProvider; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; - -/** - * Tests for application name reconciler - * - * @author Alex Boyko - * - */ -public class AppNameReconcilerTest { - - private void testAppNames(String manifest, String...expectedAppNames) throws Exception { - AppNameReconciler reconciler = new AppNameReconciler(new YamlASTProvider(new Yaml(new SafeConstructor()))); - AppNameAnnotationModel annotationModel = new AppNameAnnotationModel("test"); - Document doc = new Document(manifest); - reconciler.reconcile(doc, annotationModel, new NullProgressMonitor()); - HashSet actualAppNames = new HashSet<>(); - for (Iterator itr = annotationModel.getAnnotationIterator(); itr.hasNext();) { - Object o = itr.next(); - if (o instanceof AppNameAnnotation) { - actualAppNames.add(((AppNameAnnotation)o).getText()); - } - } - assertEquals(new HashSet<>(Arrays.asList(expectedAppNames)), actualAppNames); - } - - @Test - public void testSingleAppName() throws Exception { - testAppNames( - "applications:\n" + - "- name: app\n" + - " memory: 512M\n", - "app"); - } - - @Test - public void testMultipleAppNames() throws Exception { - testAppNames( - "applications:\n" + - "- name: app\n" + - " memory: 512M\n" + - "- name: anotherApp\n" + - " memory: 512M\n" + - "- name: someApp\n" + - " memory: 512M\n", - "app", "anotherApp", "someApp"); - } - - @Test - public void testNoAppName() throws Exception { - testAppNames( - "applications:\n" + - " memory: 512M\n"); - } - - @Test - public void testNoAppDueToSyntaxErrorNames() throws Exception { - testAppNames( - "applications:\n" + - "- name: app\n" + - " memory 512M\n" + - "- name: anotherApp\n" + - " memory: 512M\n" + - "- name: someApp\n" + - " memory: 512M\n"); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/CFRouteTests.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/CFRouteTests.java deleted file mode 100644 index f986ddf1f..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/CFRouteTests.java +++ /dev/null @@ -1,590 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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.test.yaml; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFRoute; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFRouteBuilder; - -public class CFRouteTests { - - public static final List SPRING_CLOUD_DOMAINS = Arrays.asList("springsource.org", "spring.io", - "myowndomain.spring.io", "tcp.spring.io", "spring.framework"); - - - @Test - public void test_domain_host() throws Exception { - CFRoute route = CFRoute.builder().from("myapp.spring.io", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("spring.io", route.getDomain()); - Assert.assertEquals("myapp", route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("myapp.spring.io", route.getRoute()); - } - - @Test - public void test_domain_only() throws Exception { - CFRoute route = CFRoute.builder().from("spring.io", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("spring.io", route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("spring.io", route.getRoute()); - } - - @Test - public void test_longer_domain_match() throws Exception { - CFRoute route = CFRoute.builder().from("myowndomain.spring.io", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("myowndomain.spring.io", route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("myowndomain.spring.io", route.getRoute()); - } - - @Test - public void test_longer_domain_nonexisting() throws Exception { - // For domains that do not exist, the first segment is assumed to be the "host" - CFRoute route = CFRoute.builder().from("app.doesnotexist.io", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("doesnotexist.io", route.getDomain()); - Assert.assertEquals("app",route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("app.doesnotexist.io", route.getRoute()); - } - - @Test - public void test_longer_domain_nonexisting_path() throws Exception { - CFRoute route = CFRoute.builder().from("app.doesnotexist.io/withpath", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("doesnotexist.io", route.getDomain()); - Assert.assertEquals("app",route.getHost()); - Assert.assertEquals("/withpath",route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("app.doesnotexist.io/withpath", route.getRoute()); - } - - @Test - public void test_longer_domain_nonexisting_path_port() throws Exception { - CFRoute route = CFRoute.builder().from("app.doesnotexist.io:60100/withpath", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("doesnotexist.io", route.getDomain()); - Assert.assertEquals("app",route.getHost()); - Assert.assertEquals("/withpath",route.getPath()); - Assert.assertEquals(60100, route.getPort()); - Assert.assertEquals("app.doesnotexist.io:60100/withpath", route.getRoute()); - } - - @Test - public void test_longer_domain_match_2() throws Exception { - CFRoute route = CFRoute.builder().from("myapp.myowndomain.spring.io", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("myowndomain.spring.io", route.getDomain()); - Assert.assertEquals("myapp", route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("myapp.myowndomain.spring.io", route.getRoute()); - } - - @Test - public void test_domain_host_path() throws Exception { - CFRoute route = CFRoute.builder().from("myapp.spring.io/appPath", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("spring.io", route.getDomain()); - Assert.assertEquals("myapp", route.getHost()); - Assert.assertEquals("/appPath", route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("myapp.spring.io/appPath", route.getRoute()); - } - - @Test - public void test_domain_host_path_2() throws Exception { - CFRoute route = CFRoute.builder().from("myapp.spring.io/appPath/additionalSegment", SPRING_CLOUD_DOMAINS) - .build(); - Assert.assertEquals("spring.io", route.getDomain()); - Assert.assertEquals("myapp", route.getHost()); - Assert.assertEquals("/appPath/additionalSegment", route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("myapp.spring.io/appPath/additionalSegment", route.getRoute()); - } - - @Test - public void test_tcp_port() throws Exception { - CFRoute route = CFRoute.builder().from("tcp.spring.io:9000", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("tcp.spring.io", route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(9000, route.getPort()); - Assert.assertEquals("tcp.spring.io:9000", route.getRoute()); - } - - @Test - public void test_host_path() throws Exception { - CFRoute route = CFRoute.builder().from("justhost/path", SPRING_CLOUD_DOMAINS).build(); - Assert.assertNull(route.getDomain()); - Assert.assertEquals("justhost",route.getHost()); - Assert.assertEquals("/path",route.getPath()); - Assert.assertEquals("justhost/path",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - } - - @Test - public void test_routes() throws Exception { - // A CFRoute does not validate route values. It can create any CF route even with wrong domains - // ports, hosts.. This tests that the route builder is parsing an invalid route into different - // components that some other external mechanism (like the CF Java client) can the use to validate - - CFRoute route = CFRoute.builder().from("", SPRING_CLOUD_DOMAINS).build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.EMPTY_ROUTE,route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - route = CFRoute.builder().from(null, SPRING_CLOUD_DOMAINS).build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.EMPTY_ROUTE,route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - route = CFRoute.builder().from(".", SPRING_CLOUD_DOMAINS).build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(".",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - route = CFRoute.builder().from("justhost", SPRING_CLOUD_DOMAINS).build(); - Assert.assertNull(route.getDomain()); - Assert.assertEquals("justhost",route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals("justhost",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - route = CFRoute.builder().from("justhost.", SPRING_CLOUD_DOMAINS).build(); - Assert.assertNull(route.getDomain()); - Assert.assertEquals("justhost",route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals("justhost.",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - route = CFRoute.builder().from(".justdomain", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("justdomain",route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(".justdomain",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - route = CFRoute.builder().from("..justdomain", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals(".justdomain",route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals("..justdomain",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - - route = CFRoute.builder().from("/justpath/morepath", SPRING_CLOUD_DOMAINS).build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertEquals("/justpath/morepath",route.getPath()); - Assert.assertEquals("/justpath/morepath",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - route = CFRoute.builder().from("/", SPRING_CLOUD_DOMAINS).build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertEquals("/",route.getPath()); - Assert.assertEquals("/",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - } - - @Test - public void test_incorrect_ports() throws Exception { - CFRoute route = CFRoute.builder().from("myapp.spring.io:notAn1nt3g3r", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("spring.io",route.getDomain()); - Assert.assertEquals("myapp",route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals("myapp.spring.io:notAn1nt3g3r",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - // Test parsing around the first encountered ':' - route = CFRoute.builder().from("https://myapp.spring.io", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("https://myapp.spring.io",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - route = CFRoute.builder().from("tcp.spring.io:8000:9000", SPRING_CLOUD_DOMAINS).build(); - // Only one ':' is allowed. it should not be able to parse a port if more than ':' is encountered - Assert.assertEquals("tcp.spring.io:8000:9000",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - - route = CFRoute.builder().from("myapp.spring.io:8000/", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("spring.io",route.getDomain()); - Assert.assertEquals("myapp",route.getHost()); - Assert.assertEquals("/",route.getPath()); - Assert.assertEquals("myapp.spring.io:8000/",route.getRoute()); - Assert.assertEquals(8000, route.getPort()); - } - - @Test - public void test_incorrect_paths() throws Exception { - CFRoute route = CFRoute.builder().from("myapp.spring.io//path", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("spring.io",route.getDomain()); - Assert.assertEquals("myapp",route.getHost()); - Assert.assertEquals("//path",route.getPath()); - Assert.assertEquals("myapp.spring.io//path",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - - route = CFRoute.builder().from("myapp.spring.io/", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("spring.io",route.getDomain()); - Assert.assertEquals("myapp",route.getHost()); - Assert.assertEquals("/",route.getPath()); - Assert.assertEquals("myapp.spring.io/",route.getRoute()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - } - - @Test - public void parse_null_domain() throws Exception { - String domain = CFRouteBuilder.findDomain("", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain(null, SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain(".", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain(".cfapps", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain("cfapps.", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain("...", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain("..cfapps..", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain(".cfapps..", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain("..cfapps.", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - } - - @Test - public void parse_valid_domain() throws Exception { - - // These exist - String domain = CFRouteBuilder.findDomain("spring.io", SPRING_CLOUD_DOMAINS); - Assert.assertEquals("spring.io", domain); - - domain = CFRouteBuilder.findDomain(".spring.io", SPRING_CLOUD_DOMAINS); - Assert.assertEquals("spring.io", domain); - - domain = CFRouteBuilder.findDomain("..spring.io", SPRING_CLOUD_DOMAINS); - Assert.assertEquals("spring.io", domain); - - domain = CFRouteBuilder.findDomain("myapp.spring.io", SPRING_CLOUD_DOMAINS); - Assert.assertEquals("spring.io", domain); - - domain = CFRouteBuilder.findDomain("myowndomain.spring.io", SPRING_CLOUD_DOMAINS); - Assert.assertEquals("myowndomain.spring.io", domain); - - domain = CFRouteBuilder.findDomain("myapp.myowndomain.spring.io", SPRING_CLOUD_DOMAINS); - Assert.assertEquals("myowndomain.spring.io", domain); - } - - @Test - public void parse_invalid_domain() throws Exception { - - // These variations of existing domains don't exist - String domain = CFRouteBuilder.findDomain("spring.io.", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain("spring.cfapps.io", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain("spring.io.cfapps", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain("unknown", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - - domain = CFRouteBuilder.findDomain("unknown.domain.io", SPRING_CLOUD_DOMAINS); - Assert.assertNull(domain); - } - - @Test - public void bug_142279275_parse_hostAndPathSameName() throws Exception { - - // Fixes Pivotal Tracker item 142279275 - CFRoute route = CFRoute.builder().from("hello-user.myowndomain.spring.io/hello", SPRING_CLOUD_DOMAINS).build(); - Assert.assertEquals("hello-user", route.getHost()); - Assert.assertEquals("myowndomain.spring.io", route.getDomain()); - Assert.assertEquals("/hello", route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("hello-user.myowndomain.spring.io/hello", route.getRoute()); - } - - @Test - public void build_route_value_empty() throws Exception { - - String val = CFRouteBuilder.buildRouteVal(null, null, null, CFRoute.NO_PORT); - Assert.assertEquals(CFRoute.EMPTY_ROUTE, val); - - val = CFRouteBuilder.buildRouteVal("", "", "", CFRoute.NO_PORT); - Assert.assertEquals(CFRoute.EMPTY_ROUTE, val); - - } - - @Test - public void build_route_value() throws Exception { - - String val = CFRouteBuilder.buildRouteVal("appHost", null, null, CFRoute.NO_PORT); - Assert.assertEquals("appHost", val); - - val = CFRouteBuilder.buildRouteVal(null, "cfapps.io", "", CFRoute.NO_PORT); - Assert.assertEquals("cfapps.io", val); - - val = CFRouteBuilder.buildRouteVal("appHost", "cfapps.io", "", CFRoute.NO_PORT); - Assert.assertEquals("appHost.cfapps.io", val); - - val = CFRouteBuilder.buildRouteVal(null, null, "/path/to/app", CFRoute.NO_PORT); - Assert.assertEquals("/path/to/app", val); - - val = CFRouteBuilder.buildRouteVal(null, null, "/path/to/app", 8000); - Assert.assertEquals(":8000/path/to/app", val); - - val = CFRouteBuilder.buildRouteVal(null, null, null, 60101); - Assert.assertEquals(":60101", val); - - val = CFRouteBuilder.buildRouteVal("appHost", "cfapps.io", "/path/to/app", CFRoute.NO_PORT); - Assert.assertEquals("appHost.cfapps.io/path/to/app", val); - - val = CFRouteBuilder.buildRouteVal("appHost", "cfapps.io", "/path/to/app", 60101); - Assert.assertEquals("appHost.cfapps.io:60101/path/to/app", val); - } - - @Test - public void test_build_route_from_domain() throws Exception { - CFRoute route = CFRoute.builder().domain("spring.io").build(); - Assert.assertEquals("spring.io", route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("spring.io", route.getRoute()); - } - - @Test - public void test_build_route_from_nonexisting_domain() throws Exception { - CFRoute route = CFRoute.builder().domain("not.exist.io").build(); - Assert.assertEquals("not.exist.io", route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("not.exist.io", route.getRoute()); - } - - @Test - public void test_build_route_from_null_domain() throws Exception { - CFRoute route = CFRoute.builder().domain(null).build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals(CFRoute.EMPTY_ROUTE, route.getRoute()); - } - - @Test - public void test_build_route_from_empty_domain() throws Exception { - CFRoute route = CFRoute.builder().domain("").build(); - Assert.assertEquals("",route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals(CFRoute.EMPTY_ROUTE,route.getRoute()); - } - - @Test - public void test_build_route_from_host() throws Exception { - CFRoute route = CFRoute.builder().host("myapp").build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getPath()); - Assert.assertEquals("myapp", route.getHost()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("myapp", route.getRoute()); - } - - @Test - public void test_build_route_from_null_host() throws Exception { - CFRoute route = CFRoute.builder().host(null).build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getPath()); - Assert.assertNull(route.getHost()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals(CFRoute.EMPTY_ROUTE, route.getRoute()); - } - - @Test - public void test_build_route_from_empty_host() throws Exception { - CFRoute route = CFRoute.builder().host("").build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getPath()); - Assert.assertEquals("",route.getHost()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals(CFRoute.EMPTY_ROUTE, route.getRoute()); - } - - @Test - public void test_build_route_from_domain_host() throws Exception { - CFRoute route = CFRoute.builder().domain("spring.io").host("myapp").build(); - Assert.assertEquals("spring.io", route.getDomain()); - Assert.assertEquals("myapp", route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("myapp.spring.io", route.getRoute()); - } - - @Test - public void test_build_route_from_path() throws Exception { - CFRoute route = CFRoute.builder().path("/path").build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertEquals("/path",route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("/path", route.getRoute()); - } - - @Test - public void test_build_route_from_path_2() throws Exception { - CFRoute route = CFRoute.builder().path("/path/additional").build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertEquals("/path/additional",route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("/path/additional", route.getRoute()); - } - - @Test - public void test_build_route_from_path_3() throws Exception { - CFRoute route = CFRoute.builder().path("/path/").build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertEquals("/path/",route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("/path/", route.getRoute()); - } - - @Test - public void test_build_route_from_domain_path() throws Exception { - CFRoute route = CFRoute.builder().path("/mypath").domain("spring.io").build(); - Assert.assertEquals("spring.io",route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertEquals("/mypath",route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("spring.io/mypath", route.getRoute()); - } - - @Test - public void test_build_route_from_host_path() throws Exception { - CFRoute route = CFRoute.builder().path("/mypath").host("myapp").build(); - Assert.assertNull(route.getDomain()); - Assert.assertEquals("myapp",route.getHost()); - Assert.assertEquals("/mypath",route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("myapp/mypath", route.getRoute()); - } - - @Test - public void test_build_route_from_host_path_samename() throws Exception { - CFRoute route = CFRoute.builder().path("/myapp").host("myapp").build(); - Assert.assertNull(route.getDomain()); - Assert.assertEquals("myapp",route.getHost()); - Assert.assertEquals("/myapp",route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals("myapp/myapp", route.getRoute()); - } - - @Test - public void test_build_route_from_host_path_port() throws Exception { - CFRoute route = CFRoute.builder().path("/mypath").host("myapp").port(8000).build(); - Assert.assertNull(route.getDomain()); - Assert.assertEquals("myapp",route.getHost()); - Assert.assertEquals("/mypath",route.getPath()); - Assert.assertEquals(8000, route.getPort()); - Assert.assertEquals("myapp:8000/mypath", route.getRoute()); - } - - @Test - public void test_build_route_from_domain_path_port() throws Exception { - CFRoute route = CFRoute.builder().path("/mypath").domain("spring.io").port(8000).build(); - Assert.assertEquals("spring.io", route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertEquals("/mypath",route.getPath()); - Assert.assertEquals(8000, route.getPort()); - Assert.assertEquals("spring.io:8000/mypath", route.getRoute()); - } - - @Test - public void test_build_route_from_port() throws Exception { - CFRoute route = CFRoute.builder().port(8000).build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(8000, route.getPort()); - Assert.assertEquals(":8000", route.getRoute()); - } - - - @Test - public void test_build_route_from_no_port() throws Exception { - CFRoute route = CFRoute.builder().port(CFRoute.NO_PORT).build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals(CFRoute.EMPTY_ROUTE, route.getRoute()); - } - - @Test - public void test_build_route_from_no_port_2() throws Exception { - CFRoute route = CFRoute.builder().port(-1).build(); - Assert.assertNull(route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(CFRoute.NO_PORT, route.getPort()); - Assert.assertEquals(CFRoute.EMPTY_ROUTE, route.getRoute()); - } - - @Test - public void test_tcp_port_building() throws Exception { - CFRoute route = CFRoute.builder().domain("tcp.spring.io").port(8000).build(); - Assert.assertEquals("tcp.spring.io",route.getDomain()); - Assert.assertNull(route.getHost()); - Assert.assertNull(route.getPath()); - Assert.assertEquals(8000, route.getPort()); - Assert.assertEquals("tcp.spring.io:8000", route.getRoute()); - } - - - @Test - public void test_complete() throws Exception { - CFRoute route = CFRoute.builder().domain("spring.io").host("myapp").path("/mypath/additional").port(8000).build(); - Assert.assertEquals("spring.io",route.getDomain()); - Assert.assertEquals("myapp", route.getHost()); - Assert.assertEquals("/mypath/additional", route.getPath()); - Assert.assertEquals(8000, route.getPort()); - Assert.assertEquals("myapp.spring.io:8000/mypath/additional", route.getRoute()); - } -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/DeploymentProperties2YamlTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/DeploymentProperties2YamlTest.java deleted file mode 100644 index 3a31a14b9..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/DeploymentProperties2YamlTest.java +++ /dev/null @@ -1,173 +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.test.yaml; - -import static org.junit.Assert.assertEquals; - -import java.io.File; -import java.io.FileInputStream; -import java.util.Arrays; -import java.util.Map; - -import org.junit.Test; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.ApplicationManifestHandler; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springsource.ide.eclipse.commons.frameworks.core.util.IOUtil; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.DumperOptions.FlowStyle; -import org.yaml.snakeyaml.DumperOptions.LineBreak; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; -import org.yaml.snakeyaml.representer.Representer; - -/** - * Tests for generating YAML files from {@link CloudApplicationDeploymentProperties} - * - * @author Alex Boyko - * - */ -public class DeploymentProperties2YamlTest { - - private static void testDeploymentProperties(CloudApplicationDeploymentProperties props, String expectedYamlFilePath) throws Exception { - Map map = ApplicationManifestHandler.toYaml(props, ManifestCompareMergeTests.createCloudData()); - - DumperOptions options = new DumperOptions(); - options.setExplicitStart(true); - options.setCanonical(false); - options.setPrettyFlow(true); - options.setDefaultFlowStyle(FlowStyle.BLOCK); - options.setLineBreak(LineBreak.getPlatformLineBreak()); - - String generatedManifest = new Yaml(new SafeConstructor(), new Representer(options), options).dump(map); - - File yamlFile = ManifestCompareMergeTests.getTestFile(expectedYamlFilePath); - FileInputStream inputStream = null; - try { - inputStream = new FileInputStream(yamlFile); - assertEquals(IOUtil.toString(inputStream).trim(), generatedManifest.trim()); - } finally { - if (inputStream != null) { - inputStream.close(); - } - } - } - - @Test - public void test_no_route_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setUris(null); - testDeploymentProperties(props, "manifest-generate-data/no-route-1.yml"); - } - - @Test - public void test_uri_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setUris(Arrays.asList("app.springsource.org")); - testDeploymentProperties(props, "manifest-generate-data/uri-1.yml"); - } - - @Test - public void test_uri_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setUris(Arrays.asList("app-1.springsource.org", "app-2.spring.io")); - testDeploymentProperties(props, "manifest-generate-data/uri-2.yml"); - } - - @Test - public void test_uri_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setUris(Arrays.asList("app-1.springsource.org")); - testDeploymentProperties(props, "manifest-generate-data/uri-3.yml"); - } - - @Test - public void test_no_hostname_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setUris(Arrays.asList("springsource.org")); - testDeploymentProperties(props, "manifest-generate-data/no-hostname-1.yml"); - } - - @Test - public void test_no_hostname_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setUris(Arrays.asList("springsource.org", "spring.io")); - testDeploymentProperties(props, "manifest-generate-data/no-hostname-2.yml"); - } - - @Test - public void test_command_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setCommand("my-command"); - props.setUris(Arrays.asList("app.springsource.org")); - testDeploymentProperties(props, "manifest-generate-data/command-1.yml"); - } - - @Test - public void test_stack_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setStack("my-stack"); - props.setUris(Arrays.asList("app.springsource.org")); - testDeploymentProperties(props, "manifest-generate-data/stack-1.yml"); - } - - - @Test - public void test_health_check_http() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setHealthCheckType("http"); - props.setHealthCheckHttpEndpoint("/testhealth"); - props.setUris(Arrays.asList("app.springsource.org")); - - testDeploymentProperties(props, "manifest-generate-data/health-check-http.yml"); - } - - - @Test - public void test_health_check_process() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setHealthCheckType("process"); - props.setUris(Arrays.asList("app.springsource.org")); - - testDeploymentProperties(props, "manifest-generate-data/health-check-process.yml"); - } - - @Test - public void test_health_check_port() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(512); - props.setHealthCheckType("port"); - props.setUris(Arrays.asList("app.springsource.org")); - - testDeploymentProperties(props, "manifest-generate-data/health-check-port.yml"); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/ManifestCompareMergeTests.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/ManifestCompareMergeTests.java deleted file mode 100644 index 7fc910db4..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/ManifestCompareMergeTests.java +++ /dev/null @@ -1,1162 +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.test.yaml; - -import static org.junit.Assert.assertEquals; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.text.Document; -import org.eclipse.text.edits.TextEdit; -import org.junit.Assert; -import org.junit.Test; -import org.osgi.framework.Bundle; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFCloudDomain; -import org.springframework.ide.eclipse.boot.dash.cf.client.CFStack; -import org.springframework.ide.eclipse.boot.dash.cf.client.v2.CFCloudDomainData; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.ApplicationManifestHandler; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudData; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.YamlGraphDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.test.AllBootDashTests; -import org.springsource.ide.eclipse.commons.frameworks.core.util.IOUtil; - -import com.google.common.collect.ImmutableList; - -/** - * Manifest YAML file and Deployment properties compare and merge tests. - * - * @author Alex Boyko - * - */ -public class ManifestCompareMergeTests { - - public static final String DEFAULT_BUILDPACK = "java_buildpack_offline"; - - public static final List SPRING_CLOUD_DOMAINS = Arrays.asList( - new CFCloudDomainData("springsource.org"), - new CFCloudDomainData("spring.io"), - new CFCloudDomainData("spring.framework")); - - public static final List SPRING_CLOUD_STACKS = Arrays.asList(new CFStack[] { new CFStack() { - @Override - public String getName() { - return "stack1"; - } - }}); - - public static CloudData createCloudData() { - return new CloudData(SPRING_CLOUD_DOMAINS, DEFAULT_BUILDPACK, SPRING_CLOUD_STACKS); - } - - private static void performMergeTest(File manifest, DeploymentProperties props, File expected) throws Exception { - String yamlContents = IOUtil.toString(new FileInputStream(manifest)); - String expectText = expected == null ? null : IOUtil.toString(new FileInputStream(expected)); - //Note: You don't need to close the FileInputStreams because IOUtil does that already. - performMergeTest(props, yamlContents, expectText); - } - - private static void performMergeTest(DeploymentProperties props, String manifest, String expectText) throws Exception { - YamlGraphDeploymentProperties yamlGraphProps = new YamlGraphDeploymentProperties(manifest, props.getAppName(), createCloudData()); - TextEdit edit = yamlGraphProps.getDifferences(props); - if (expectText == null) { - assertEquals(null, edit); - } else { - Document doc = new Document(manifest); - if (edit!=null) { - edit.apply(doc); - } - assertEquals(expectText.trim(), doc.get().trim()); - } - } - - public static File getTestFile(String path) throws IOException { - Bundle bundle = Platform.getBundle(AllBootDashTests.PLUGIN_ID); - File bundleFile = FileLocator.getBundleFile(bundle); - Assert.assertNotNull(bundleFile); - Assert.assertTrue("The bundle "+bundle.getBundleId()+" must be unpacked to allow using the embedded test resources", bundleFile.isDirectory()); - return new File(bundleFile, path); - } - - @Test - public void anchorReferenceAndExtend() throws Exception { - String manifest = - "defaults: &defaults\n" + - " services:\n" + - " - my-rabbit\n" + - " memory: 1G\n" + - " instances: 3\n" + - "applications:\n" + - "- name: chatter-web-ui\n" + - " <<: *defaults\n" + - " buildpack: java_buildpack"; - - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("chatter-web-ui"); - props.setServices(ImmutableList.of("my-rabbit")); - props.setMemory(1024); - props.setInstances(3); - props.setMemory(1024); - props.setBuildpack("java_buildpack"); - props.setUris(ImmutableList.of("chatter-web-ui.springsource.org")); - performMergeTest(props, manifest, manifest); - - props.setInstances(2); - performMergeTest(props, manifest, - "defaults: &defaults\n" + - " services:\n" + - " - my-rabbit\n" + - " memory: 1G\n" + - " instances: 2\n" + - "applications:\n" + - "- name: chatter-web-ui\n" + - " <<: *defaults\n" + - " buildpack: java_buildpack" - ); - } - - @Test - public void test_health_check_port() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setHealthCheckType("port"); - - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" - , // ==> - null - ); - - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: port\n" - , // ==> - null - ); - - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: none\n" - , // ==> - "applications:\n" + - "- name: app\n" + - " no-route: true\n" - ); - } - - @Test - public void test_health_check_none() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setHealthCheckType("none"); - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" - , // ==> - "applications:\n" + - "- name: app\n" + - " health-check-type: none\n" + - " no-route: true\n" - ); - - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: port\n" - , // ==> - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: none\n" - ); - - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: none\n" - , // ==> - null - ); - } - - @Test - public void test_health_check_process() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setHealthCheckType("process"); - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" - , // ==> - "applications:\n" + - "- name: app\n" + - " health-check-type: process\n" + - " no-route: true\n" - ); - - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: port\n" - , // ==> - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: process\n" - ); - - // Test switch from http and http endpoint to process - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: http\n" + - " health-check-http-endpoint: /testhealth\n" - , // ==> - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: process\n" - ); - - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: process\n" - , // ==> - null - ); - } - - @Test - public void test_health_check_http_endpoint() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - // test both "http" type and "http endpoint", as both are used together - props.setHealthCheckType("http"); - props.setHealthCheckHttpEndpoint("/testhealth"); - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" - , // ==> - "applications:\n" + - "- name: app\n" + - " health-check-type: http\n" + - " health-check-http-endpoint: /testhealth\n" + - " no-route: true\n" - ); - - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: port\n" - , // ==> - "applications:\n" + - "- name: app\n" + - " health-check-http-endpoint: /testhealth\n" + - " no-route: true\n" + - " health-check-type: http\n" - ); - - // Test that old endpoint is replaced with new one - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: http\n" + - " health-check-http-endpoint: /oldtesthealth\n" - , // ==> - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: http\n" + - " health-check-http-endpoint: /testhealth\n" - ); - - performMergeTest(props, - "applications:\n" + - "- name: app\n" + - " no-route: true\n" + - " health-check-type: http\n" + - " health-check-http-endpoint: /testhealth\n" - , // ==> - null - ); - } - - - @Test - public void test_memory_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/memory-1.yml"), props, getTestFile("mergeTestsData/memory-1-expected.yml")); - } - - @Test - public void test_memory_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/memory-2.yml"), props, getTestFile("mergeTestsData/memory-2-expected.yml")); - } - - @Test - public void test_memory_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/memory-3.yml"), props, getTestFile("mergeTestsData/memory-3-expected.yml")); - } - - @Test - public void test_memory_4() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/memory-4.yml"), props, null); - } - - @Test - public void test_memory_5() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/memory-5.yml"), props, null); - } - - @Test - public void test_memory_6() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(3000); - performMergeTest(getTestFile("mergeTestsData/memory-5.yml"), props, getTestFile("mergeTestsData/memory-6-expected.yml")); - } - - @Test - public void test_appNameNoMatch_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app1"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/appNameNoMatch-1.yml"), props, getTestFile("mergeTestsData/appNameNoMatch-1-expected.yml")); - } - - @Test - public void test_appNameNoMatch_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app1"); - props.setUris(Collections.singletonList("test-app-1.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/appNameNoMatch-2.yml"), props, getTestFile("mergeTestsData/appNameNoMatch-2-expected.yml")); - } - - @Test - public void test_appNameNoMatch_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app1"); - props.setUris(Collections.singletonList("test-app-1.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/appNameNoMatch-3.yml"), props, getTestFile("mergeTestsData/appNameNoMatch-3-expected.yml")); - } - - @Test - public void test_appNameNoMatch_4() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app1"); - props.setUris(Collections.singletonList("app-1.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/appNameNoMatch-4.yml"), props, getTestFile("mergeTestsData/appNameNoMatch-4-expected.yml")); - } - - @Test - public void test_noAppsNode_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/noAppsNode-1.yml"), props, getTestFile("mergeTestsData/noAppsNode-1-expected.yml")); - } - - @Test - public void test_noAppsNode_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app1"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/noAppsNode-2.yml"), props, getTestFile("mergeTestsData/noAppsNode-2-expected.yml")); - } - - @Test - public void test_noManifest_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/noManifest-1.yml"), props, getTestFile("mergeTestsData/noManifest-1-expected.yml")); - } - - @Test - public void test_noManifest_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/noManifest-2.yml"), props, getTestFile("mergeTestsData/noManifest-2-expected.yml")); - } - - @Test - public void test_map_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - Map env = new LinkedHashMap<>(); - env.put("KEY1", "value1"); - env.put("KEY2", "value2"); - env.put("KEY3", "value3"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/map-1.yml"), props, getTestFile("mergeTestsData/map-1-expected.yml")); - } - - @Test - public void test_map_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - Map env = new LinkedHashMap<>(); - env.put("KEY1", "value1"); - env.put("KEY2", "value2"); - env.put("KEY3", "value3"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/map-2.yml"), props, getTestFile("mergeTestsData/map-2-expected.yml")); - } - - @Test - public void test_map_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/map-3.yml"), props, getTestFile("mergeTestsData/map-3-expected.yml")); - } - - @Test - public void test_map_4() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/map-4.yml"), props, getTestFile("mergeTestsData/map-4-expected.yml")); - } - - @Test - public void test_map_5() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - Map env = new LinkedHashMap<>(); - env.put("KEY1", "value1"); - env.put("KEY2", "value2"); - env.put("KEY3", "value3"); - env.put("KEY4", "value4"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/map-5.yml"), props, getTestFile("mergeTestsData/map-5-expected.yml")); - } - - @Test - public void test_map_6() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - Map env = new LinkedHashMap<>(); - env.put("KEY1", "value1"); - env.put("KEY2", "value2"); - env.put("KEY3", "value3"); - env.put("KEY4", "value4"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/map-6.yml"), props, getTestFile("mergeTestsData/map-6-expected.yml")); - } - - @Test - public void test_map_7() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - Map env = new LinkedHashMap<>(); - env.put("KEY1", "value1"); - env.put("KEY2", "value2"); - env.put("KEY3", "value3"); - env.put("KEY4", "value4"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/map-7.yml"), props, getTestFile("mergeTestsData/map-7-expected.yml")); - } - - @Test - public void test_map_8() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/map-8.yml"), props, getTestFile("mergeTestsData/map-8-expected.yml")); - } - - @Test - public void test_map_9() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - Map env = new LinkedHashMap<>(); - env.put("KEY1", "value1"); - env.put("KEY2", "value2"); - env.put("KEY3", "value3"); - env.put("KEY4", "value4"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/map-9.yml"), props, getTestFile("mergeTestsData/map-9-expected.yml")); - } - - @Test - public void test_map_10() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - Map env = new LinkedHashMap<>(); - env.put("KEY1", "value1"); - env.put("KEY2", "value2"); - env.put("KEY3", "value3"); - env.put("KEY4", "value4"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/map-10.yml"), props, getTestFile("mergeTestsData/map-10-expected.yml")); - } - - @Test - public void test_map_11() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - Map env = new LinkedHashMap<>(); - env.put("KEY1", "value1"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/map-11.yml"), props, getTestFile("mergeTestsData/map-11-expected.yml")); - } - - @Test - public void test_health_check_http() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setHealthCheckType("http"); - props.setHealthCheckHttpEndpoint("/testhealth"); - props.setUris(Collections.singletonList("app-1.springsource.org")); - - performMergeTest(getTestFile("mergeTestsData/health-check-http.yml"), props, getTestFile("mergeTestsData/health-check-http-expected.yml")); - } - - @Test - public void test_health_check_process_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("app-1.springsource.org")); - props.setMemory(2048); - props.setHealthCheckType("process"); - performMergeTest(getTestFile("mergeTestsData/health-check-process.yml"), props, getTestFile("mergeTestsData/health-check-process-expected.yml")); - } - - @Test - public void test_health_check_port_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("app-1.springsource.org")); - props.setMemory(2048); - // NOTE: port is a "default" value, so when setting port, the resulting manifest will have no health check type - // as no health check type is equivalent to having "port" type - props.setHealthCheckType("port"); - performMergeTest(getTestFile("mergeTestsData/health-check-port.yml"), props, getTestFile("mergeTestsData/health-check-port-expected.yml")); - } - - @Test - public void test_instances_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/instances-1.yml"), props, getTestFile("mergeTestsData/instances-1-expected.yml")); - } - - @Test - public void test_instances_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/instances-2.yml"), props, getTestFile("mergeTestsData/instances-2-expected.yml")); - } - - @Test - public void test_instances_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/instances-3.yml"), props, getTestFile("mergeTestsData/instances-3-expected.yml")); - } - - @Test - public void test_instances_4() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/instances-4.yml"), props, null); - } - - @Test - public void test_instances_5() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/instances-5.yml"), props, getTestFile("mergeTestsData/instances-5-expected.yml")); - } - - @Test - public void test_root_comment_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(512); - performMergeTest(getTestFile("mergeTestsData/root-comment-1.yml"), props, getTestFile("mergeTestsData/root-comment-1-expected.yml")); - } - - @Test - public void test_root_comment_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(512); - performMergeTest(getTestFile("mergeTestsData/root-comment-2.yml"), props, getTestFile("mergeTestsData/root-comment-2-expected.yml")); - } - - @Test - public void test_root_comment_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(512); - props.setInstances(2); - performMergeTest(getTestFile("mergeTestsData/root-comment-3.yml"), props, getTestFile("mergeTestsData/root-comment-3-expected.yml")); - } - - @Test - public void test_root_comment_4() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.singletonList("test-app.springsource.org")); - props.setMemory(512); - performMergeTest(getTestFile("mergeTestsData/root-comment-4.yml"), props, getTestFile("mergeTestsData/root-comment-4-expected.yml")); - } - - @Test - public void test_no_route_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.emptyList()); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/no-route-1.yml"), props, getTestFile("mergeTestsData/no-route-1-expected.yml")); - } - - @Test - public void test_no_route_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.emptyList()); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/no-route-2.yml"), props, getTestFile("mergeTestsData/no-route-2-expected.yml")); - } - - @Test - public void test_no_route_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.emptyList()); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/no-route-3.yml"), props, null); - } - - @Test - public void test_no_hostname_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("my-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/no-hostname-1.yml"), props, getTestFile("mergeTestsData/no-hostname-1-expected.yml")); - } - - @Test - public void test_no_hostname_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/no-hostname-2.yml"), props, getTestFile("mergeTestsData/no-hostname-2-expected.yml")); - } - - @Test - public void test_no_hostname_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/no-hostname-3.yml"), props, null); - } - - @Test - public void test_random_route_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/random-route-1.yml"), props, null); - } - - @Test - public void test_random_route_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("my-app1.springsource.org", "my-app2.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/random-route-2.yml"), props, getTestFile("mergeTestsData/random-route-2-expected.yml")); - } - - @Test - public void test_random_route_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("app2.springsource.org")); - props.setMemory(1024); - props.setBuildpack("java_buildpack_offline"); - performMergeTest(getTestFile("mergeTestsData/random-route-3.yml"), props, getTestFile("mergeTestsData/random-route-3-expected.yml")); - } - - @Test - public void test_hosts_domains_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("my-app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/hosts-domains-1.yml"), props, getTestFile("mergeTestsData/hosts-domains-1-expected.yml")); - } - - @Test - public void test_hosts_domains_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("app1.springsource.org", "app2.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/hosts-domains-2.yml"), props, getTestFile("mergeTestsData/hosts-domains-2-expected.yml")); - } - - @Test - public void test_hosts_domains_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("app1.springsource.org", "app2.springsource.org", "app1.spring.io", "app2.spring.io")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/hosts-domains-3.yml"), props, null); - } - - @Test - public void test_hosts_domains_4() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("app1.springsource.org", "app2.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/hosts-domains-4.yml"), props, getTestFile("mergeTestsData/hosts-domains-4-expected.yml")); - } - - @Test - public void test_hosts_domains_5() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("app.springsource.org")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/hosts-domains-5.yml"), props, getTestFile("mergeTestsData/hosts-domains-5-expected.yml")); - } - - @Test - public void test_hosts_domains_6() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("spring.framework")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/hosts-domains-6.yml"), props, getTestFile("mergeTestsData/hosts-domains-6-expected.yml")); - } - - @Test - public void test_hosts_domains_7() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("app1.springsource.org", "app2.springsource.org", "app3.springsource.org", - "app1.spring.io", "app2.spring.io", "app3.spring.io", "app1.spring.framework", "app2.spring.framework", - "app3.spring.framework")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/hosts-domains-7.yml"), props, null); - } - - @Test - public void test_hosts_domains_8() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("app1.spring.io", "app2.spring.io")); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/hosts-domains-8.yml"), props, getTestFile("mergeTestsData/hosts-domains-8-expected.yml")); - } - - @Test - public void test_root_node_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(3); - props.setUris(Arrays.asList("app.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-node-1.yml"), props, getTestFile("mergeTestsData/root-node-1-expected.yml")); - } - - @Test - public void test_root_node_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-node-2.yml"), props, getTestFile("mergeTestsData/root-node-2-expected.yml")); - } - - @Test - public void test_root_list_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app.springsource.org")); - props.setServices(Arrays.asList("s1", "s2", "s3")); - performMergeTest(getTestFile("mergeTestsData/root-list-1.yml"), props, getTestFile("mergeTestsData/root-list-1-expected.yml")); - } - - @Test - public void test_root_list_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app.springsource.org")); - props.setServices(Arrays.asList("s1", "s2", "s3", "s4", "s5")); - performMergeTest(getTestFile("mergeTestsData/root-list-2.yml"), props, getTestFile("mergeTestsData/root-list-2-expected.yml")); - } - - @Test - public void test_root_list_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app.springsource.org")); - props.setServices(Arrays.asList("s1", "s3", "s4", "s5")); - performMergeTest(getTestFile("mergeTestsData/root-list-3.yml"), props, getTestFile("mergeTestsData/root-list-3-expected.yml")); - } - - @Test - public void test_root_map_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app.springsource.org")); - Map env = new HashMap<>(); - env.put("k1", "v1"); - env.put("k2", "v2"); - env.put("k3", "v3"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/root-map-1.yml"), props, getTestFile("mergeTestsData/root-map-1-expected.yml")); - } - - @Test - public void test_root_map_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app.springsource.org")); - Map env = new HashMap<>(); - env.put("k1", "v1"); - env.put("k2", "v2-alt"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/root-map-2.yml"), props, getTestFile("mergeTestsData/root-map-2-expected.yml")); - } - - @Test - public void test_root_map_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-map-3.yml"), props, getTestFile("mergeTestsData/root-map-3-expected.yml")); - } - - @Test - public void test_root_map_4() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app.springsource.org")); - Map env = new HashMap<>(); - env.put("k2", "v2"); - props.setEnvironmentVariables(env); - performMergeTest(getTestFile("mergeTestsData/root-map-4.yml"), props, getTestFile("mergeTestsData/root-map-4-expected.yml")); - } - - @Test - public void test_root_noroute_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-noroute-1.yml"), props, getTestFile("mergeTestsData/root-noroute-1-expected.yml")); - } - - @Test - public void test_root_noroute_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - performMergeTest(getTestFile("mergeTestsData/root-noroute-2.yml"), props, getTestFile("mergeTestsData/root-noroute-2-expected.yml")); - } - - @Test - public void test_root_randomroute_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app-1.springsource.org", "app-2.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-randomroute-1.yml"), props, getTestFile("mergeTestsData/root-randomroute-1-expected.yml")); - } - - @Test - public void test_root_randomroute_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-randomroute-2.yml"), props, null); - } - - @Test - public void test_root_nohost_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("my-app.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-nohost-1.yml"), props, getTestFile("mergeTestsData/root-nohost-1-expected.yml")); - } - - @Test - public void test_root_nohost_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("springsource.org", "spring.io")); - performMergeTest(getTestFile("mergeTestsData/root-nohost-2.yml"), props, getTestFile("mergeTestsData/root-nohost-2-expected.yml")); - } - - @Test - public void test_root_nohost_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-nohost-3.yml"), props, null); - } - - @Test - public void test_root_hosts_domains_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app1.springsource.org", "app2.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-hosts-domains-1.yml"), props, getTestFile("mergeTestsData/root-hosts-domains-1-expected.yml")); - } - - @Test - public void test_root_hosts_domains_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("my-app.springsource.org", "test-app1.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-hosts-domains-2.yml"), props, getTestFile("mergeTestsData/root-hosts-domains-2-expected.yml")); - } - - @Test - public void test_root_hosts_domains_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("test-app-1.springsource.org", "test-app-3.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/root-hosts-domains-3.yml"), props, getTestFile("mergeTestsData/root-hosts-domains-3-expected.yml")); - } - - @Test - public void test_routes_1() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app-1.springsource.org", "app-2.springsource.org", "app-3.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/routes-1.yml"), props, getTestFile("mergeTestsData/routes-1-expected.yml")); - } - - @Test - public void test_routes_2() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app-1.springsource.org", "app-2.springsource.org", "app-3.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/routes-2.yml"), props, getTestFile("mergeTestsData/routes-2-expected.yml")); - } - - @Test - public void test_routes_3() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app-1.springsource.org", "app-2.springsource.org", "app-3.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/routes-3.yml"), props, getTestFile("mergeTestsData/routes-3-expected.yml")); - } - - @Test - public void test_routes_4() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app-1.springsource.org", "app-2.springsource.org", "app-3.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/routes-4.yml"), props, getTestFile("mergeTestsData/routes-4-expected.yml")); - } - - @Test - public void test_routes_5() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app-1.springsource.org", "app-2.springsource.org", "app-3.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/routes-5.yml"), props, getTestFile("mergeTestsData/routes-5-expected.yml")); - } - - @Test - public void test_routes_6() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("demo-app"); - props.setMemory(1024); - props.setInstances(1); - props.setUris(Arrays.asList("route-2.springsource.org")); - performMergeTest(getTestFile("mergeTestsData/routes-6.yml"), props, getTestFile("mergeTestsData/routes-6-expected.yml")); - } - - @Test - public void test_routes_paths_ports() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setMemory(2048); - props.setInstances(1); - props.setUris(Arrays.asList("app-1.springsource.org", "app-2.springsource.org", "app-3.springsource.org", "app-4.springsource.org/myappPath/moresegments", "tcp.springsource.org:9003")); - performMergeTest(getTestFile("mergeTestsData/routes-paths-ports.yml"), props, getTestFile("mergeTestsData/routes-paths-ports-expected.yml")); - } - - @Test - public void test_no_route_5() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Collections.emptyList()); - props.setMemory(2048); - performMergeTest(getTestFile("mergeTestsData/no-route-5.yml"), props, getTestFile("mergeTestsData/no-route-5-expected.yml")); - } - - @Test - public void test_random_route_4() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("app-1.springsource.org", "app-2.springsource.org", "app-3.springsource.org")); - props.setMemory(512); - performMergeTest(getTestFile("mergeTestsData/random-route-4.yml"), props, null); - } - - @Test - public void test_random_route_5() throws Exception { - CloudApplicationDeploymentProperties props = new CloudApplicationDeploymentProperties(); - props.setAppName("app"); - props.setUris(Arrays.asList("app.springsource.org")); - props.setMemory(512); - performMergeTest(getTestFile("mergeTestsData/random-route-5.yml"), props, getTestFile("mergeTestsData/random-route-5-expected.yml")); - } -} - diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/Yaml2DeploymentPropertiesTest.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/Yaml2DeploymentPropertiesTest.java deleted file mode 100644 index 5272376b4..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/yaml/Yaml2DeploymentPropertiesTest.java +++ /dev/null @@ -1,477 +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.test.yaml; - -import static org.junit.Assert.assertEquals; - -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.junit.Test; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.ApplicationManifestHandler; -import org.springframework.ide.eclipse.boot.dash.cf.deployment.CloudApplicationDeploymentProperties; -import org.springframework.ide.eclipse.boot.dash.cloudfoundry.deployment.DeploymentProperties; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -/** - * Tests for parsing YAML deployment manifest into - * {@link CloudApplicationDeploymentProperties} - * - * @author Alex Boyko - * - */ -public class Yaml2DeploymentPropertiesTest { - - private static CloudApplicationDeploymentProperties readDeploymentPropertiesFile(final String filePath) throws Exception { - ApplicationManifestHandler handler = new ApplicationManifestHandler(null, ManifestCompareMergeTests.createCloudData()) { - @Override - protected InputStream getInputStream() throws Exception { - return new FileInputStream(ManifestCompareMergeTests.getTestFile(filePath)); - } - }; - return handler.load(new NullProgressMonitor()).get(0); - } - - @Test - public void test_health_check_process() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/health-check-process.yml"); - assertEquals("Health check types not equal", "process", props.getHealthCheckType()); - } - - @Test - public void test_health_check_port() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/health-check-port.yml"); - assertEquals("Health check types not equal", "port", props.getHealthCheckType()); - } - - @Test - public void test_health_check_http() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/health-check-http.yml"); - assertEquals("Health check types not equal", "http", props.getHealthCheckType()); - assertEquals("Health check http endpoints not equal", "/testhealth", props.getHealthCheckHttpEndpoint()); - } - - @Test - public void test_no_route_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-route-1.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_no_route_2() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-route-2.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_no_route_3() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-route-3.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_no_route_4() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-route-4.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_no_route_5() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-route-5.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_no_hostname_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-hostname-1.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("my-app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_no_hostname_2() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-hostname-2.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("my-app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_no_hostname_3() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-hostname-3.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("my-app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_no_hostname_4() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-hostname-4.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_no_hostname_5() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-hostname-5.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_no_hostname_6() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/no-hostname-6.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("springsource.org", "spring.framework")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_random_route_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/random-route-1.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("my-app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_random_route_2() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/random-route-2.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("my-app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_random_route_3() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/random-route-3.yml"); - HashSet uris = new HashSet<>(props.getUris()); - assertEquals(1, uris.size()); - String uri = uris.iterator().next(); - String host = uri.substring(0, uri.indexOf('.')); - HashSet expected = new HashSet<>(Collections.singletonList("springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_random_route_4() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/random-route-4.yml"); - HashSet uris = new HashSet<>(props.getUris()); - assertEquals(1, uris.size()); - String uri = uris.iterator().next(); - String host = uri.substring(0, uri.indexOf('.')); - HashSet expected = new HashSet<>(Collections.singletonList("springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_random_route_5() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/random-route-5.yml"); - HashSet uris = new HashSet<>(props.getUris()); - Set expected = ImmutableSet.of("spring.io", "spring.framework"); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_domains_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/domains-1.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("my-app.spring.io")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_domains_2() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/domains-2.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("my-app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_domains_3() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/domains-3.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("my-app.spring.framework")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_domains_4() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/domains-4.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("my-app.spring.io")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_domains_5() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/domains-5.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("my-app.spring.framework", "my-app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_domains_6() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/domains-6.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Collections.singletonList("my-app.spring.what")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_domains_7() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/domains-7.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("my-app.springsource.org", "my-app.spring.framework", "my-app.spring.io")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_domains_8() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/domains-8.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("my-app.springsource.org", "my-app.spring.framework", "my-app.spring.io")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_domains_9() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/domains-9.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("my-app.springsource.org", "my-app.spring.framework", "my-app.spring.io")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_hosts_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/hosts-1.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_hosts_2() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/hosts-2.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("my-app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_hosts_3() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/hosts-3.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("my-app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_hosts_4() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/hosts-4.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("my-app.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_hosts_5() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/hosts-5.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("my-app-1.springsource.org", "my-app-2.springsource.org", "my-app-3.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_hosts_6() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/hosts-6.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("my-app-1.springsource.org", "my-app-2.springsource.org", - "my-app-3.springsource.org", "my-root-2.springsource.org", "my-root-3.springsource.org")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_uris_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/uris-1.yml"); - HashSet uris = new HashSet<>(props.getUris()); - HashSet expected = new HashSet<>(Arrays.asList("my-app-1.springsource.org", "my-app-2.springsource.org", - "my-app-3.springsource.org", "my-app-1.spring.io", "my-app-2.spring.io", "my-app-3.spring.io", - "my-app-1.spring.framework", "my-app-2.spring.framework", "my-app-3.spring.framework")); - assertEquals("Uris sets not equal", expected, uris); - } - - @Test - public void test_root_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/root-1.yml"); - assertEquals("app", props.getAppName()); - assertEquals(1024, props.getMemory()); - assertEquals(new HashSet<>(Arrays.asList("app.spring.io")), props.getUris()); - } - - @Test - public void test_command_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/command-1.yml"); - assertEquals("mycommand", props.getCommand()); - } - - @Test - public void test_stack_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/stack-1.yml"); - assertEquals("stack1", props.getStack()); - } - - @Test - public void test_memory_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/memory-1.yml"); - assertEquals("Uris sets not equal", DeploymentProperties.DEFAULT_MEMORY, props.getMemory()); - } - - @Test - public void test_memory_2() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/memory-2.yml"); - assertEquals("Uris sets not equal", 768, props.getMemory()); - } - - @Test - public void test_memory_3() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/memory-3.yml"); - assertEquals("Uris sets not equal", 768, props.getMemory()); - } - - @Test - public void test_memory_4() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/memory-4.yml"); - assertEquals("Uris sets not equal", 768, props.getMemory()); - } - - @Test - public void test_memory_5() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/memory-5.yml"); - assertEquals("Uris sets not equal", 1024, props.getMemory()); - } - - @Test - public void test_memory_6() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/memory-6.yml"); - assertEquals("Uris sets not equal", 1024, props.getMemory()); - } - - @Test(expected=CoreException.class) - public void test_memory_7() throws Exception { - readDeploymentPropertiesFile("manifest-parse-data/memory-7.yml"); - } - - @Test(expected=CoreException.class) - public void test_memory_8() throws Exception { - readDeploymentPropertiesFile("manifest-parse-data/memory-8.yml"); - } - - @Test - public void test_memory_9() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/memory-9.yml"); - assertEquals("Uris sets not equal", 3072, props.getMemory()); - } - - @Test - public void test_memory_10() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/memory-10.yml"); - assertEquals("Uris sets not equal", 4096, props.getMemory()); - } - - @Test - public void test_memory_11() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile("manifest-parse-data/memory-11.yml"); - assertEquals("Uris sets not equal", 1500, props.getMemory()); - } - - @Test - public void test_routes_no_route() throws Exception { - // Manifest has a route but if "no-route" is also present, test that - // list of URI is empty in the props - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile( - "manifest-generate-data/routes-no-route.yml"); - - assertEquals("Routes and URIs not equal", ImmutableList.of(), ImmutableList.copyOf(props.getUris())); - } - - @Test - public void test_routes_1() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile( - "manifest-parse-data/routes-1.yml"); - - assertEquals("Routes not equal", ImmutableSet.of("my-route.springsource.org"), ImmutableSet.copyOf(props.getUris())); - } - - @Test - public void test_routes_2() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile( - "manifest-parse-data/routes-2.yml"); - - assertEquals("Routes not equal", ImmutableSet.of("my-route-1.springsource.org", "my-route-2.springsource.org"), ImmutableSet.copyOf(props.getUris())); - } - - @Test - public void test_routes_3() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile( - "manifest-parse-data/routes-3.yml"); - - assertEquals("Routes not equal", ImmutableSet.of(), ImmutableSet.copyOf(props.getUris())); - } - - @Test - public void test_routes_4() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile( - "manifest-parse-data/routes-4.yml"); - - assertEquals("Routes not equal", ImmutableSet.of("my-route-1.springsource.org", "my-route-2.springsource.org"), ImmutableSet.copyOf(props.getUris())); - } - - @Test - public void test_routes_5() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile( - "manifest-parse-data/routes-5.yml"); - - assertEquals("Routes not equal", ImmutableSet.of("my-route-1.springsource.org", "my-route-2.springsource.org", - "my-root-route-1.springsource.org"), ImmutableSet.copyOf(props.getUris())); - } - - @Test - public void test_routes_6() throws Exception { - CloudApplicationDeploymentProperties props = readDeploymentPropertiesFile( - "manifest-parse-data/routes-6.yml"); - - assertEquals("Routes not equal", ImmutableSet.of("my-route-1.invaliddomain.org", "my-route-2.springsource.org"), ImmutableSet.copyOf(props.getUris())); - } -} diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/.classpath b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/.classpath deleted file mode 100644 index db27b5575..000000000 --- a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/.classpath +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/.project b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/.project deleted file mode 100644 index 514b6962d..000000000 --- a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.springsource.ide.eclipse.commons.cloudfoundry.client.v2 - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/.settings/org.eclipse.jdt.core.prefs b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 9f6ece88b..000000000 --- a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,8 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/META-INF/MANIFEST.MF b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/META-INF/MANIFEST.MF deleted file mode 100644 index d7d9a48b2..000000000 --- a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/META-INF/MANIFEST.MF +++ /dev/null @@ -1,197 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-Vendor: %providerName -Bundle-SymbolicName: org.springsource.ide.eclipse.commons.cloudfoundry.client.v2 -Bundle-Version: 4.18.0.qualifier -Bundle-Localization: plugin -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Require-Bundle: io.projectreactor.reactor-core;bundle-version="[3.3.1,3.3.2)", - org.reactivestreams.reactive-streams;bundle-version="1.0.3" -Bundle-ClassPath: dependencies/cloudfoundry-client-4.3.0.RELEASE.jar, - dependencies/cloudfoundry-client-reactor-4.3.0.RELEASE.jar, - dependencies/cloudfoundry-operations-4.3.0.RELEASE.jar, - dependencies/cloudfoundry-util-4.3.0.RELEASE.jar, - dependencies/commons-compress-1.19.jar, - dependencies/evo-inflector-1.2.2.jar, - dependencies/jackson-annotations-2.10.1.jar, - dependencies/jackson-core-2.10.1.jar, - dependencies/jackson-databind-2.10.1.jar, - dependencies/jackson-datatype-jdk8-2.10.1.jar, - dependencies/java-semver-0.9.0.jar, - dependencies/jcl-over-slf4j-1.7.29.jar, - dependencies/jjwt-0.9.1.jar, - dependencies/netty-buffer-4.1.43.Final.jar, - dependencies/netty-codec-4.1.43.Final.jar, - dependencies/netty-codec-http-4.1.43.Final.jar, - dependencies/netty-codec-http2-4.1.43.Final.jar, - dependencies/netty-codec-socks-4.1.43.Final.jar, - dependencies/netty-common-4.1.43.Final.jar, - dependencies/netty-handler-4.1.43.Final.jar, - dependencies/netty-handler-proxy-4.1.43.Final.jar, - dependencies/netty-resolver-4.1.43.Final.jar, - dependencies/netty-transport-4.1.43.Final.jar, - dependencies/netty-transport-native-epoll-4.1.43.Final-linux-x86_64.jar, - dependencies/netty-transport-native-unix-common-4.1.43.Final.jar, - dependencies/okio-1.8.0.jar, - dependencies/reactor-netty-0.9.2.RELEASE.jar, - dependencies/slf4j-api-1.7.29.jar, - dependencies/slf4j-simple-1.7.16.jar, - dependencies/snakeyaml-1.25.jar, - dependencies/spring-core-5.2.2.RELEASE.jar, - dependencies/spring-jcl-5.2.2.RELEASE.jar, - dependencies/spring-web-5.2.2.RELEASE.jar, - dependencies/wire-runtime-2.2.0.jar -Export-Package: org.cloudfoundry, - org.cloudfoundry.client, - org.cloudfoundry.client.v2, - org.cloudfoundry.client.v2.applications, - org.cloudfoundry.client.v2.applicationusageevents, - org.cloudfoundry.client.v2.blobstores, - org.cloudfoundry.client.v2.buildpacks, - org.cloudfoundry.client.v2.domains, - org.cloudfoundry.client.v2.environmentvariablegroups, - org.cloudfoundry.client.v2.events, - org.cloudfoundry.client.v2.featureflags, - org.cloudfoundry.client.v2.info, - org.cloudfoundry.client.v2.jobs, - org.cloudfoundry.client.v2.organizationquotadefinitions, - org.cloudfoundry.client.v2.organizations, - org.cloudfoundry.client.v2.privatedomains, - org.cloudfoundry.client.v2.resourcematch, - org.cloudfoundry.client.v2.routemappings, - org.cloudfoundry.client.v2.routes, - org.cloudfoundry.client.v2.securitygroups, - org.cloudfoundry.client.v2.servicebindings, - org.cloudfoundry.client.v2.servicebrokers, - org.cloudfoundry.client.v2.serviceinstances, - org.cloudfoundry.client.v2.servicekeys, - org.cloudfoundry.client.v2.serviceplans, - org.cloudfoundry.client.v2.serviceplanvisibilities, - org.cloudfoundry.client.v2.services, - org.cloudfoundry.client.v2.serviceusageevents, - org.cloudfoundry.client.v2.shareddomains, - org.cloudfoundry.client.v2.spacequotadefinitions, - org.cloudfoundry.client.v2.spaces, - org.cloudfoundry.client.v2.stacks, - org.cloudfoundry.client.v2.userprovidedserviceinstances, - org.cloudfoundry.client.v2.users, - org.cloudfoundry.client.v3, - org.cloudfoundry.client.v3.applications, - org.cloudfoundry.client.v3.builds, - org.cloudfoundry.client.v3.deployments, - org.cloudfoundry.client.v3.droplets, - org.cloudfoundry.client.v3.isolationsegments, - org.cloudfoundry.client.v3.jobs, - org.cloudfoundry.client.v3.organizations, - org.cloudfoundry.client.v3.packages, - org.cloudfoundry.client.v3.processes, - org.cloudfoundry.client.v3.serviceInstances, - org.cloudfoundry.client.v3.servicebindings, - org.cloudfoundry.client.v3.spaces, - org.cloudfoundry.client.v3.tasks, - org.cloudfoundry.doppler, - org.cloudfoundry.dropsonde.events, - org.cloudfoundry.networking, - org.cloudfoundry.networking.v1.policies, - org.cloudfoundry.networking.v1.tags, - org.cloudfoundry.operations, - org.cloudfoundry.operations.advanced, - org.cloudfoundry.operations.applications, - org.cloudfoundry.operations.buildpacks, - org.cloudfoundry.operations.domains, - org.cloudfoundry.operations.networkpolicies, - org.cloudfoundry.operations.organizationadmin, - org.cloudfoundry.operations.organizations, - org.cloudfoundry.operations.routes, - org.cloudfoundry.operations.serviceadmin, - org.cloudfoundry.operations.services, - org.cloudfoundry.operations.spaceadmin, - org.cloudfoundry.operations.spaces, - org.cloudfoundry.operations.stacks, - org.cloudfoundry.operations.useradmin, - org.cloudfoundry.operations.util, - org.cloudfoundry.reactor, - org.cloudfoundry.reactor.client, - org.cloudfoundry.reactor.client.v2, - org.cloudfoundry.reactor.client.v2.applications, - org.cloudfoundry.reactor.client.v2.applicationusageevents, - org.cloudfoundry.reactor.client.v2.blobstores, - org.cloudfoundry.reactor.client.v2.buildpacks, - org.cloudfoundry.reactor.client.v2.domains, - org.cloudfoundry.reactor.client.v2.environmentvariablegroups, - org.cloudfoundry.reactor.client.v2.events, - org.cloudfoundry.reactor.client.v2.featureflags, - org.cloudfoundry.reactor.client.v2.info, - org.cloudfoundry.reactor.client.v2.jobs, - org.cloudfoundry.reactor.client.v2.organizationquotadefinitions, - org.cloudfoundry.reactor.client.v2.organizations, - org.cloudfoundry.reactor.client.v2.privatedomains, - org.cloudfoundry.reactor.client.v2.resourcematch, - org.cloudfoundry.reactor.client.v2.routemappings, - org.cloudfoundry.reactor.client.v2.routes, - org.cloudfoundry.reactor.client.v2.securitygroups, - org.cloudfoundry.reactor.client.v2.servicebindings, - org.cloudfoundry.reactor.client.v2.servicebrokers, - org.cloudfoundry.reactor.client.v2.serviceinstances, - org.cloudfoundry.reactor.client.v2.servicekeys, - org.cloudfoundry.reactor.client.v2.serviceplans, - org.cloudfoundry.reactor.client.v2.serviceplanvisibilities, - org.cloudfoundry.reactor.client.v2.services, - org.cloudfoundry.reactor.client.v2.serviceusageevents, - org.cloudfoundry.reactor.client.v2.shareddomains, - org.cloudfoundry.reactor.client.v2.spacequotadefinitions, - org.cloudfoundry.reactor.client.v2.spaces, - org.cloudfoundry.reactor.client.v2.stacks, - org.cloudfoundry.reactor.client.v2.userprovidedserviceinstances, - org.cloudfoundry.reactor.client.v2.users, - org.cloudfoundry.reactor.client.v3, - org.cloudfoundry.reactor.client.v3.applications, - org.cloudfoundry.reactor.client.v3.builds, - org.cloudfoundry.reactor.client.v3.deployments, - org.cloudfoundry.reactor.client.v3.droplets, - org.cloudfoundry.reactor.client.v3.isolationsegments, - org.cloudfoundry.reactor.client.v3.jobs, - org.cloudfoundry.reactor.client.v3.organizations, - org.cloudfoundry.reactor.client.v3.packages, - org.cloudfoundry.reactor.client.v3.processes, - org.cloudfoundry.reactor.client.v3.servicebindings, - org.cloudfoundry.reactor.client.v3.serviceinstances, - org.cloudfoundry.reactor.client.v3.spaces, - org.cloudfoundry.reactor.client.v3.tasks, - org.cloudfoundry.reactor.doppler, - org.cloudfoundry.reactor.networking, - org.cloudfoundry.reactor.networking.v1.policies, - org.cloudfoundry.reactor.networking.v1.tags, - org.cloudfoundry.reactor.routing, - org.cloudfoundry.reactor.routing.v1, - org.cloudfoundry.reactor.routing.v1.routergroups, - org.cloudfoundry.reactor.routing.v1.tcproutes, - org.cloudfoundry.reactor.tokenprovider, - org.cloudfoundry.reactor.uaa, - org.cloudfoundry.reactor.uaa.authorizations, - org.cloudfoundry.reactor.uaa.clients, - org.cloudfoundry.reactor.uaa.groups, - org.cloudfoundry.reactor.uaa.identityproviders, - org.cloudfoundry.reactor.uaa.identityzones, - org.cloudfoundry.reactor.uaa.serverinformation, - org.cloudfoundry.reactor.uaa.tokens, - org.cloudfoundry.reactor.uaa.users, - org.cloudfoundry.reactor.util, - org.cloudfoundry.routing, - org.cloudfoundry.routing.v1, - org.cloudfoundry.routing.v1.routergroups, - org.cloudfoundry.routing.v1.tcproutes, - org.cloudfoundry.uaa, - org.cloudfoundry.uaa.authorizations, - org.cloudfoundry.uaa.clients, - org.cloudfoundry.uaa.groups, - org.cloudfoundry.uaa.identityproviders, - org.cloudfoundry.uaa.identityzones, - org.cloudfoundry.uaa.serverinformation, - org.cloudfoundry.uaa.tokens, - org.cloudfoundry.uaa.users, - org.cloudfoundry.util, - org.cloudfoundry.util.tuple -Automatic-Module-Name: org.springsource.ide.eclipse.commons.cloudfoundry.client.v2 -Import-Package: javax.xml.bind diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/build.properties b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/build.properties deleted file mode 100644 index 80919f8cd..000000000 --- a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/build.properties +++ /dev/null @@ -1,39 +0,0 @@ -output.. = bin/ -bin.includes = META-INF/,\ - embedded-libs.properties,\ - plugin.properties,\ - dependencies/cloudfoundry-client-4.3.0.RELEASE.jar,\ - dependencies/cloudfoundry-client-reactor-4.3.0.RELEASE.jar,\ - dependencies/cloudfoundry-operations-4.3.0.RELEASE.jar,\ - dependencies/cloudfoundry-util-4.3.0.RELEASE.jar,\ - dependencies/commons-compress-1.19.jar,\ - dependencies/evo-inflector-1.2.2.jar,\ - dependencies/jackson-annotations-2.10.1.jar,\ - dependencies/jackson-core-2.10.1.jar,\ - dependencies/jackson-databind-2.10.1.jar,\ - dependencies/jackson-datatype-jdk8-2.10.1.jar,\ - dependencies/java-semver-0.9.0.jar,\ - dependencies/jcl-over-slf4j-1.7.29.jar,\ - dependencies/jjwt-0.9.1.jar,\ - dependencies/netty-buffer-4.1.43.Final.jar,\ - dependencies/netty-codec-4.1.43.Final.jar,\ - dependencies/netty-codec-http-4.1.43.Final.jar,\ - dependencies/netty-codec-http2-4.1.43.Final.jar,\ - dependencies/netty-codec-socks-4.1.43.Final.jar,\ - dependencies/netty-common-4.1.43.Final.jar,\ - dependencies/netty-handler-4.1.43.Final.jar,\ - dependencies/netty-handler-proxy-4.1.43.Final.jar,\ - dependencies/netty-resolver-4.1.43.Final.jar,\ - dependencies/netty-transport-4.1.43.Final.jar,\ - dependencies/netty-transport-native-epoll-4.1.43.Final-linux-x86_64.jar,\ - dependencies/netty-transport-native-unix-common-4.1.43.Final.jar,\ - dependencies/okio-1.8.0.jar,\ - dependencies/reactor-netty-0.9.2.RELEASE.jar,\ - dependencies/slf4j-api-1.7.29.jar,\ - dependencies/slf4j-simple-1.7.16.jar,\ - dependencies/snakeyaml-1.25.jar,\ - dependencies/spring-core-5.2.2.RELEASE.jar,\ - dependencies/spring-jcl-5.2.2.RELEASE.jar,\ - dependencies/spring-web-5.2.2.RELEASE.jar,\ - dependencies/wire-runtime-2.2.0.jar -src.includes = sources/ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-client-4.3.0.RELEASE.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-client-4.3.0.RELEASE.jar deleted file mode 100644 index 85383854e..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-client-4.3.0.RELEASE.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-client-reactor-4.3.0.RELEASE.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-client-reactor-4.3.0.RELEASE.jar deleted file mode 100644 index 18c71d4ec..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-client-reactor-4.3.0.RELEASE.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-operations-4.3.0.RELEASE.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-operations-4.3.0.RELEASE.jar deleted file mode 100644 index d3c61385f..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-operations-4.3.0.RELEASE.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-util-4.3.0.RELEASE.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-util-4.3.0.RELEASE.jar deleted file mode 100644 index bea79b7b4..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/cloudfoundry-util-4.3.0.RELEASE.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/commons-compress-1.19.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/commons-compress-1.19.jar deleted file mode 100644 index 5c9f52a29..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/commons-compress-1.19.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/evo-inflector-1.2.2.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/evo-inflector-1.2.2.jar deleted file mode 100644 index 1019ae3e7..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/evo-inflector-1.2.2.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-annotations-2.10.1.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-annotations-2.10.1.jar deleted file mode 100644 index a10399ce3..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-annotations-2.10.1.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-core-2.10.1.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-core-2.10.1.jar deleted file mode 100644 index 1640a4e08..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-core-2.10.1.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-databind-2.10.1.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-databind-2.10.1.jar deleted file mode 100644 index abe3748db..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-databind-2.10.1.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-datatype-jdk8-2.10.1.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-datatype-jdk8-2.10.1.jar deleted file mode 100644 index fc00dc967..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jackson-datatype-jdk8-2.10.1.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/java-semver-0.9.0.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/java-semver-0.9.0.jar deleted file mode 100644 index 842d290ca..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/java-semver-0.9.0.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jcl-over-slf4j-1.7.29.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jcl-over-slf4j-1.7.29.jar deleted file mode 100644 index d84213a1b..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jcl-over-slf4j-1.7.29.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jjwt-0.9.1.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jjwt-0.9.1.jar deleted file mode 100644 index 905c80e9f..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/jjwt-0.9.1.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-buffer-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-buffer-4.1.43.Final.jar deleted file mode 100644 index bf9a298bf..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-buffer-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-4.1.43.Final.jar deleted file mode 100644 index bafba25e6..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-http-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-http-4.1.43.Final.jar deleted file mode 100644 index fbb830ab1..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-http-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-http2-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-http2-4.1.43.Final.jar deleted file mode 100644 index dd0d465b7..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-http2-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-socks-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-socks-4.1.43.Final.jar deleted file mode 100644 index 4f5a1bd48..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-codec-socks-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-common-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-common-4.1.43.Final.jar deleted file mode 100644 index 3bad97e5e..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-common-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-handler-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-handler-4.1.43.Final.jar deleted file mode 100644 index 7a2cac19f..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-handler-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-handler-proxy-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-handler-proxy-4.1.43.Final.jar deleted file mode 100644 index 8b28a52c4..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-handler-proxy-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-resolver-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-resolver-4.1.43.Final.jar deleted file mode 100644 index 3a8ad38e7..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-resolver-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-transport-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-transport-4.1.43.Final.jar deleted file mode 100644 index 870e7c32c..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-transport-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-transport-native-epoll-4.1.43.Final-linux-x86_64.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-transport-native-epoll-4.1.43.Final-linux-x86_64.jar deleted file mode 100644 index 962e0d887..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-transport-native-epoll-4.1.43.Final-linux-x86_64.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-transport-native-unix-common-4.1.43.Final.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-transport-native-unix-common-4.1.43.Final.jar deleted file mode 100644 index 91de52f77..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/netty-transport-native-unix-common-4.1.43.Final.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/okio-1.8.0.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/okio-1.8.0.jar deleted file mode 100644 index bb70f758b..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/okio-1.8.0.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/reactor-netty-0.9.2.RELEASE.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/reactor-netty-0.9.2.RELEASE.jar deleted file mode 100644 index ade31277e..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/reactor-netty-0.9.2.RELEASE.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/slf4j-api-1.7.29.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/slf4j-api-1.7.29.jar deleted file mode 100644 index 81ed475d2..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/slf4j-api-1.7.29.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/slf4j-simple-1.7.16.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/slf4j-simple-1.7.16.jar deleted file mode 100644 index 4ac074e38..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/slf4j-simple-1.7.16.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/snakeyaml-1.25.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/snakeyaml-1.25.jar deleted file mode 100644 index 000498505..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/snakeyaml-1.25.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/spring-core-5.2.2.RELEASE.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/spring-core-5.2.2.RELEASE.jar deleted file mode 100644 index d32f78201..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/spring-core-5.2.2.RELEASE.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/spring-jcl-5.2.2.RELEASE.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/spring-jcl-5.2.2.RELEASE.jar deleted file mode 100644 index ea0f6150b..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/spring-jcl-5.2.2.RELEASE.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/spring-web-5.2.2.RELEASE.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/spring-web-5.2.2.RELEASE.jar deleted file mode 100644 index d950f29c9..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/spring-web-5.2.2.RELEASE.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/wire-runtime-2.2.0.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/wire-runtime-2.2.0.jar deleted file mode 100644 index 325a9ad89..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/dependencies/wire-runtime-2.2.0.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/embedded-libs.properties b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/embedded-libs.properties deleted file mode 100644 index 7821eb66c..000000000 --- a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/embedded-libs.properties +++ /dev/null @@ -1,98 +0,0 @@ -cloudfoundry-client-3.8.0.RELEASE.jar-name=cloudfoundry-java-client -cloudfoundry-client-3.8.0.RELEASE.jar-version=3.8.0 - -cloudfoundry-client-reactor-3.8.0.RELEASE.jar-name=cloudfoundry-java-client -cloudfoundry-client-reactor-3.8.0.RELEASE.jar-version=3.8.0 - -cloudfoundry-operations-3.8.0.RELEASE.jar-name=cloudfoundry-java-client -cloudfoundry-operations-3.8.0.RELEASE.jar-version=3.8.0 - -cloudfoundry-util-3.8.0.RELEASE.jar-name=cloudfoundry-java-client -cloudfoundry-util-3.8.0.RELEASE.jar-version=3.8.0 - -commons-compress-1.16.1.jar-name=commons-compress -commons-compress-1.16.1.jar-version=1.16.1 - -evo-inflector-1.2.2.jar-name=evo-inflector -evo-inflector-1.2.2.jar-version=1.2.2 - -jackson-annotations-2.8.0.jar-name=jackson-annotations -jackson-annotations-2.8.0.jar-version=2.8.0 - -jackson-core-2.8.10.jar-name=jackson-core -jackson-core-2.8.10.jar-version=2.8.10 - -jackson-databind-2.8.10.jar-name=jackson-databind -jackson-databind-2.8.10.jar-version=2.8.10 - -jackson-datatype-jdk8-2.8.10.jar-name=jackson-datatype-jdk8 -jackson-datatype-jdk8-2.8.10.jar-version=2.8.10 - -java-semver-0.9.0.jar-name=java-semver -java-semver-0.9.0.jar-version=0.9.0 - -jcl-over-slf4j-1.7.25.jar-name=jcl-over-slf4j -jcl-over-slf4j-1.7.25.jar-version=1.7.25 - -jjwt-0.9.0.jar-name=jjwt -jjwt-0.9.0.jar-version=0.9.0 - -netty-buffer-4.1.22.Final.jar-name=netty-buffer -netty-buffer-4.1.22.Final.jar-version=4.1.22.final - -netty-codec-4.1.22.Final.jar-name=netty-codec -netty-codec-4.1.22.Final.jar-version=4.1.22.final - -netty-codec-http-4.1.22.Final.jar-name=netty-codec-http -netty-codec-http-4.1.22.Final.jar-version=4.1.22.final - -netty-codec-socks-4.1.22.Final.jar-name=netty-codec-socks -netty-codec-socks-4.1.22.Final.jar-version=4.1.22.final - -netty-common-4.1.22.Final.jar-name=netty-common -netty-common-4.1.22.Final.jar-version=4.1.22.final - -netty-handler-4.1.22.Final.jar-name=netty-handler -netty-handler-4.1.22.Final.jar-version=4.1.22.final - -netty-handler-proxy-4.1.22.Final.jar-name=netty-handler-proxy -netty-handler-proxy-4.1.22.Final.jar-version=4.1.22.final - -netty-resolver-4.1.22.Final.jar-name=netty-resolver -netty-resolver-4.1.22.Final.jar-version=4.1.22.final - -netty-transport-4.1.22.Final.jar-name=netty-transport -netty-transport-4.1.22.Final.jar-version=4.1.22.final - -netty-transport-native-epoll-4.1.22.Final.jar-name=netty-transport-native-epoll -netty-transport-native-epoll-4.1.22.Final.jar-version=4.1.22.final - -netty-transport-native-unix-common-4.1.22.Final.jar-name=netty-transport-native-unix-common -netty-transport-native-unix-common-4.1.22.Final.jar-version=4.1.22.final - -objenesis-2.6.jar-name=objenesis -objenesis-2.6.jar-version=2.6 - -okio-1.8.0.jar-name=okio -okio-1.8.0.jar-version=1.8.0 - -reactor-netty-0.7.5.RELEASE.jar-name=reactor-netty -reactor-netty-0.7.5.RELEASE.jar-version=0.7.5 - -slf4j-api-1.7.25.jar-name=slf4j-api -slf4j-api-1.7.25.jar-version=1.7.25 - -slf4j-simple-1.7.16.jar-name=slf4j-simple -slf4j-simple-1.7.16.jar-version=1.7.16 - -snakeyaml-1.17.jar-name=snakeyaml -snakeyaml-1.17.jar-version=1.17 - -spring-core-4.3.14.RELEASE.jar-name=spring-core -spring-core-4.3.14.RELEASE.jar-version=4.3.14.release - -spring-web-4.3.14.RELEASE.jar-name=spring-web -spring-web-4.3.14.RELEASE.jar-version=4.3.14.release - -wire-runtime-2.2.0.jar-name=wire-runtime -wire-runtime-2.2.0.jar-version=2.2.0 diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/plugin.properties b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/plugin.properties deleted file mode 100644 index 766d19566..000000000 --- a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/plugin.properties +++ /dev/null @@ -1,2 +0,0 @@ -providerName = VMware, Inc. -pluginName = Cloud Foundry Java Client Lib v2 \ No newline at end of file diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/pom.xml b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/pom.xml deleted file mode 100644 index 9d3627782..000000000 --- a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - 4.0.0 - - - org.springframework.boot.ide - org.springframework.boot.ide - 4.18.0-SNAPSHOT - ../../eclipse-distribution/pom.xml - - - org.springframework.ide.eclipse - org.springsource.ide.eclipse.commons.cloudfoundry.client.v2 - eclipse-plugin - - - 1.8 - 1.8 - - - - - - - org.eclipse.tycho - target-platform-configuration - ${tycho-version} - - p2 - ignore - - - - - org.eclipse.tycho - tycho-compiler-plugin - ${tycho-version} - - - - org.eclipse.tycho - tycho-source-plugin - ${tycho-version} - - - plugin-source - generate-sources - - plugin-source - - - - - - - org.eclipse.tycho - tycho-p2-plugin - ${tycho-version} - - - second-generate-p2-metadata - - p2-metadata - - verify - - - - - - - - diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-client-4.3.0.RELEASE-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-client-4.3.0.RELEASE-sources.jar deleted file mode 100644 index d48960956..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-client-4.3.0.RELEASE-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-client-reactor-4.3.0.RELEASE-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-client-reactor-4.3.0.RELEASE-sources.jar deleted file mode 100644 index f2e4d6ffb..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-client-reactor-4.3.0.RELEASE-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-operations-4.3.0.RELEASE-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-operations-4.3.0.RELEASE-sources.jar deleted file mode 100644 index b4dd1589e..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-operations-4.3.0.RELEASE-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-util-4.3.0.RELEASE-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-util-4.3.0.RELEASE-sources.jar deleted file mode 100644 index dea326c25..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/cloudfoundry-util-4.3.0.RELEASE-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/commons-compress-1.19-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/commons-compress-1.19-sources.jar deleted file mode 100644 index cc6682215..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/commons-compress-1.19-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/evo-inflector-1.2.2-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/evo-inflector-1.2.2-sources.jar deleted file mode 100644 index f419db941..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/evo-inflector-1.2.2-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-annotations-2.10.1-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-annotations-2.10.1-sources.jar deleted file mode 100644 index 15bd5f4ff..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-annotations-2.10.1-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-core-2.10.1-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-core-2.10.1-sources.jar deleted file mode 100644 index e8c84e719..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-core-2.10.1-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-databind-2.10.1-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-databind-2.10.1-sources.jar deleted file mode 100644 index 15d35c305..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-databind-2.10.1-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-datatype-jdk8-2.10.1-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-datatype-jdk8-2.10.1-sources.jar deleted file mode 100644 index c794d4528..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jackson-datatype-jdk8-2.10.1-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/java-semver-0.9.0-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/java-semver-0.9.0-sources.jar deleted file mode 100644 index 963e5f175..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/java-semver-0.9.0-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jcl-over-slf4j-1.7.29-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jcl-over-slf4j-1.7.29-sources.jar deleted file mode 100644 index 5d1ba9a20..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jcl-over-slf4j-1.7.29-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jjwt-0.9.1-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jjwt-0.9.1-sources.jar deleted file mode 100644 index 25a2fafb6..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/jjwt-0.9.1-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-buffer-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-buffer-4.1.43.Final-sources.jar deleted file mode 100644 index 2a28da7f7..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-buffer-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-4.1.43.Final-sources.jar deleted file mode 100644 index 3fc3af3c4..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-http-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-http-4.1.43.Final-sources.jar deleted file mode 100644 index 98591a12f..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-http-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-http2-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-http2-4.1.43.Final-sources.jar deleted file mode 100644 index 49b67a555..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-http2-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-socks-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-socks-4.1.43.Final-sources.jar deleted file mode 100644 index 1eebd6a3c..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-codec-socks-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-common-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-common-4.1.43.Final-sources.jar deleted file mode 100644 index a5d52f71b..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-common-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-handler-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-handler-4.1.43.Final-sources.jar deleted file mode 100644 index a915ffeee..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-handler-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-handler-proxy-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-handler-proxy-4.1.43.Final-sources.jar deleted file mode 100644 index 789f86460..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-handler-proxy-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-resolver-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-resolver-4.1.43.Final-sources.jar deleted file mode 100644 index b2ab5143e..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-resolver-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-transport-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-transport-4.1.43.Final-sources.jar deleted file mode 100644 index bb7c2e913..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-transport-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-transport-native-epoll-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-transport-native-epoll-4.1.43.Final-sources.jar deleted file mode 100644 index 3a2e19175..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-transport-native-epoll-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-transport-native-unix-common-4.1.43.Final-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-transport-native-unix-common-4.1.43.Final-sources.jar deleted file mode 100644 index 3637dc1fc..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/netty-transport-native-unix-common-4.1.43.Final-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/okio-1.8.0-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/okio-1.8.0-sources.jar deleted file mode 100644 index a6e320c18..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/okio-1.8.0-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/reactor-netty-0.9.2.RELEASE-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/reactor-netty-0.9.2.RELEASE-sources.jar deleted file mode 100644 index 20dbe7178..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/reactor-netty-0.9.2.RELEASE-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/slf4j-api-1.7.29-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/slf4j-api-1.7.29-sources.jar deleted file mode 100644 index e4f4d4350..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/slf4j-api-1.7.29-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/slf4j-simple-1.7.16-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/slf4j-simple-1.7.16-sources.jar deleted file mode 100644 index 48ec9eb34..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/slf4j-simple-1.7.16-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/snakeyaml-1.25-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/snakeyaml-1.25-sources.jar deleted file mode 100644 index 143fbd606..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/snakeyaml-1.25-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/spring-core-5.2.2.RELEASE-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/spring-core-5.2.2.RELEASE-sources.jar deleted file mode 100644 index 5cbaeeb8c..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/spring-core-5.2.2.RELEASE-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/spring-jcl-5.2.2.RELEASE-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/spring-jcl-5.2.2.RELEASE-sources.jar deleted file mode 100644 index 0f407b31f..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/spring-jcl-5.2.2.RELEASE-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/spring-web-5.2.2.RELEASE-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/spring-web-5.2.2.RELEASE-sources.jar deleted file mode 100644 index ee09b4f6e..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/spring-web-5.2.2.RELEASE-sources.jar and /dev/null differ diff --git a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/wire-runtime-2.2.0-sources.jar b/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/wire-runtime-2.2.0-sources.jar deleted file mode 100644 index 032f1bab4..000000000 Binary files a/eclipse-extensions/org.springsource.ide.eclipse.commons.cloudfoundry.client.v2/sources/wire-runtime-2.2.0-sources.jar and /dev/null differ