26
vscode-extensions/commons/commons-cf/.classpath
Normal file
26
vscode-extensions/commons/commons-cf/.classpath
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
29
vscode-extensions/commons/commons-cf/.project
Normal file
29
vscode-extensions/commons/commons-cf/.project
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>commons-cf</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.core.springbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.springframework.ide.eclipse.core.springnature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
@@ -0,0 +1,4 @@
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
||||
42
vscode-extensions/commons/commons-cf/pom.xml
Normal file
42
vscode-extensions/commons/commons-cf/pom.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>commons-cf</artifactId>
|
||||
<name>commons-cf</name>
|
||||
<description>Common code related to 'accessing Cloud Foundry'</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-util</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cloudfoundry</groupId>
|
||||
<artifactId>cloudfoundry-client-reactor</artifactId>
|
||||
<version>${cloudfoundry-client-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cloudfoundry</groupId>
|
||||
<artifactId>cloudfoundry-operations</artifactId>
|
||||
<version>${cloudfoundry-client-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-core</artifactId>
|
||||
<version>${reactor-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor.ipc</groupId>
|
||||
<artifactId>reactor-netty</artifactId>
|
||||
<version>${reactor-netty}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public enum CFAppState {
|
||||
|
||||
STOPPED,
|
||||
STARTED,
|
||||
UNKNOWN
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.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<String> getServices();
|
||||
String getBuildpackUrl();
|
||||
List<String> getUris();
|
||||
CFAppState getState();
|
||||
int getDiskQuota();
|
||||
Integer getTimeout();
|
||||
String getCommand();
|
||||
String getStack();
|
||||
|
||||
Map<String,String> getEnvAsMap();
|
||||
String getHealthCheckType();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public interface CFApplicationArchive {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CFApplicationDetail extends CFApplication {
|
||||
List<CFInstanceStats> getInstanceDetails();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public interface CFBuildpack {
|
||||
String getName();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public interface CFCloudDomain {
|
||||
String getName();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public interface CFEntity {
|
||||
String getName();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
|
||||
/**
|
||||
* Static methods to recognize specific types of exceptions CF client
|
||||
* may throw.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class CFExceptions {
|
||||
|
||||
public static boolean isSSLCertificateFailure(Exception e) {
|
||||
Throwable cause = ExceptionUtil.getDeepestCause(e);
|
||||
return cause.getClass().getName().equals("sun.security.provider.certpath.SunCertPathBuilderException");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public enum CFInstanceState {
|
||||
RUNNING, CRASHED, FLAPPING, STARTING, DOWN, UNKNOWN
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public interface CFInstanceStats {
|
||||
|
||||
CFInstanceState getState();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface CFOrganization extends CFEntity {
|
||||
UUID getGuid();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public interface CFServiceInstance extends CFEntity {
|
||||
|
||||
String getName();
|
||||
String getService();
|
||||
String getPlan();
|
||||
String getDescription();
|
||||
String getDocumentationUrl();
|
||||
String getDashboardUrl();
|
||||
|
||||
//TODO: last operation info?
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface CFSpace extends CFEntity {
|
||||
CFOrganization getOrganization();
|
||||
UUID getGuid();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public interface CFStack extends CFEntity {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public class HealthChecks {
|
||||
|
||||
public static final String HC_NONE = "none";
|
||||
public static final String HC_PORT = "port";
|
||||
public static final String[] HC_ALL = {HC_NONE, HC_PORT};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
public enum LoginMethod {
|
||||
PASSWORD,
|
||||
TEMPORARY_CODE;
|
||||
|
||||
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(pieces[i].toLowerCase());
|
||||
}
|
||||
return label.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal Software, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal Software, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.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$
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.target;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFCredentials.CFCredentialType;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
|
||||
/**
|
||||
* All the parameters needed to create a CF client.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class CFClientParams {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(CFClientParams.class.getName());
|
||||
|
||||
private final String apiUrl;
|
||||
private final String username;
|
||||
private CFCredentials credentials;
|
||||
private final boolean skipSslValidation;
|
||||
|
||||
private String orgName; // optional
|
||||
private String spaceName; //optional
|
||||
|
||||
public CFClientParams(String apiUrl,
|
||||
String username,
|
||||
CFCredentials credentials,
|
||||
String orgName,
|
||||
String spaceName,
|
||||
boolean skipSslValidation
|
||||
) {
|
||||
Assert.isNotNull(apiUrl);
|
||||
Assert.isNotNull(credentials);
|
||||
if (credentials.getType()==CFCredentialType.PASSWORD) {
|
||||
Assert.isNotNull(username);
|
||||
}
|
||||
this.apiUrl = apiUrl;
|
||||
this.username = username;
|
||||
this.credentials = credentials;
|
||||
this.skipSslValidation = skipSslValidation;
|
||||
this.orgName = orgName;
|
||||
this.spaceName = spaceName;
|
||||
}
|
||||
|
||||
public CFCredentials getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
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) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), 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 + ((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 (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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CFClientParams [apiUrl=" + apiUrl + ", username=" + username + ", credentials=" + credentials
|
||||
+ ", skipSslValidation=" + skipSslValidation + ", orgName=" + orgName + ", spaceName=" + spaceName
|
||||
+ "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
/**
|
||||
* Resolves Cloud Foundry client parameters from registered params providers
|
||||
*
|
||||
*/
|
||||
public class CFClientParamsFactory {
|
||||
|
||||
public static final CFClientParamsFactory INSTANCE = new CFClientParamsFactory();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Provider<List<CFClientParams>>> providers = new ArrayList<>();
|
||||
|
||||
private CFClientParamsFactory() {
|
||||
// Singleton
|
||||
addProvider(new CfCliParamsProvider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds provider to the front of the registered providers such that it would
|
||||
* be called first when a request is made for CF client params
|
||||
*
|
||||
* @param provider
|
||||
*/
|
||||
public void addProvider(Provider<List<CFClientParams>> provider) {
|
||||
if (provider != null) {
|
||||
providers.add(provider);
|
||||
}
|
||||
}
|
||||
|
||||
public List<CFClientParams> getParams() {
|
||||
|
||||
// Start from the last provider, which is the highest priority
|
||||
for (int i = providers.size() - 1; i >= 0; i--) {
|
||||
List<CFClientParams> params = providers.get(i).get();
|
||||
if (params != null && !params.isEmpty()) {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.target;
|
||||
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.LoginMethod;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.target;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.ExternalCommand;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalProcess;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Provides existing Cloud Foundry client params, like target and credentials,
|
||||
* from the CLI config.json in the file system.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class CfCliParamsProvider implements Provider<List<CFClientParams>> {
|
||||
|
||||
public static final String TARGET = "Target";
|
||||
public static final String REFRESH_TOKEN = "RefreshToken";
|
||||
public static final String ORGANIZATION_FIELDS = "OrganizationFields";
|
||||
public static final String SPACE_FIELDS = "SpaceFields";
|
||||
public static final String NAME = "Name";
|
||||
public static final String SSL_DISABLED = "SSLDisabled";
|
||||
|
||||
private static Logger logger = Logger.getLogger(CfCliParamsProvider.class.getName());
|
||||
|
||||
@Override
|
||||
public List<CFClientParams> get() {
|
||||
try {
|
||||
File file = getConfigJsonFile();
|
||||
if (file != null) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
Map<String, Object> userData = mapper.readValue(file, Map.class);
|
||||
if (userData != null) {
|
||||
String refreshToken = (String) userData.get(REFRESH_TOKEN);
|
||||
if (refreshToken == null) {
|
||||
return null;
|
||||
}
|
||||
CFCredentials credentials = CFCredentials.fromRefreshToken(refreshToken);
|
||||
boolean sslDisabled = (Boolean) userData.get(SSL_DISABLED);
|
||||
String target = (String) userData.get(TARGET);
|
||||
Map<String, Object> orgFields = (Map<String, Object>) userData.get(ORGANIZATION_FIELDS);
|
||||
Map<String, Object> spaceFields = (Map<String, Object>) userData.get(SPACE_FIELDS);
|
||||
if (target != null && orgFields != null && spaceFields != null) {
|
||||
String orgName = (String) orgFields.get(NAME);
|
||||
String spaceName = (String) spaceFields.get(NAME);
|
||||
List<CFClientParams> params = new ArrayList<>();
|
||||
params.add(new CFClientParams(target, null, credentials, orgName, spaceName, sslDisabled));
|
||||
return params;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
log(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private File getConfigJsonFile() throws IOException, InterruptedException {
|
||||
if (!System.getProperty("os.name").toLowerCase().startsWith("win")) {
|
||||
String homeDir = getUnixHomeDir();
|
||||
if (homeDir != null) {
|
||||
if (!homeDir.endsWith("/")) {
|
||||
homeDir += '/';
|
||||
}
|
||||
String filePath = homeDir + ".cf/config.json";
|
||||
File file = new File(filePath);
|
||||
if (file.exists() && file.canRead()) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getUnixHomeDir() throws IOException, InterruptedException {
|
||||
File currentWorkDir = null; /*
|
||||
* use current working dir which means pass
|
||||
* null
|
||||
*/
|
||||
ExternalProcess homeDirProcess = new ExternalProcess(currentWorkDir,
|
||||
new ExternalCommand("/bin/bash", "-c", "echo $HOME"), true);
|
||||
String homeDir = homeDirProcess.getOut();
|
||||
if (homeDir != null) {
|
||||
homeDir = homeDir.trim(); // remove any new line chars
|
||||
}
|
||||
return homeDir;
|
||||
}
|
||||
|
||||
private void log(Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.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<Map<String,String>> getEnv();
|
||||
Mono<List<String>> getServices();
|
||||
Mono<String> getBuildpack();
|
||||
Mono<String> getStack();
|
||||
Mono<Integer> getTimeout();
|
||||
Mono<String> getCommand();
|
||||
Mono<String> getHealthCheckType();
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFApplicationDetail;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFInstanceStats;
|
||||
|
||||
public class CFApplicationDetailData extends CFApplicationSummaryData implements CFApplicationDetail {
|
||||
|
||||
private List<CFInstanceStats> instanceDetails;
|
||||
|
||||
public CFApplicationDetailData(
|
||||
CFApplicationSummaryData app,
|
||||
List<CFInstanceStats> 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<CFInstanceStats> 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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFAppState;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFApplication;
|
||||
|
||||
public class CFApplicationSummaryData implements CFApplication {
|
||||
|
||||
private String name;
|
||||
private int instances;
|
||||
private int runningInstances;
|
||||
private int memory;
|
||||
private UUID guid;
|
||||
private List<String> uris;
|
||||
private CFAppState state;
|
||||
private int diskQuota;
|
||||
protected ApplicationExtras extras;
|
||||
|
||||
public CFApplicationSummaryData(
|
||||
String name,
|
||||
int instances,
|
||||
int runningInstances,
|
||||
int memory,
|
||||
UUID guid,
|
||||
List<String> 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<String> getServices() {
|
||||
return extras.getServices().block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBuildpackUrl() {
|
||||
return extras.getBuildpack().block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUris() {
|
||||
return uris;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CFAppState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDiskQuota() {
|
||||
return diskQuota;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getTimeout() {
|
||||
return extras.getTimeout().block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHealthCheckType() {
|
||||
return extras.getHealthCheckType().block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommand() {
|
||||
return extras.getCommand().block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStack() {
|
||||
return extras.getStack().block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getEnvAsMap() {
|
||||
return extras.getEnv().block();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.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.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
|
||||
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<String> 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<String, String> env = ImmutableMap.of();
|
||||
private Integer instances;
|
||||
private List<String> services = ImmutableList.of();
|
||||
private ZipFile applicationData;
|
||||
private boolean noStart = false;
|
||||
|
||||
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<String, String> getEnv() {
|
||||
return env;
|
||||
}
|
||||
public void setEnv(Map<String, String> env) {
|
||||
this.env = env;
|
||||
}
|
||||
public Integer getInstances() {
|
||||
return instances;
|
||||
}
|
||||
public void setInstances(Integer instances) {
|
||||
this.instances = instances;
|
||||
}
|
||||
public List<String> getServices() {
|
||||
return services;
|
||||
}
|
||||
public void setServices(List<String> services) {
|
||||
this.services = services;
|
||||
}
|
||||
public ZipFile getApplicationData() {
|
||||
return applicationData;
|
||||
}
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
if (applicationData!=null) {
|
||||
applicationData.close();
|
||||
}
|
||||
}
|
||||
public void setApplicationData(File archive) throws Exception {
|
||||
if (applicationData==null) {
|
||||
ExceptionUtil.exception("Can only set this once", null);
|
||||
}
|
||||
this.applicationData = new ZipFile(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<String> getRoutes() {
|
||||
return routes;
|
||||
}
|
||||
public void setRoutes(Collection<String> 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+" ]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
import org.cloudfoundry.operations.routes.Route;
|
||||
|
||||
public class CFRoute {
|
||||
|
||||
final private String domain;
|
||||
final private String host;
|
||||
final private String path;
|
||||
|
||||
public CFRoute(Route route) {
|
||||
this.domain = route.getDomain();
|
||||
this.host = route.getHost();
|
||||
this.path = route.getPath();
|
||||
}
|
||||
|
||||
public CFRoute(String domain, String host, String path) {
|
||||
super();
|
||||
this.domain = domain;
|
||||
this.host = host;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CFRoute [domain=" + domain + ", host=" + host + ", path=" + path + "]";
|
||||
}
|
||||
|
||||
public static CFRoute.Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
public static class Builder {
|
||||
private String domain;
|
||||
private String host;
|
||||
private String path = "";
|
||||
|
||||
public CFRoute build() {
|
||||
return new CFRoute(this.domain, this.host, this.path);
|
||||
}
|
||||
|
||||
public Builder domain(String domain) {
|
||||
this.domain = domain;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder host(String host) {
|
||||
this.host = host;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.cloudfoundry.client.v2.buildpacks.BuildpackResource;
|
||||
import org.cloudfoundry.client.v2.domains.DomainResource;
|
||||
import org.cloudfoundry.operations.applications.ApplicationDetail;
|
||||
import org.cloudfoundry.operations.applications.ApplicationSummary;
|
||||
import org.cloudfoundry.operations.applications.InstanceDetail;
|
||||
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.vscode.commons.cloudfoundry.client.CFAppState;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFApplication;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFApplicationDetail;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFBuildpack;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFCloudDomain;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFInstanceState;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFInstanceStats;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFOrganization;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFServiceInstance;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFSpace;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFStack;
|
||||
|
||||
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 {
|
||||
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DefaultClientRequestsV2.class.getName());
|
||||
|
||||
|
||||
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<CFInstanceStats> 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<CFInstanceStats> instanceDetails = ImmutableList.copyOf(
|
||||
details
|
||||
.getInstanceDetails()
|
||||
.stream()
|
||||
.map(CFWrappingV2::wrap)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
return new CFApplicationDetailData(summary, instanceDetails);
|
||||
}
|
||||
|
||||
public static CFCloudDomain wrap(DomainResource domainRsrc) {
|
||||
if (domainRsrc!=null) {
|
||||
String name = domainRsrc.getEntity().getName();
|
||||
return new CFCloudDomain() {
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CFCloudDomain("+name+")";
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static CFInstanceStats wrap(InstanceDetail instanceDetail) {
|
||||
return new CFInstanceStats() {
|
||||
@Override
|
||||
public CFInstanceState getState() {
|
||||
try {
|
||||
return CFInstanceState.valueOf(instanceDetail.getState());
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), 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) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), 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) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), 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) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
/**
|
||||
* Manages a set of CancelationTokens.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class CancelationTokens {
|
||||
|
||||
private String DEBUG = null;
|
||||
|
||||
//Note: we don't actually have to keep a set of tokens explicitly.
|
||||
// The tokens use a 'id' which is incremented on each new token.
|
||||
//So it is easy to cancel all existing tokens based on a their
|
||||
//id simply by remembering the 'id' where the cancelation
|
||||
//occurred. All ids 'older' than the current id are 'canceled'.
|
||||
|
||||
/**
|
||||
* An uncancelable token that can be used by operations that don't
|
||||
* need cancelation support.
|
||||
*/
|
||||
public static final CancelationToken NULL = new CancelationToken() {
|
||||
@Override
|
||||
public boolean isCanceled() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private final Object SYNC = CancelationTokens.this;
|
||||
|
||||
private int canceledAllBefore = 0;
|
||||
private int nextId = 0;
|
||||
|
||||
public CancelationTokens() {
|
||||
}
|
||||
|
||||
public CancelationTokens(String debug) {
|
||||
this.DEBUG = debug;
|
||||
}
|
||||
|
||||
public interface CancelationToken {
|
||||
boolean isCanceled();
|
||||
}
|
||||
|
||||
public synchronized CancelationToken create() {
|
||||
CancelationToken token = new ManagedToken();
|
||||
debug("creating cancelation token: "+token);
|
||||
return token;
|
||||
}
|
||||
|
||||
private class ManagedToken implements CancelationToken {
|
||||
private int id;
|
||||
|
||||
private ManagedToken() {
|
||||
synchronized (SYNC) {
|
||||
this.id = nextId++;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCanceled() {
|
||||
synchronized (SYNC) {
|
||||
boolean isCanceled = id < canceledAllBefore;
|
||||
debug("isCanceled? ["+id+"] => "+isCanceled);
|
||||
return isCanceled;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CancelToken("+id+")";
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void cancelAll() {
|
||||
canceledAllBefore = nextId;
|
||||
debug("CancelationTokens < "+canceledAllBefore+" are Canceled");
|
||||
}
|
||||
|
||||
private void debug(String string) {
|
||||
if (DEBUG!=null) {
|
||||
System.out.println(DEBUG+": "+string);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015, 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFApplication;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFApplicationDetail;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFBuildpack;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFCloudDomain;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFServiceInstance;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFSpace;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFStack;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.SshClientSupport;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.CancelationTokens.CancelationToken;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface ClientRequests {
|
||||
|
||||
// /**
|
||||
// * The actual Rest API version that cloud controller claims to be.
|
||||
// */
|
||||
// Version getApiVersion();
|
||||
//
|
||||
// /**
|
||||
// * 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;
|
||||
void logout();
|
||||
|
||||
List<CFApplication> getApplicationsWithBasicInfo() throws Exception;
|
||||
List<CFBuildpack> getBuildpacks() throws Exception;
|
||||
List<CFCloudDomain> getDomains() throws Exception;
|
||||
List<CFServiceInstance> getServices() throws Exception;
|
||||
List<CFSpace> getSpaces() throws Exception;
|
||||
List<CFStack> getStacks() throws Exception;
|
||||
void restartApplication(String appName, CancelationToken token) throws Exception;
|
||||
void stopApplication(String appName) throws Exception;
|
||||
Flux<CFApplicationDetail> getApplicationDetails(List<CFApplication> appsToLookUp) throws Exception;
|
||||
String getHealthCheck(UUID appGuid) throws Exception;
|
||||
void setHealthCheck(UUID guid, String hcType) throws Exception;
|
||||
boolean applicationExists(String appName) throws Exception;
|
||||
|
||||
//Removed in V2
|
||||
//void createApplication(CloudApplicationDeploymentProperties deploymentProperties) throws Exception;
|
||||
|
||||
//Added since v2:
|
||||
void push(CFPushArguments args, CancelationToken cancelationToken) throws Exception;
|
||||
Map<String, String> getApplicationEnvironment(String appName) throws Exception;
|
||||
Mono<Void> 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<String> getUserName();
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cloudfoundry.client.CloudFoundryClient;
|
||||
import org.cloudfoundry.reactor.ConnectionContext;
|
||||
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.springframework.ide.vscode.commons.cloudfoundry.client.target.CFCredentials;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <p>
|
||||
* So we have a permanent cache of clients here that is reused.
|
||||
* <p>
|
||||
* 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 ConnectionContext 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;
|
||||
|
||||
private ProxyConfiguration getProxy(String host) {
|
||||
// TODO: enable proxy support for vscode. The code below retrieves proxy via Eclipse proxy service thus
|
||||
// not applicable when this is used outside of Eclipse
|
||||
// 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<Boolean> 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();
|
||||
}
|
||||
|
||||
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<Boolean> 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<Params, CFClientProvider> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientParams;
|
||||
|
||||
public interface CloudFoundryClientFactory {
|
||||
|
||||
ClientRequests getClient(CFClientParams params) throws Exception;
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,33 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientParams;
|
||||
|
||||
public class DefaultCloudFoundryClientFactoryV2 implements CloudFoundryClientFactory {
|
||||
|
||||
public static final CloudFoundryClientFactory INSTANCE = new DefaultCloudFoundryClientFactoryV2();
|
||||
|
||||
/**
|
||||
* Use 'INSTANCE' constant instead. This class is a singleton.
|
||||
*/
|
||||
private DefaultCloudFoundryClientFactoryV2() {}
|
||||
|
||||
private CloudFoundryClientCache cache = new CloudFoundryClientCache();
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ide.vscode.commons.cloudfoundry.client.v2.CloudFoundryClientFactory#getClient(org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientParams)
|
||||
*/
|
||||
@Override
|
||||
public ClientRequests getClient(CFClientParams params) throws Exception {
|
||||
return new DefaultClientRequestsV2(cache, params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Interface for Cloud Foundry application deployment properties
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public interface DeploymentProperties {
|
||||
|
||||
int DEFAULT_MEMORY = 1024;
|
||||
int DEFAULT_INSTANCES = 1;
|
||||
String DEFAULT_HEALTH_CHECK_TYPE = "port";
|
||||
|
||||
String getAppName();
|
||||
|
||||
int getMemory();
|
||||
|
||||
int getDiskQuota();
|
||||
|
||||
Integer getTimeout();
|
||||
|
||||
String getHealthCheckType();
|
||||
|
||||
String getBuildpack();
|
||||
|
||||
String getCommand();
|
||||
|
||||
String getStack();
|
||||
|
||||
Map<String, String> getEnvironmentVariables();
|
||||
|
||||
int getInstances();
|
||||
|
||||
List<String> getServices();
|
||||
|
||||
Set<String> getUris();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.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.reactivestreams.Publisher;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.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;
|
||||
|
||||
// TODO: uncommented when cancellation is handled in vscode
|
||||
// /**
|
||||
// * Convert a {@link CancelationToken} into a Mono that raises
|
||||
// * an {@link OperationCanceledException} when the token is canceled.
|
||||
// */
|
||||
// public static <T> Mono<T> toMono(CancelationToken cancelToken) {
|
||||
// return Mono.delay(Duration.ofSeconds(1))
|
||||
// .then((ping) ->
|
||||
// cancelToken.isCanceled()
|
||||
// ? Mono.<T>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.
|
||||
* <p>
|
||||
* 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> T get(Mono<T> 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.
|
||||
* <p>
|
||||
* 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> T get(Duration timeout, CancelationToken cancelationToken, Mono<T> mono) throws Exception {
|
||||
try {
|
||||
return mono
|
||||
// TODO: uncomment when cancellation properly supported in vscode
|
||||
// Mono
|
||||
// .first(mono,
|
||||
// toMono(cancelationToken))
|
||||
// .otherwise(errorFilter(cancelationToken))
|
||||
.block(timeout);
|
||||
} catch (Exception e) {
|
||||
dumpStacks();
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> get(Duration t, Mono<List<T>> 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 <T> Function<Throwable, Mono<T>> errorFilter(CancelationToken cancelationToken) {
|
||||
// return (Throwable e) -> cancelationToken.isCanceled()?Mono.error(new OperationCanceledException()):Mono.error(e);
|
||||
return (Throwable e) -> Mono.error(e);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated because this is really the same as Mono.justOrEmpty, so use that instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static <T> Mono<T> 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 <T> Function<Throwable, Mono<T>> suppressException(Class<? extends Throwable> exceptionType) {
|
||||
return (Throwable caught) -> {
|
||||
if (exceptionType.isAssignableFrom(caught.getClass())) {
|
||||
return Mono.empty();
|
||||
} else {
|
||||
return Mono.error(caught);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Mono<Void> that executes a given number of Mono<Void> one after the
|
||||
* other.
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static Mono<Void> sequence(Mono<Void>... tasks) {
|
||||
Mono<Void> seq = Mono.empty();
|
||||
for (Mono<Void> 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)
|
||||
* <p>
|
||||
* 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<Void> safeMerge(Flux<Mono<Void>> operations, int concurrency) {
|
||||
AtomicReference<Throwable> failure = new AtomicReference<>(null);
|
||||
return Flux.merge(
|
||||
operations
|
||||
.map((Mono<Void> op) -> {
|
||||
return op.otherwise((e) -> {
|
||||
failure.compareAndSet(null, e);
|
||||
return Mono.empty();
|
||||
});
|
||||
}),
|
||||
concurrency //limit concurrency otherwise troubles (flooding/choking request broker?)
|
||||
)
|
||||
.then(() -> {
|
||||
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 <T> Flux<Tuple2<T,Long>> timestamp(Flux<T> 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'.
|
||||
* <p>
|
||||
* 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 <T> Flux<T> sort(Flux<T> stream, Comparator<T> comparator, Duration bufferTime) {
|
||||
|
||||
class SorterAccumulator {
|
||||
|
||||
final PriorityQueue<Tuple2<T, Long>> holdingPen = new PriorityQueue<>((Tuple2<T, Long> o1, Tuple2<T, Long> o2) -> {
|
||||
return comparator.compare(o1.getT1(), o2.getT1());
|
||||
});
|
||||
|
||||
final Flux<T> released = Flux.fromIterable(() -> new Iterator<T>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
Tuple2<T, Long> nxt;
|
||||
synchronized (holdingPen) {
|
||||
nxt = holdingPen.peek();
|
||||
}
|
||||
return nxt!=null && isOldEnough(nxt);
|
||||
}
|
||||
|
||||
private boolean isOldEnough(Tuple2<T, Long> 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<Tuple2<T, Long>> window) {
|
||||
window.subscribe((e) -> {
|
||||
synchronized (holdingPen) {
|
||||
holdingPen.add(e);
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public Flux<T> getReleased() {
|
||||
return released;
|
||||
}
|
||||
|
||||
public Publisher<? extends T> 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<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
|
||||
for (Map.Entry<Thread, StackTraceElement[]> 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 <T> void completeWith(CompletableFuture<T> future, Mono<T> mono) {
|
||||
mono.doOnNext((T v) -> {
|
||||
future.complete(v);
|
||||
})
|
||||
.doOnError((Throwable e) -> {
|
||||
future.completeExceptionally(e);
|
||||
})
|
||||
.subscribeOn(Schedulers.elastic())
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientParamsFactory;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientTarget;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientTargets;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.CloudFoundryClientFactory;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.DefaultCloudFoundryClientFactoryV2;
|
||||
|
||||
public class CFClientTest {
|
||||
|
||||
|
||||
|
||||
@Ignore @Test public void testGetBuildpacksFromCliParamsTarget() throws Exception {
|
||||
|
||||
CFClientParamsFactory paramsFactory = CFClientParamsFactory.INSTANCE;
|
||||
CloudFoundryClientFactory clientFactory = DefaultCloudFoundryClientFactoryV2.INSTANCE;
|
||||
|
||||
CFClientTargets targets = new CFClientTargets(paramsFactory, clientFactory);
|
||||
CFClientTarget target = targets.getTargets().get(0);
|
||||
|
||||
List<CFBuildpack> buildPacks = target.getBuildpacks();
|
||||
assertTrue(!buildPacks.isEmpty());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -76,4 +76,13 @@ public class ExceptionUtil {
|
||||
return new ExecutionException(cause);
|
||||
}
|
||||
|
||||
public static Object exception(String message, Throwable error) {
|
||||
if (message != null) {
|
||||
// Wrap only if there is an additional message
|
||||
return new ExecutionException(message, error);
|
||||
} else {
|
||||
return exception(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -238,6 +238,22 @@ public class Editor {
|
||||
assertEquals(expect.toString(), actual.toString());
|
||||
}
|
||||
|
||||
public void assertContainsCompletions(String... expectTextAfter) throws Exception {
|
||||
StringBuilder actual = new StringBuilder();
|
||||
|
||||
for (CompletionItem completion : getCompletions()) {
|
||||
Editor editor = this.clone();
|
||||
editor.apply(completion);
|
||||
actual.append(editor.getText());
|
||||
actual.append("\n-------------------\n");
|
||||
}
|
||||
String actualText = actual.toString();
|
||||
|
||||
for (String after : expectTextAfter) {
|
||||
assertContains(after, actualText);
|
||||
}
|
||||
}
|
||||
|
||||
public void apply(CompletionItem completion) throws Exception {
|
||||
TextEdit edit = completion.getTextEdit();
|
||||
String docText = document.getText();
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<module>commons-util</module>
|
||||
<module>commons-java</module>
|
||||
<module>java-properties</module>
|
||||
|
||||
<module>commons-cf</module>
|
||||
<module>commons-maven</module>
|
||||
|
||||
|
||||
@@ -45,6 +45,11 @@
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>http://repo.spring.io/release</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
@@ -57,7 +62,10 @@
|
||||
<jackson-2-version>2.5.0</jackson-2-version>
|
||||
<jersey-2-version>2.10</jersey-2-version>
|
||||
<lsp4j-version>0.1.0-SNAPSHOT</lsp4j-version>
|
||||
<reactor-version>3.0.2.RELEASE</reactor-version>
|
||||
<!-- NOTE: Reactor version must match version used by the CF client -->
|
||||
<reactor-version>3.0.4.RELEASE</reactor-version>
|
||||
<reactor-netty>0.6.0.RELEASE</reactor-netty>
|
||||
<cloudfoundry-client-version>2.1.0.RELEASE</cloudfoundry-client-version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -42,6 +42,12 @@
|
||||
<artifactId>commons-yaml</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- CF -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-cf</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- Test harness -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.manifest.yaml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFBuildpack;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientTarget;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.BasicYValueHint;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YValueHint;
|
||||
|
||||
public class ManifestYamlCFBuildpacksProvider implements Provider<Collection<YValueHint>> {
|
||||
|
||||
private final List<CFClientTarget> targets;
|
||||
private static final Logger logger = Logger.getLogger(ManifestYamlCFBuildpacksProvider.class.getName());
|
||||
|
||||
|
||||
public ManifestYamlCFBuildpacksProvider(List<CFClientTarget> targets) {
|
||||
this.targets = targets;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<YValueHint> get() {
|
||||
List<YValueHint> hints = new ArrayList<>();
|
||||
|
||||
if (targets != null) {
|
||||
for (CFClientTarget cfClientTarget : targets) {
|
||||
|
||||
List<CFBuildpack> buildpacks;
|
||||
try {
|
||||
buildpacks = cfClientTarget.getBuildpacks();
|
||||
if (buildpacks != null) {
|
||||
for (CFBuildpack buildpack : buildpacks) {
|
||||
String name = buildpack.getName();
|
||||
String label = getBuildpackLabel(cfClientTarget, buildpack);
|
||||
YValueHint hint = new BasicYValueHint(name, label);
|
||||
if (!hints.contains(hint)) {
|
||||
hints.add(hint);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
|
||||
protected String getBuildpackLabel(CFClientTarget target, CFBuildpack buildpack) {
|
||||
return buildpack.getName() + " (" + target.getName() + ")";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.manifest.yaml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFServiceInstance;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientTarget;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.BasicYValueHint;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YValueHint;
|
||||
|
||||
public class ManifestYamlCFServicesProvider implements Provider<Collection<YValueHint>> {
|
||||
|
||||
private final List<CFClientTarget> targets;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ManifestYamlCFServicesProvider.class.getName());
|
||||
|
||||
public ManifestYamlCFServicesProvider(List<CFClientTarget> targets) {
|
||||
this.targets = targets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<YValueHint> get() {
|
||||
List<YValueHint> hints = new ArrayList<>();
|
||||
|
||||
if (targets != null) {
|
||||
for (CFClientTarget cfClientTarget : targets) {
|
||||
|
||||
try {
|
||||
List<CFServiceInstance> services = cfClientTarget.getClientRequests().getServices();
|
||||
if (services != null) {
|
||||
for (CFServiceInstance service : services) {
|
||||
String name = service.getName();
|
||||
String label = getServiceLabel(cfClientTarget, service);
|
||||
YValueHint hint = new BasicYValueHint(name, label);
|
||||
if (!hints.contains(hint)) {
|
||||
hints.add(hint);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
|
||||
private String getServiceLabel(CFClientTarget cfClientTarget, CFServiceInstance service) {
|
||||
return service.getName() + " - " + service.getPlan() + " (" + cfClientTarget.getParams().getOrgName() + " - "
|
||||
+ cfClientTarget.getParams().getSpaceName() + ")";
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,20 @@
|
||||
package org.springframework.ide.vscode.manifest.yaml;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionOptions;
|
||||
import org.eclipse.lsp4j.ServerCapabilities;
|
||||
import org.eclipse.lsp4j.TextDocumentSyncKind;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientParamsFactory;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientTarget;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientTargets;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.CloudFoundryClientFactory;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.DefaultCloudFoundryClientFactoryV2;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider;
|
||||
@@ -32,16 +40,25 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class ManifestYamlLanguageServer extends SimpleLanguageServer {
|
||||
|
||||
private static final Provider<Collection<YValueHint>> NO_BUILDPACKS = () -> ImmutableList.of();
|
||||
private static final Provider<Collection<YValueHint>> NO_PROVIDER = () -> ImmutableList.of();
|
||||
private static Logger logger = Logger.getLogger(ManifestYamlLanguageServer.class.getName());
|
||||
|
||||
private Yaml yaml = new Yaml();
|
||||
private YamlSchema schema = new ManifestYmlSchema(NO_BUILDPACKS);
|
||||
private YamlSchema schema;
|
||||
private CFClientTargets cfClientTargets;
|
||||
|
||||
|
||||
public ManifestYamlLanguageServer() {
|
||||
SimpleTextDocumentService documents = getTextDocumentService();
|
||||
|
||||
YamlASTProvider parser = new YamlParser(yaml);
|
||||
|
||||
CFClientTargets cfTargets = getCFTargets();
|
||||
|
||||
Provider<Collection<YValueHint>> buildPacksProvider = getBuildpacksProvider(cfTargets);
|
||||
Provider<Collection<YValueHint>> servicesProvider = getServicesProvider(cfTargets);
|
||||
|
||||
schema = new ManifestYmlSchema(buildPacksProvider, servicesProvider);
|
||||
|
||||
YamlStructureProvider structureProvider = YamlStructureProvider.DEFAULT;
|
||||
YamlAssistContextProvider contextProvider = new SchemaBasedYamlAssistContextProvider(schema);
|
||||
@@ -72,7 +89,48 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer {
|
||||
documents.onCompletionResolve(completionEngine::resolveCompletion);
|
||||
documents.onHover(hoverEngine ::getHover);
|
||||
}
|
||||
|
||||
private CFClientTargets getCFTargets() {
|
||||
if (cfClientTargets == null) {
|
||||
CFClientParamsFactory paramsFactory = CFClientParamsFactory.INSTANCE;
|
||||
CloudFoundryClientFactory clientFactory = DefaultCloudFoundryClientFactoryV2.INSTANCE;
|
||||
cfClientTargets = new CFClientTargets(paramsFactory, clientFactory);
|
||||
}
|
||||
return cfClientTargets;
|
||||
}
|
||||
|
||||
private Provider<Collection<YValueHint>> getBuildpacksProvider(CFClientTargets targets) {
|
||||
|
||||
try {
|
||||
if (targets != null) {
|
||||
List<CFClientTarget> cfTargets = targets.getTargets();
|
||||
if (cfTargets != null && !cfTargets.isEmpty()) {;
|
||||
return new ManifestYamlCFBuildpacksProvider(cfTargets);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
|
||||
return NO_PROVIDER;
|
||||
}
|
||||
|
||||
private Provider<Collection<YValueHint>> getServicesProvider(CFClientTargets targets) {
|
||||
|
||||
try {
|
||||
if (targets != null) {
|
||||
List<CFClientTarget> cfTargets = targets.getTargets();
|
||||
if (cfTargets != null && !cfTargets.isEmpty()) {
|
||||
return new ManifestYamlCFServicesProvider(cfTargets);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerCapabilities getServerCapabilities() {
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.AbstractType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YAtomicType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YBeanType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YTypedPropertyImpl;
|
||||
@@ -41,7 +42,7 @@ public class ManifestYmlSchema implements YamlSchema {
|
||||
"name", "host", "hosts"
|
||||
);
|
||||
|
||||
public ManifestYmlSchema(Provider<Collection<YValueHint>> buildpackProvider) {
|
||||
public ManifestYmlSchema(Provider<Collection<YValueHint>> buildpackProvider, Provider<Collection<YValueHint>> servicesProvider) {
|
||||
this.buildpackProvider = buildpackProvider;
|
||||
YTypeFactory f = new YTypeFactory();
|
||||
TYPE_UTIL = f.TYPE_UTIL;
|
||||
@@ -51,15 +52,20 @@ public class ManifestYmlSchema implements YamlSchema {
|
||||
|
||||
YBeanType application = f.ybean("Application");
|
||||
YAtomicType t_path = f.yatomic("Path");
|
||||
|
||||
YAtomicType t_buildpack = f.yatomic("Buildpack");
|
||||
|
||||
YAtomicType t_buildpack = f.yatomic("Buildpack");
|
||||
t_buildpack.addHintProvider(this.buildpackProvider);
|
||||
|
||||
YType t_service_string = f.yatomic("String");
|
||||
if (servicesProvider != null && t_service_string instanceof AbstractType) {
|
||||
((AbstractType)t_service_string).addHintProvider(servicesProvider);
|
||||
}
|
||||
YType t_services = f.yseq(t_service_string);
|
||||
|
||||
YAtomicType t_boolean = f.yenum("boolean", "true", "false");
|
||||
YType t_string = f.yatomic("String");
|
||||
YType t_strings = f.yseq(t_string);
|
||||
|
||||
|
||||
YAtomicType t_memory = f.yatomic("Memory");
|
||||
t_memory.addHints("256M", "512M", "1024M");
|
||||
t_memory.parseWith(ManifestYmlValueParsers.MEMORY);
|
||||
@@ -94,7 +100,7 @@ public class ManifestYmlSchema implements YamlSchema {
|
||||
f.yprop("no-route", t_boolean),
|
||||
f.yprop("path", t_path),
|
||||
f.yprop("random-route", t_boolean),
|
||||
f.yprop("services", t_strings),
|
||||
f.yprop("services", t_services),
|
||||
f.yprop("stack", t_string),
|
||||
f.yprop("timeout", t_pos_integer),
|
||||
f.yprop("health-check-type", t_health_check_type)
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.manifest.yaml;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
|
||||
public class ManifestYamlEditorCFTest {
|
||||
LanguageServerHarness harness;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
harness = new LanguageServerHarness(ManifestYamlLanguageServer::new);
|
||||
harness.intialize(null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Optional test that is here only to be run in certain conditions. Tests if
|
||||
* buildpack completion values are actually fetched from PWS if the test env
|
||||
* also has a CLI that is alread connected to PWS. Enable only if underlying
|
||||
* conditions for CF connection from vscode are present. For example, CLI is
|
||||
* installed.
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void optionalDynamicBuildpacksPWSUsingCliParams() throws Exception {
|
||||
// No special test harness setup to use CLI. It is a "default" CF client params
|
||||
// provider in the CF vscode framework.
|
||||
// Just have to make sure the test env has a CLI that is connected to
|
||||
// PWS
|
||||
assertContainsCompletions("buildpack: <*>", "buildpack: java_buildpack<*>");
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void optionalDynamicServicesPWSUsingCliParams() throws Exception {
|
||||
// No special test harness setup to use CLI. It is a "default" CF client params
|
||||
// provider in the CF vscode framework.
|
||||
// Just have to make sure the test env has a CLI that is connected to
|
||||
// PWS
|
||||
assertContainsCompletions( "services:\n"+
|
||||
" - <*>", "sql");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void assertContainsCompletions(String textBefore, String... textAfter) throws Exception {
|
||||
Editor editor = harness.newEditor(textBefore);
|
||||
editor.assertContainsCompletions(textAfter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public class ManifestYmlSchemaTest {
|
||||
"timeout"
|
||||
};
|
||||
|
||||
ManifestYmlSchema schema = new ManifestYmlSchema(null);
|
||||
ManifestYmlSchema schema = new ManifestYmlSchema(null, null);
|
||||
|
||||
@Test
|
||||
public void toplevelProperties() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user