diff --git a/pom.xml b/pom.xml index d0225128..a7fbbffa 100755 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,12 @@ com.jcraft jsch - 0.1.44-1 + 0.1.51 + + + org.apache.commons + commons-compress + 1.8.1 junit diff --git a/src/main/java/com/openshift/client/DeploymentTypes.java b/src/main/java/com/openshift/client/DeploymentTypes.java new file mode 100644 index 00000000..bd94fbe8 --- /dev/null +++ b/src/main/java/com/openshift/client/DeploymentTypes.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.client; + +import java.util.Arrays; +import java.util.List; + +/** + * @author Andre Dietisheim + */ +public class DeploymentTypes { + + private static final String GIT = "git"; + private static final String BINARY = "binary"; + + private DeploymentTypes() { + } + + public static String git() { + return GIT; + } + + public static String binary() { + return BINARY; + } + + public static boolean isBinary(String deploymentType) { + return BINARY.equals(deploymentType); + } + + public static boolean isGit(String deploymentType) { + return GIT.equals(deploymentType); + } + + public static List getAll() { + return Arrays.asList(GIT, BINARY); + } + + public static String switchType(String deploymentType) { + if (isBinary(deploymentType)) { + return GIT; + } else if (isGit(deploymentType)) { + return BINARY; + } else { + throw new OpenShiftException("Unknown deployment type {0}", deploymentType); + } + } + +} diff --git a/src/main/java/com/openshift/client/IApplication.java b/src/main/java/com/openshift/client/IApplication.java index 7e307f36..55d0340b 100755 --- a/src/main/java/com/openshift/client/IApplication.java +++ b/src/main/java/com/openshift/client/IApplication.java @@ -61,11 +61,18 @@ public interface IApplication extends IOpenShiftResource { public String getSshUrl(); /** - * Returns the git url that the application will get its initial code and configuration from. + * Returns the git url that the application will get its initial code and + * configuration from. * * @return the initial git url */ public String getInitialGitUrl(); + + /** + * Returns the deployment type for this application. Either "binary" or "git" currently. + * @return "binary" or "git" + */ + public String getDeploymentType(); /** * Returns the url at which this application may be reached at. @@ -103,7 +110,8 @@ public interface IApplication extends IOpenShiftResource { /** * Adds the given embeddable cartridge to this application. * - * @param cartridge the cartridge that shall be added + * @param cartridge + * the cartridge that shall be added * @throws OpenShiftException */ public IEmbeddedCartridge addEmbeddableCartridge(ICartridge cartridge) throws OpenShiftException; @@ -111,7 +119,8 @@ public interface IApplication extends IOpenShiftResource { /** * Adds the given embeddable cartridges to this application. * - * @param cartridges the cartridges that shall be added + * @param cartridges + * the cartridges that shall be added * @throws OpenShiftException */ public List addEmbeddableCartridges(ICartridge... cartridges) throws OpenShiftException; @@ -182,8 +191,8 @@ public IEmbeddedCartridge getEmbeddedCartridge(String cartridgeName) throws OpenShiftException; /** - * Returns the embedded cartridge in this application. Returns null if none was - * found. + * Returns the embedded cartridge in this application. Returns + * null if none was found. * * @param cartridge * @return the embedded cartridge @@ -205,19 +214,19 @@ public IEmbeddedCartridge getEmbeddedCartridge(IEmbeddableCartridge cartridge) public void removeEmbeddedCartridge(IEmbeddableCartridge cartridge) throws OpenShiftException; /** - * Removes the given embedded cartridges in this application that are equal to the - * given IEmbeddableCartridge. Does nothing if the cartridge is not present - * in this application. + * Removes the given embedded cartridges in this application that are equal + * to the given IEmbeddableCartridge. Does nothing if the cartridge is not + * present in this application. * - * @param cartridges the cartridges that shall get removed + * @param cartridges + * the cartridges that shall get removed * @throws OpenShiftException */ public void removeEmbeddedCartridges(Collection cartridges) throws OpenShiftException; - /** - * Returns the gear groups for this application. - * The collection is never cached, so each call will trigger a request to the OpenShift Broker. + * Returns the gear groups for this application. The collection is never + * cached, so each call will trigger a request to the OpenShift Broker. * * @return the collection of {@link IGearGroup} for this application. * @throws OpenShiftException @@ -321,6 +330,15 @@ public IEmbeddedCartridge getEmbeddedCartridge(IEmbeddableCartridge cartridge) */ public void scaleUp() throws OpenShiftException; + /** + * Sets the deployment type for this application. Can be either "binary" or + * "git" currently. + * + * @param deploymentType + * @return the deployment type that was set + */ + public String setDeploymentType(String deploymentType); + /** * Add application alias * @@ -359,9 +377,11 @@ public IEmbeddedCartridge getEmbeddedCartridge(IEmbeddableCartridge cartridge) * initialized out of the library, since the user's SSH settings may depend * on the runtime environment (Eclipse, etc.). * - * @param session the SSH session + * @param session + * the SSH session * - * @deprecated use {@link IApplicationSSHSession#setSSHSession(com.jcraft.jsch.Session)} + * @deprecated use + * {@link IApplicationSSHSession#setSSHSession(com.jcraft.jsch.Session)} */ public void setSSHSession(Session session); @@ -454,36 +474,45 @@ public IEmbeddedCartridge getEmbeddedCartridge(IEmbeddableCartridge cartridge) /** * Checks if the environment variable is present in the application. * - * @param name Name of the environment variable - * @return true if the current instance has IEnvironmentVariables to return
- * false if the current instance has no IEnvironmentVariables to return + * @param name + * Name of the environment variable + * @return true if the current instance has + * IEnvironmentVariables to return
+ * false if the current instance has no + * IEnvironmentVariables to return * @throws OpenShiftSSHOperationException */ public boolean hasEnvironmentVariable(String name) throws OpenShiftException; /** - * Adds an environment variable to this application. + * Adds an environment variable to this application. * - * @param name key associated with the variable to add - * @param value value of the new variable - * @throws OpenShiftSSHOperationException - if the variable already exists + * @param name + * key associated with the variable to add + * @param value + * value of the new variable + * @throws OpenShiftSSHOperationException + * - if the variable already exists */ public IEnvironmentVariable addEnvironmentVariable(String name, String value) throws OpenShiftException; /** * Updates an environment variable to this application. * - * @param name key associated with the variable to update - * @param value value of the new variable - * @throws OpenShiftSSHOperationException - if the variable already exists + * @param name + * key associated with the variable to update + * @param value + * value of the new variable + * @throws OpenShiftSSHOperationException + * - if the variable already exists */ public IEnvironmentVariable updateEnvironmentVariable(String name, String value) throws OpenShiftException; - /** * Adds a map of environment variables to the application * - * @param environmentVariables Map of environment variables + * @param environmentVariables + * Map of environment variables * @throws OpenShiftSSHOperationException */ public Map addEnvironmentVariables(Map environmentVariables) @@ -492,44 +521,60 @@ public Map addEnvironmentVariables(Maptrue if this application can list its environment variables.
- * Returns false if it cannot. Internally this translates to the presence of the link to list environment variables. + * @return Returns true if this application can list its + * environment variables.
+ * Returns false if it cannot. Internally this + * translates to the presence of the link to list environment + * variables. * * @see #getEnvironmentVariablesMap() * @see #getEnvironmentVariable(String) @@ -538,9 +583,11 @@ public Map addEnvironmentVariables(Maptrue if this application can augment its environment variables.
+ * @return Returns true if this application can augment its + * environment variables.
* Returns false if it cannot.
* * @see #addEnvironmentVariable(String, String) diff --git a/src/main/java/com/openshift/client/IApplicationSSHSession.java b/src/main/java/com/openshift/client/IApplicationSSHSession.java index 5e170405..2b5e6edc 100644 --- a/src/main/java/com/openshift/client/IApplicationSSHSession.java +++ b/src/main/java/com/openshift/client/IApplicationSSHSession.java @@ -37,7 +37,7 @@ public interface IApplicationSSHSession { * @return true if the SSH session provided to the application * is still valid (connected). */ - public boolean isSSHSessionConnected(); + public boolean isConnected(); /** * Returns the list of forwardable ports on OpenShift for this application. diff --git a/src/main/java/com/openshift/client/IUser.java b/src/main/java/com/openshift/client/IUser.java index f92f2bfc..3f420614 100755 --- a/src/main/java/com/openshift/client/IUser.java +++ b/src/main/java/com/openshift/client/IUser.java @@ -42,8 +42,30 @@ public interface IUser extends IOpenShiftResource { public List getSSHKeys() throws OpenShiftException; + /** + * Deprecated, use {@link #addSSHKey(String, ISSHPublicKey)} + * + * @param name key name to use + * @param key the key to put/add + * @return + * @throws OpenShiftException + */ + @Deprecated public IOpenShiftSSHKey putSSHKey(String name, ISSHPublicKey key) throws OpenShiftException; + /** + * Adds the given ssh key with the given name. Key names and public keys have to be unique. Throws + * OpenShiftSSHKeyException if either the key name or the public key are already used. + * + * @param name + * the name to identify the key + * @param key + * the key to add + * @return + * @throws OpenShiftException + */ + public IOpenShiftSSHKey addSSHKey(String name, ISSHPublicKey key) throws OpenShiftException; + public IOpenShiftSSHKey getSSHKeyByName(String name) throws OpenShiftUnknonwSSHKeyTypeException, OpenShiftException; public IOpenShiftSSHKey getSSHKeyByPublicKey(String publicKey) throws OpenShiftUnknonwSSHKeyTypeException, OpenShiftException; @@ -52,6 +74,9 @@ public interface IUser extends IOpenShiftResource { public boolean hasSSHPublicKey(String publicKey) throws OpenShiftUnknonwSSHKeyTypeException, OpenShiftException; + public boolean removeSSHKey(String name); + + @Deprecated public void deleteKey(String name); public int getMaxGears(); diff --git a/src/main/java/com/openshift/client/SSHPublicKey.java b/src/main/java/com/openshift/client/SSHPublicKey.java index 7d96363d..216245bb 100644 --- a/src/main/java/com/openshift/client/SSHPublicKey.java +++ b/src/main/java/com/openshift/client/SSHPublicKey.java @@ -47,7 +47,7 @@ private void init(File publicKeyFile) throws OpenShiftException, FileNotFoundExc Matcher matcher = PUBLICKEY_PATTERN.matcher(keyWithIdAndComment); if (!matcher.find() || matcher.groupCount() < 1) { - throw new OpenShiftException("Could not load public key from file \"{0}\"", publicKeyFile.getAbsolutePath()); + throw new OpenShiftException("Could not load public key from file \"{0}\": unknown key format.", publicKeyFile.getAbsolutePath()); } setKeyType(matcher.group(1)); diff --git a/src/main/java/com/openshift/client/utils/TarFileUtils.java b/src/main/java/com/openshift/client/utils/TarFileUtils.java new file mode 100644 index 00000000..e59b7e80 --- /dev/null +++ b/src/main/java/com/openshift/client/utils/TarFileUtils.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.client.utils; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; + +import com.openshift.internal.client.utils.StreamUtils; + +/** + * @author Andre Dietisheim + */ +public class TarFileUtils { + + private static final String GIT_FOLDER_NAME = "git"; + + private TarFileUtils() { + // inhibit instantiation + } + + public static boolean hasGitFolder(InputStream inputStream) throws IOException { + TarArchiveInputStream tarInputStream = null; + try { + boolean gitFolderPresent = false; + tarInputStream = new TarArchiveInputStream(new GzipCompressorInputStream(inputStream)); + for (TarArchiveEntry entry = null; (entry = tarInputStream.getNextTarEntry()) != null;) { + if (GIT_FOLDER_NAME.equals(entry.getName()) + && entry.isDirectory()) { + gitFolderPresent = true; + break; + } + } + return gitFolderPresent; + } finally { + StreamUtils.close(tarInputStream); + } + } +} diff --git a/src/main/java/com/openshift/internal/client/AbstractOpenShiftResource.java b/src/main/java/com/openshift/internal/client/AbstractOpenShiftResource.java index a053bc40..33e0e977 100755 --- a/src/main/java/com/openshift/internal/client/AbstractOpenShiftResource.java +++ b/src/main/java/com/openshift/internal/client/AbstractOpenShiftResource.java @@ -141,7 +141,7 @@ protected ServiceRequest(final String linkName) { protected DTO execute(final Parameter... parameters) throws OpenShiftException { return getData(getService().request( - getLink(linkName), + getLink(linkName), IHttpClient.NO_TIMEOUT, Collections. emptyList(), Collections. emptyList(), diff --git a/src/main/java/com/openshift/internal/client/ApplicationResource.java b/src/main/java/com/openshift/internal/client/ApplicationResource.java index ff04e280..cc6081a6 100755 --- a/src/main/java/com/openshift/internal/client/ApplicationResource.java +++ b/src/main/java/com/openshift/internal/client/ApplicationResource.java @@ -93,6 +93,8 @@ public class ApplicationResource extends AbstractOpenShiftResource implements IA private static final String LINK_GET_GEAR_GROUPS = "GET_GEAR_GROUPS"; private static final String LINK_LIST_ENVIRONMENT_VARIABLES = "LIST_ENVIRONMENT_VARIABLES"; private static final String LINK_SET_UNSET_ENVIRONMENT_VARIABLES = "SET_UNSET_ENVIRONMENT_VARIABLES"; + private static final String LINK_UPDATE = "UPDATE"; + private static final Pattern REGEX_FORWARDED_PORT = Pattern.compile("([^ ]+) -> ([^:]+):(\\d+)"); /** The (unique) uuid of this application. */ @@ -127,6 +129,9 @@ public class ApplicationResource extends AbstractOpenShiftResource implements IA /** the git url for the initial code and configuration for the application */ private String initialGitUrl; + + /** the deployment type for this application **/ + private String deploymentType; /** The aliases of this application. */ private List aliases; @@ -156,7 +161,7 @@ public class ApplicationResource extends AbstractOpenShiftResource implements IA protected ApplicationResource(ApplicationResourceDTO dto, DomainResource domain) { this(dto.getName(), dto.getUuid(), dto.getCreationTime(), dto.getMessages(), dto.getApplicationUrl(), - dto.getSshUrl(), dto.getGitUrl(), dto.getInitialGitUrl(), dto.getGearProfile(), dto.getApplicationScale(), + dto.getSshUrl(), dto.getGitUrl(), dto.getInitialGitUrl(), dto.getDeploymentType(), dto.getGearProfile(), dto.getApplicationScale(), dto.getAliases(), dto.getCartridges(), dto.getLinks(), domain); } @@ -189,7 +194,7 @@ protected ApplicationResource(ApplicationResourceDTO dto, DomainResource domain) */ protected ApplicationResource(final String name, final String uuid, final String creationTime, final Messages messages, final String applicationUrl, final String sshUrl, final String gitUrl, - final String initialGitUrl, final IGearProfile gearProfile, final ApplicationScale scale, final List aliases, + final String initialGitUrl, final String deploymentType, final IGearProfile gearProfile, final ApplicationScale scale, final List aliases, final Map cartridgesByName, final Map links, final DomainResource domain) { super(domain.getService(), links, messages); @@ -202,6 +207,7 @@ protected ApplicationResource(final String name, final String uuid, final String this.sshUrl = sshUrl; this.gitUrl = gitUrl; this.initialGitUrl = initialGitUrl; + this.deploymentType = deploymentType; this.domain = domain; this.aliases = aliases; updateCartridges(cartridgesByName); @@ -341,10 +347,16 @@ public String getGitUrl() { return gitUrl; } + @Override public String getInitialGitUrl() { return initialGitUrl; } + @Override + public String getDeploymentType() { + return deploymentType; + } + @Override public String getSshUrl() { return sshUrl; @@ -355,6 +367,19 @@ public String getApplicationUrl() { return applicationUrl; } + @Override + public String setDeploymentType(String deploymentType) { + Assert.isTrue(!StringUtils.isEmpty(deploymentType)); + + if (this.deploymentType.equals(deploymentType)) { + return this.deploymentType; + } + + final ApplicationResourceDTO applicationDTO = + new UpdateRequest().execute(deploymentType); + return this.deploymentType = applicationDTO.getDeploymentType(); + } + @Override public IEmbeddedCartridge addEmbeddableCartridge(ICartridge cartridge) throws OpenShiftException { Assert.notNull(cartridge); @@ -727,18 +752,12 @@ public Map addEnvironmentVariables(Map execute(Map envir } } + private class UpdateRequest extends ServiceRequest { + protected UpdateRequest() { + super(LINK_UPDATE); + } + + protected DTO execute(String deploymentType) throws OpenShiftException { + return super.execute(new StringParameter(IOpenShiftJsonConstants.PROPERTY_DEPLOYMENT_TYPE, deploymentType)); + } + } } diff --git a/src/main/java/com/openshift/internal/client/ApplicationSSHSession.java b/src/main/java/com/openshift/internal/client/ApplicationSSHSession.java index afaf37ee..6d93f817 100644 --- a/src/main/java/com/openshift/internal/client/ApplicationSSHSession.java +++ b/src/main/java/com/openshift/internal/client/ApplicationSSHSession.java @@ -10,30 +10,45 @@ ******************************************************************************/ package com.openshift.internal.client; -import com.jcraft.jsch.Channel; -import com.jcraft.jsch.ChannelExec; -import com.jcraft.jsch.JSchException; -import com.jcraft.jsch.Session; -import com.openshift.client.*; -import com.openshift.internal.client.ssh.ApplicationPortForwarding; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcraft.jsch.Channel; +import com.jcraft.jsch.ChannelExec; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; +import com.openshift.client.IApplication; +import com.openshift.client.IApplicationPortForwarding; +import com.openshift.client.IApplicationSSHSession; +import com.openshift.client.OpenShiftException; +import com.openshift.client.OpenShiftSSHOperationException; +import com.openshift.client.utils.TarFileUtils; +import com.openshift.internal.client.ssh.ApplicationPortForwarding; +import com.openshift.internal.client.utils.StreamUtils; + /** + * @author Xavier Coulon * @author André Dietisheim - * @author Syed Iqbal - * @author Martes G Wigglesworth * @author Corey Daley */ public class ApplicationSSHSession implements IApplicationSSHSession { + private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationSSHSession.class); + + private static final int CONNECT_TIMEOUT = 10 * 60 * 1000; + private static final String JSCH_EXEC_CHANNEL = "exec"; + /** SSH Session to use for all methods */ private Session session; @@ -43,17 +58,16 @@ public class ApplicationSSHSession implements IApplicationSSHSession { /** List of ports available for port forwarding */ private List ports = null; - /** Regex for port forwarding */ - private static final Pattern REGEX_FORWARDED_PORT = Pattern.compile("([^ ]+) -> ([^:]+):(\\d+)"); - /** * Sets the SSH session that this application will use to connect to * OpenShift to perform some operations. This SSH session must be * initialized out of the library, since the user's SSH settings may depend * on the runtime environment (Eclipse, etc.). * - * @param application The application that this SSH session is connecting to - * @param session The SSH session that is connected to the application + * @param application + * The application that this SSH session is connecting to + * @param session + * The SSH session that is connected to the application */ public ApplicationSSHSession(IApplication application, Session session) { this.application = application; @@ -62,57 +76,65 @@ public ApplicationSSHSession(IApplication application, Session session) { /** * Set the current SSH session - * @param session A new SSH session to use for the ApplicationSSHSession object + * + * @param session + * A new SSH session to use for the ApplicationSSHSession object */ - public void setSSHSession(final Session session) {this.session = session;} + public void setSSHSession(final Session session) { + this.session = session; + } /** * Get the application associated with this ApplicationSSHSession + * * @return The application associated with this ssh session */ - public IApplication getApplication() {return this.application;} + public IApplication getApplication() { + return this.application; + } /** * Check if the current SSH session is connected + * * @return True if the SSH session is connected */ - public boolean isSSHSessionConnected() { + public boolean isConnected() { return this.session.isConnected(); } /** * Check if port forwarding has been started + * * @return true if port forwarding is started, false otherwise * @throws OpenShiftSSHOperationException */ public boolean isPortFowardingStarted() throws OpenShiftSSHOperationException { try { - return isSSHSessionConnected() && this.session.getPortForwardingL().length > 0; + return isConnected() + && session.getPortForwardingL().length > 0; } catch (JSchException e) { throw new OpenShiftSSHOperationException(e, - "Unable to verify if port-forwarding has been started for application \"{0}\"", application.getName()); + "Unable to verify if port-forwarding has been started for application \"{0}\"", + application.getName()); } } /** * Start forwarding available ports to this application + * * @return Current list of ports * @throws OpenShiftSSHOperationException */ public List startPortForwarding() throws OpenShiftSSHOperationException { - if (!isSSHSessionConnected()) { - throw new OpenShiftSSHOperationException( - "SSH session for application ''{0}'' is closed. Cannot start port forwarding", - application.getName()); - } + assertLiveSSHSession(); + for (IApplicationPortForwarding port : ports) { try { port.start(session); } catch (OpenShiftSSHOperationException oss) { /* - * ignore for now - * FIXME: should store this error on the forward to let user - * know why it could not start/stop + * ignore for now FIXME: should store this error on the forward + * to let user know why it could not start/stop */ } } @@ -121,17 +143,19 @@ public List startPortForwarding() throws OpenShiftSS /** * Stop forwarding of all ports to this application + * * @return The current list of ports * @throws OpenShiftSSHOperationException */ public List stopPortForwarding() throws OpenShiftSSHOperationException { + assertLiveSSHSession(); for (IApplicationPortForwarding port : ports) { try { port.stop(session); } catch (OpenShiftSSHOperationException oss) { - /* ignore for now - * should store this error on the forward to let user know why - * it could not start/stop + /* + * ignore for now should store this error on the forward to let + * user know why it could not start/stop */ } } @@ -142,20 +166,24 @@ public List stopPortForwarding() throws OpenShiftSSH /** * Refresh the list of forwardable ports for an application + * * @return List of forwardable ports for your application * @throws OpenShiftSSHOperationException */ public List refreshForwardablePorts() throws OpenShiftSSHOperationException { + assertLiveSSHSession(); this.ports = loadPorts(); return getForwardablePorts(); } /** * Gets a list of forwardable ports for your application + * * @return List of forwardable ports for your application * @throws OpenShiftSSHOperationException */ public List getForwardablePorts() throws OpenShiftSSHOperationException { + assertLiveSSHSession(); if (ports == null) { this.ports = loadPorts(); } @@ -164,64 +192,112 @@ public List getForwardablePorts() throws OpenShiftSS /** * Get a list of properties from your OpenShift Application + * * @return List of properties from your OpenShift application * @throws OpenShiftSSHOperationException */ @Override public List getEnvironmentProperties() throws OpenShiftSSHOperationException { + assertLiveSSHSession(); List openshiftProps = new ArrayList(); - List allEnvProps = sshExecCmd("set", SshStreams.INPUT); - for (String line : allEnvProps) { - openshiftProps.add(line); + InputStream in = execCommand("set", ChannelInputStreams.DATA, session); + try { + for (String line : new SshCommandResponse(in).getLines()) { + openshiftProps.add(line); + } + return openshiftProps; + } catch (IOException e) { + throw new OpenShiftSSHOperationException(e, + "Could not execute \"set\" command via ssh on application {0}", application.getName()); } - return openshiftProps; + } + + public InputStream saveFullSnapshot() { + assertLiveSSHSession(); + + return new FullSnapshotCommand(session).save(); + } + + public InputStream restoreFullSnapshot(InputStream inputStream) { + return restoreFullSnapshot(inputStream, true); } /** - * Extract the named forwardable port from the 'rhc-list-ports' command - * result line, with the following format: - * java -> 127.10.187.1:4447. - * - * @param portValue The raw port data to parse - * @return the forwardable port. + * Restores the given full snapshot to the application that this session is + * bound to. Providing true for includeGit will also activate + * the snapshot (and having the page reflecting the changes in the + * snapshot). It only works though if the snapshot has a /git/ folder with + * content. + * + * @param inputStream + * the snapshot + * @param includeGit + * will activate the new snapshot given the snapshot includes a + * /git folder + * @return + * + * @see TarFileUtils#hasGitFolder(InputStream) + * @see #saveFullSnapshot() */ - private ApplicationPortForwarding extractForwardablePortFrom(final String portValue) { - Matcher matcher = REGEX_FORWARDED_PORT.matcher(portValue); - if (!matcher.find() - || matcher.groupCount() != 3) { - return null; - } - try { - final String name = matcher.group(1); - final String host = matcher.group(2); - final int remotePort = Integer.parseInt(matcher.group(3)); - return new ApplicationPortForwarding(application, name, host, remotePort); - } catch(NumberFormatException e) { - throw new OpenShiftSSHOperationException(e, - "Couild not determine forwarded port in application {0}", application.getName()); - } + public InputStream restoreFullSnapshot(InputStream inputStream, boolean includeGit) { + assertLiveSSHSession(); + + return new FullSnapshotCommand(session).restore(inputStream, includeGit); + } + + public InputStream saveDeploymentSnapshot() { + assertLiveSSHSession(); + + return new DeploymentSnapshotCommand(session).save(); } /** - * List all forwardable ports for a given application. - * + * Restores the given snapshot to the application that this session is bound + * to. + * + * @param inputStream + * the snapshot + * @param hotDeploy + * will not restart the application if true + * @return + * @throws OpenShiftException + * + * @see #saveDeploymentSnapshot() + */ + public InputStream restoreDeploymentSnapshot(InputStream inputStream, boolean hotDeploy) + throws OpenShiftException { + return new DeploymentSnapshotCommand(session).restore(inputStream, hotDeploy); + } + + /** + * List all forwardable ports for a given application. saveSnapshot + * * @return the forwardable ports in an unmodifiable collection * @throws OpenShiftSSHOperationException */ private List loadPorts() throws OpenShiftSSHOperationException { + assertLiveSSHSession(); this.ports = new ArrayList(); - List lines = sshExecCmd("rhc-list-ports", SshStreams.EXT_INPUT); - for (String line : lines) { - ApplicationPortForwarding port = extractForwardablePortFrom(line); - if (port != null) { - ports.add(port); + InputStream in = execCommand("rhc-list-ports", ChannelInputStreams.EXTENDED_DATA, session); + try { + return this.ports = + new RhcListPortsCommandResponse(application, in).getPortForwardings(); + } catch (IOException e) { + throw new OpenShiftSSHOperationException("Could not execute \"rhc-list-ports\" via ssh in application {0}", + application.getName()); + } finally { + try { + StreamUtils.close(in); + } catch (IOException e) { + LOGGER.error("Could not close channel to ssh server", e); } } - return ports; + } /** - * Refreshes the list of ports + * Refreshes the list of forwardable ports + * * @throws OpenShiftException */ public void refresh() throws OpenShiftException { @@ -232,15 +308,14 @@ public void refresh() throws OpenShiftException { @Override public boolean equals(Object object) { - if (this == object) { - return true; - } if (object == null) { return false; - } - if (getClass() != object.getClass()) { + } else if (getClass() != object.getClass()) { return false; + } else if (object == this) { + return true; } + ApplicationSSHSession other = (ApplicationSSHSession) object; ApplicationResource otherapp = (ApplicationResource) ((ApplicationSSHSession) object).getApplication(); if (application.getUUID() == null) { @@ -249,11 +324,11 @@ public boolean equals(Object object) { } } else if (!application.getUUID().equals(otherapp.getUUID())) { return false; - } else if (this.isSSHSessionConnected() != other.isSSHSessionConnected()) { + } else if (isConnected() != other.isConnected()) { return false; } else if (isPortFowardingStarted() != other.isPortFowardingStarted()) { return false; - } else if (this.application != otherapp) { + } else if (!application.equals(otherapp)) { return false; } return true; @@ -264,69 +339,282 @@ public String toString() { return "ApplicationSSHSession [" + "applicationuuid=" + application.getUUID() + ", applicationname=" + application.getName() - + ", isconnected=" + isSSHSessionConnected() + + ", isconnected=" + isConnected() + ", isportforwardingstarted=" + isPortFowardingStarted() + "]"; } - protected enum SshStreams { - EXT_INPUT { - protected InputStream getInputStream(Channel channel) throws IOException { - return channel.getExtInputStream(); - } + protected void assertLiveSSHSession() { + if (!isConnected()) { + throw new OpenShiftSSHOperationException( + "SSH session for application \"{0}\" is closed.", + application.getName()); + } + } - }, INPUT { - protected InputStream getInputStream(Channel channel) throws IOException { - return channel.getInputStream(); + protected InputStream execCommand(final String command, ChannelInputStreams factory, Session session) + throws OpenShiftSSHOperationException { + return execCommand(command, null, factory, session); + } + + /** + * + * @param command + * The remote command to run on the server + * @param sshMsgChannelData + * @param sshStream + * The ssh stream to use + * @return The output of the command that is run on the server + * @throws OpenShiftSSHOperationException + */ + protected InputStream execCommand(final String command, InputStream forStdIn, + ChannelInputStreams channelInputStream, Session session) throws OpenShiftSSHOperationException { + assertLiveSSHSession(); + + ChannelExec channel = null; + try { + channel = (ChannelExec) session.openChannel(JSCH_EXEC_CHANNEL); + ((ChannelExec) channel).setCommand(command); + final OutputStream remoteStdIn = channel.getOutputStream(); + + InputStream in = channel.getInputStream(); + ChannelResponse channelResponse = new ChannelResponse(in, channel); + channel.connect(CONNECT_TIMEOUT); + if (forStdIn != null) { + writeToRemoteStdInput(forStdIn, remoteStdIn); } - }; + return channelResponse; + } catch (JSchException e) { + channel.disconnect(); + throw new OpenShiftSSHOperationException(e, + "Could no execute remote ssh command \"{0}\" on application {1}", + command, application.getName()); + } catch (IOException e) { + channel.disconnect(); + throw new OpenShiftSSHOperationException(e, + "Could not get response channel for remote ssh command \"{0}\" on application {1}", + command, application.getName()); + } + } - public List getLines(Channel channel) throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(getInputStream(channel))); + private void writeToRemoteStdInput(InputStream forStdInput, OutputStream remoteStdIn) throws IOException { + for (int data = -1; (data = forStdInput.read()) != -1;) { + remoteStdIn.write(data); + } + remoteStdIn.close(); + forStdInput.close(); + } + + public abstract class AbstractSnapshotType { + + private String saveCommand; + private String restoreCommand; + + private AbstractSnapshotType(String saveCommand, String restoreCommand) { + this.saveCommand = saveCommand; + this.restoreCommand = restoreCommand; + } + + public String getSaveCommand() { + return saveCommand; + } + + public String getRestoreCommand() { + return restoreCommand; + } + } + + protected abstract class AbstractSnapshotSshCommand { + + protected Session session; + + AbstractSnapshotSshCommand(Session session) { + this.session = session; + } + + } + + class FullSnapshotCommand extends AbstractSnapshotSshCommand { + + FullSnapshotCommand(Session session) { + super(session); + } + + public InputStream save() { + /* rhc snapshot save -a */ + return execCommand( + "snapshot", ChannelInputStreams.DATA, session); + } + + public InputStream restore(InputStream in, boolean includeGit) { + return execCommand( + MessageFormat.format("restore{0}", includeGit ? " INCLUDE_GIT" : ""), + in, + ChannelInputStreams.DATA, + session); + } + } + + class DeploymentSnapshotCommand extends AbstractSnapshotSshCommand { + + DeploymentSnapshotCommand(Session session) { + super(session); + } + + public InputStream save() { + /* rhc snapshot save -a */ + return execCommand( + "gear archive-deployment", ChannelInputStreams.DATA, session); + } + + public InputStream restore(InputStream inputStream, boolean hotDeploy) { + return execCommand( + MessageFormat.format("oo-binary-deploy{0}", hotDeploy ? " --hot-deploy" : ""), + inputStream, + ChannelInputStreams.DATA, + session); + } + } + + protected static class SshCommandResponse { + + private InputStream inputStream; + + SshCommandResponse(InputStream inputStream) { + this.inputStream = inputStream; + } + + public List getLines() throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); List lines = new ArrayList(); String line = null; - // Read File Line By Line while ((line = reader.readLine()) != null) { lines.add(line); } return lines; } - protected abstract InputStream getInputStream(Channel channel) throws IOException; } - /** - * - * @param command The remote command to run on the server - * @param sshStream The ssh stream to use - * @return The output of the command that is run on the server - * @throws OpenShiftSSHOperationException - */ - protected List sshExecCmd(final String command, final SshStreams sshStream) - throws OpenShiftSSHOperationException { - final Session session = this.session; - if (session == null) { - throw new OpenShiftSSHOperationException( - "No SSH session available for application ''{0}''. Please supply an SSH session using ApplicationResource@setSSHSession.", - application.getName()); + private static class RhcListPortsCommandResponse extends SshCommandResponse { + + /** Regex for port forwarding */ + private static final Pattern REGEX_FORWARDED_PORT = Pattern.compile("([^ ]+) -> ([^:]+):(\\d+)"); + + private IApplication application; + + RhcListPortsCommandResponse(IApplication application, InputStream inputStream) { + super(inputStream); + this.application = application; } - Channel channel = null; - try { - session.openChannel("exec"); - channel = session.openChannel("exec"); - ((ChannelExec) channel).setCommand(command); - channel.connect(); - return sshStream.getLines(channel); - } catch (JSchException e) { - throw new OpenShiftSSHOperationException(e, "Failed to execute remote ssh command \"{0}\"", - application.getName()); - } catch (IOException e) { - throw new OpenShiftSSHOperationException(e, "Failed to execute remote ssh command \"{0}\"", - application.getName()); - } finally { - if (channel != null && channel.isConnected()) { - channel.disconnect(); + public List getPortForwardings() throws IOException { + List ports = new ArrayList(); + for (String line : getLines()) { + ApplicationPortForwarding port = extractForwardablePortFrom(line); + if (port != null) { + ports.add(port); + } + } + return ports; + } + + /** + * Extracts the named forwardable port from the 'rhc-list-ports' command + * result line, with the following format: + * java -> 127.10.187.1:4447. + * + * @param rhcListPortsOutput + * The raw port data to parse + * @return the forwardable port. + */ + private ApplicationPortForwarding extractForwardablePortFrom(final String rhcListPortsOutput) { + Matcher matcher = REGEX_FORWARDED_PORT.matcher(rhcListPortsOutput); + if (!matcher.find() + || matcher.groupCount() != 3) { + return null; + } + try { + final String name = matcher.group(1); + final String host = matcher.group(2); + final int remotePort = Integer.parseInt(matcher.group(3)); + return new ApplicationPortForwarding(application, name, host, remotePort); + } catch (NumberFormatException e) { + throw new OpenShiftSSHOperationException(e, + "Couild not determine forwarded port in application {0}", application.getName()); } } } + + enum ChannelInputStreams { + DATA { + + @Override + public InputStream get(Channel channel) throws IOException, JSchException { + return channel.getInputStream(); + } + + }, + EXTENDED_DATA { + @Override + public InputStream get(Channel channel) throws IOException, JSchException { + return channel.getExtInputStream(); + } + }; + + public abstract InputStream get(Channel channel) throws IOException, JSchException; + } + + class ChannelResponse extends InputStream { + + /** the delay to wait for further data from the remote **/ + private static final int WAIT_DELAY = 1000; + + private ChannelExec channel; + private InputStream channelInputStream; + private InputStream channelErrorStream; + + protected ChannelResponse(InputStream response, ChannelExec channel) + throws IOException, JSchException { + this.channel = channel; + // ATTENTION: stream must be get before connecting + this.channelInputStream = response; + this.channelErrorStream = channel.getErrStream(); + } + + @Override + public int read() throws IOException { + if (channel.isClosed() + && channel.getExitStatus() != 0) { + throw new IOException(StreamUtils.readToString(channelErrorStream)); + } + while (!(channel.isClosed() + && channelInputStream.available() == 0)) { + if (channelInputStream.available() > 0) { + int data = channelInputStream.read(); + if (data == -1) { + continue; + } + return data; + } + try { + Thread.sleep(WAIT_DELAY); + } catch (InterruptedException e) { + break; + } + } + return -1; + } + + @Override + public void close() throws IOException { + channel.disconnect(); + channelInputStream.close(); + } + + @Override + public int available() throws IOException { + return channelInputStream.available(); + } + } + } diff --git a/src/main/java/com/openshift/internal/client/UserResource.java b/src/main/java/com/openshift/internal/client/UserResource.java index 29dfea26..5397ad85 100755 --- a/src/main/java/com/openshift/internal/client/UserResource.java +++ b/src/main/java/com/openshift/internal/client/UserResource.java @@ -10,8 +10,9 @@ ******************************************************************************/ package com.openshift.internal.client; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import com.openshift.client.IDomain; import com.openshift.client.IOpenShiftConnection; @@ -40,7 +41,7 @@ public class UserResource extends AbstractOpenShiftResource implements IUser { private final int maxGears; private final int consumedGears; - private List sshKeys; + private Map sshKeys; public UserResource(final APIResource api, final UserResourceDTO dto, final String password) { super(api.getService(), dto.getLinks(), dto.getMessages()); @@ -51,64 +52,74 @@ public UserResource(final APIResource api, final UserResourceDTO dto, final Stri this.password = password; } + @Override public IOpenShiftConnection getConnection() { return api; } + @Override public String getRhlogin() { return rhLogin; } + @Override public String getPassword() { return password; } + @Override public String getServer() { return api.getServer(); } + @Override public int getMaxGears() { return maxGears; } + @Override public int getConsumedGears() { return consumedGears; } + @Override public IDomain createDomain(String id) throws OpenShiftException { Assert.notNull(id); return api.createDomain(id); } + @Override public List getDomains() throws OpenShiftException { List domains = api.getDomains(); return domains; } + @Override public IDomain getDefaultDomain() throws OpenShiftException { return api.getDefaultDomain(); } + @Override public IDomain getDomain(String id) throws OpenShiftException { return api.getDomain(id); } + @Override public boolean hasDomain() throws OpenShiftException { return (api.getDomains().size() > 0); } + @Override public boolean hasDomain(String id) throws OpenShiftException { Assert.notNull(id); return api.getDomain(id) != null; } + @Override public void refresh() throws OpenShiftException { - if (this.sshKeys != null) { - this.sshKeys = null; - loadKeys(); - } + this.sshKeys = loadKeys(); api.refresh(); DomainResource defaultDomain = (DomainResource) getDefaultDomain(); @@ -117,14 +128,15 @@ public void refresh() throws OpenShiftException { } } + @Override public List getSSHKeys() throws OpenShiftUnknonwSSHKeyTypeException, OpenShiftException { - List keys = new ArrayList(); - keys.addAll(getCachedOrLoadSSHKeys()); - return CollectionUtils.toUnmodifiableCopy(keys); + Map keys = new HashMap(); + keys.putAll(getCachedOrLoadSSHKeys()); + return CollectionUtils.toUnmodifiableCopy(keys.values()); } - private List getCachedOrLoadSSHKeys() throws OpenShiftException, + private Map getCachedOrLoadSSHKeys() throws OpenShiftException, OpenShiftUnknonwSSHKeyTypeException { if (sshKeys == null) { this.sshKeys = loadKeys(); @@ -132,41 +144,42 @@ private List getCachedOrLoadSSHKeys() throws OpenShiftException, return sshKeys; } - private List loadKeys() throws OpenShiftException, + private Map loadKeys() throws OpenShiftException, OpenShiftUnknonwSSHKeyTypeException { - List keys = new ArrayList(); + Map keys = new HashMap(); List keyDTOs = new GetSShKeysRequest().execute(); for (KeyResourceDTO keyDTO : keyDTOs) { - keys.add(new SSHKeyResource(keyDTO, this)); + keys.put(keyDTO.getName(), new SSHKeyResource(keyDTO, this)); } return keys; } - public void deleteKey(String name) { + @Override + public boolean removeSSHKey(String name) { IOpenShiftSSHKey key = getSSHKeyByName(name); - if (key != null) { - key.destroy(); + if (key == null) { + return false; } + key.destroy(); + getCachedOrLoadSSHKeys().remove(name); + return true; } + @Deprecated + @Override + public void deleteKey(String name) { + removeSSHKey(name); + } + + @Override public IOpenShiftSSHKey getSSHKeyByName(String name) throws OpenShiftUnknonwSSHKeyTypeException, OpenShiftException { Assert.notNull(name); - IOpenShiftSSHKey matchingKey = null; - if (name == null) { - return null; - } - - for (SSHKeyResource key : getCachedOrLoadSSHKeys()) { - if (name.equals(key.getName())) { - matchingKey = key; - break; - } - } - return matchingKey; + return getCachedOrLoadSSHKeys().get(name); } + @Override public IOpenShiftSSHKey getSSHKeyByPublicKey(String publicKey) throws OpenShiftUnknonwSSHKeyTypeException, OpenShiftException { Assert.notNull(publicKey); @@ -176,7 +189,7 @@ public IOpenShiftSSHKey getSSHKeyByPublicKey(String publicKey) return null; } - for (SSHKeyResource key : getCachedOrLoadSSHKeys()) { + for (SSHKeyResource key : getCachedOrLoadSSHKeys().values()) { if (publicKey.equals(key.getPublicKey())) { matchingKey = key; break; @@ -185,6 +198,7 @@ public IOpenShiftSSHKey getSSHKeyByPublicKey(String publicKey) return matchingKey; } + @Override public boolean hasSSHKeyName(String name) throws OpenShiftUnknonwSSHKeyTypeException, OpenShiftException { Assert.notNull(name); @@ -192,26 +206,26 @@ public boolean hasSSHKeyName(String name) throws OpenShiftUnknonwSSHKeyTypeExcep return getSSHKeyByName(name) != null; } + @Override public boolean hasSSHPublicKey(String publicKey) throws OpenShiftUnknonwSSHKeyTypeException, OpenShiftException { return getSSHKeyByPublicKey(publicKey) != null; } - /** - * Adds the given ssh key with the given name. Key names and public keys have to be unique. Throws - * OpenShiftSSHKeyException if either the key name or the public key are already used. - * - * @param name - * the name to identify the key - * @param key - * the key to add - * @return - * @throws OpenShiftException - */ + @Override public IOpenShiftSSHKey putSSHKey(String name, ISSHPublicKey key) throws OpenShiftException { Assert.notNull(name); Assert.notNull(key); + KeyResourceDTO keyDTO = new AddSShKeyRequest().execute(key.getKeyType(), name, key.getPublicKey()); + return put(keyDTO); + } + + @Override + public IOpenShiftSSHKey addSSHKey(String name, ISSHPublicKey key) throws OpenShiftException { + Assert.notNull(name); + Assert.notNull(key); + if (hasSSHKeyName(name)) { throw new OpenShiftSSHKeyException( "Could not add new key {0} with the name {1}. There already is a key for this name, key names must be unique.", @@ -228,12 +242,12 @@ public IOpenShiftSSHKey putSSHKey(String name, ISSHPublicKey key) throws OpenShi private SSHKeyResource put(KeyResourceDTO keyDTO) throws OpenShiftUnknonwSSHKeyTypeException { SSHKeyResource sshKey = new SSHKeyResource(keyDTO, this); - sshKeys.add(sshKey); + getCachedOrLoadSSHKeys().put(keyDTO.getName(), sshKey); return sshKey; } protected void removeSSHKey(SSHKeyResource key) { - sshKeys.remove(key); + sshKeys.remove(key.getName()); } private class GetSShKeysRequest extends ServiceRequest { diff --git a/src/main/java/com/openshift/internal/client/response/ApplicationResourceDTO.java b/src/main/java/com/openshift/internal/client/response/ApplicationResourceDTO.java index a078c014..fa97faa7 100755 --- a/src/main/java/com/openshift/internal/client/response/ApplicationResourceDTO.java +++ b/src/main/java/com/openshift/internal/client/response/ApplicationResourceDTO.java @@ -50,13 +50,16 @@ public class ApplicationResourceDTO extends BaseResourceDTO { /** the application's url. */ private final String applicationUrl; - + /** the ssh url. */ private final String sshUrl; /** the application's git repository url. */ private final String gitUrl; + /** the deployment type */ + private final String deploymentType; + /** the url for the git repo with the initial code for this application. */ private final String initialGitUrl; @@ -74,7 +77,7 @@ public class ApplicationResourceDTO extends BaseResourceDTO { */ ApplicationResourceDTO(final String framework, final String domainId, final String creationTime, final String name, final IGearProfile gearProfile, final ApplicationScale scale, final String uuid, - final String applicationUrl, final String sshUrl, final String gitUrl, final String initialGitUrl, final List aliases, + final String applicationUrl, final String sshUrl, final String gitUrl, final String initialGitUrl, final String deploymentType, final List aliases, final Map cartridgeByName, final Map links, Messages messages) { super(links, messages); this.framework = framework; @@ -88,6 +91,7 @@ public class ApplicationResourceDTO extends BaseResourceDTO { this.sshUrl = sshUrl; this.gitUrl = gitUrl; this.initialGitUrl = initialGitUrl; + this.deploymentType = deploymentType; this.aliases = aliases; this.cartridgesByName = cartridgeByName; } @@ -180,6 +184,13 @@ public final String getInitialGitUrl() { return initialGitUrl; } + /** + * @return the deployment type for this application. Either "binary" or "git" + */ + public String getDeploymentType() { + return deploymentType; + } + /** * @return the aliases */ diff --git a/src/main/java/com/openshift/internal/client/response/OpenShiftJsonDTOFactory.java b/src/main/java/com/openshift/internal/client/response/OpenShiftJsonDTOFactory.java index 301417ac..03129c64 100755 --- a/src/main/java/com/openshift/internal/client/response/OpenShiftJsonDTOFactory.java +++ b/src/main/java/com/openshift/internal/client/response/OpenShiftJsonDTOFactory.java @@ -16,6 +16,7 @@ import static com.openshift.internal.client.utils.IOpenShiftJsonConstants.PROPERTY_CONSUMED_GEARS; import static com.openshift.internal.client.utils.IOpenShiftJsonConstants.PROPERTY_CREATION_TIME; import static com.openshift.internal.client.utils.IOpenShiftJsonConstants.PROPERTY_DATA; +import static com.openshift.internal.client.utils.IOpenShiftJsonConstants.PROPERTY_DEPLOYMENT_TYPE; import static com.openshift.internal.client.utils.IOpenShiftJsonConstants.PROPERTY_DESCRIPTION; import static com.openshift.internal.client.utils.IOpenShiftJsonConstants.PROPERTY_DISPLAY_NAME; import static com.openshift.internal.client.utils.IOpenShiftJsonConstants.PROPERTY_DOMAIN_ID; @@ -300,6 +301,7 @@ private ApplicationResourceDTO createApplication(ModelNode appNode, Messages mes final String sshUrl = getAsString(appNode, PROPERTY_SSH_URL); final String gitUrl = getAsString(appNode, PROPERTY_GIT_URL); final String initialGitUrl = getAsString(appNode, PROPERTY_INITIAL_GIT_URL); + final String deploymentType = getAsString(appNode, PROPERTY_DEPLOYMENT_TYPE); final String domainId = getAsString(appNode, PROPERTY_DOMAIN_ID); final Map links = createLinks(appNode.get(PROPERTY_LINKS)); final List aliases = createAliases(appNode.get(PROPERTY_ALIASES)); @@ -317,6 +319,7 @@ private ApplicationResourceDTO createApplication(ModelNode appNode, Messages mes sshUrl, gitUrl, initialGitUrl, + deploymentType, aliases, cartridges, links, diff --git a/src/main/java/com/openshift/internal/client/utils/IOpenShiftJsonConstants.java b/src/main/java/com/openshift/internal/client/utils/IOpenShiftJsonConstants.java index a3253125..0eb81193 100755 --- a/src/main/java/com/openshift/internal/client/utils/IOpenShiftJsonConstants.java +++ b/src/main/java/com/openshift/internal/client/utils/IOpenShiftJsonConstants.java @@ -32,6 +32,7 @@ public class IOpenShiftJsonConstants { public static final String PROPERTY_DEFAULT_VALUE = "default_value"; public static final String PROPERTY_DELETE = "delete"; public static final String PROPERTY_DESCRIPTION = "description"; + public static final String PROPERTY_DEPLOYMENT_TYPE = "deployment_type"; public static final String PROPERTY_DISPLAY_NAME = "display_name"; public static final String PROPERTY_DOMAIN = "domain"; public static final String PROPERTY_DOMAINS = "domains"; diff --git a/src/main/java/com/openshift/internal/client/utils/StreamUtils.java b/src/main/java/com/openshift/internal/client/utils/StreamUtils.java index 8178ebbb..f92891e5 100644 --- a/src/main/java/com/openshift/internal/client/utils/StreamUtils.java +++ b/src/main/java/com/openshift/internal/client/utils/StreamUtils.java @@ -11,7 +11,6 @@ package com.openshift.internal.client.utils; import java.io.BufferedReader; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -19,8 +18,6 @@ import java.io.Reader; import java.io.StringWriter; import java.io.Writer; -import java.util.ArrayList; -import java.util.List; /** * @author Andre Dietisheim @@ -28,29 +25,23 @@ public class StreamUtils { public static final String UTF_8 = "UTF-8"; + + private static final byte[] buffer = new byte[1024]; /** - * Writes the content of the given input stream to the given output stream - * and returns and input stream that may still be used to read from. + * Writes the content of the given input stream to the given output stream. * * @param outputStream * the output stream to write to * @param inputStream * the input stream to read from - * @return a new, unread input stream * @throws IOException */ - public static InputStream writeTo(InputStream inputStream, OutputStream outputStream) throws IOException { - List data = new ArrayList(); - for (int character = -1; (character = inputStream.read()) != -1;) { - data.add((byte) character); - outputStream.write(character); - } - byte[] byteArray = new byte[data.size()]; - for (int i = byteArray.length - 1; i >= 0; i--) { - byteArray[i] = data.get(i); + public static void writeTo(InputStream inputStream, OutputStream outputStream) throws IOException { + for (int bytesRead = 0; (bytesRead = inputStream.read(buffer, 0, buffer.length)) != -1; ) { + outputStream.write(buffer, 0, bytesRead); } - return new ByteArrayInputStream(byteArray); + outputStream.flush(); } public static String readToString(InputStream inputStream) throws IOException { @@ -102,7 +93,7 @@ public static void close(InputStream inputStream) throws IOException { inputStream.close(); } } - + public static void quietlyClose(InputStream inputStream) { try { close(inputStream); diff --git a/src/test/java/com/openshift/client/utils/ApplicationAssert.java b/src/test/java/com/openshift/client/utils/ApplicationAssert.java index 70ede3ec..ecbcf720 100644 --- a/src/test/java/com/openshift/client/utils/ApplicationAssert.java +++ b/src/test/java/com/openshift/client/utils/ApplicationAssert.java @@ -257,7 +257,7 @@ public void assertThatContainsCartridges(Collection should } } - public ApplicationAssert hasContent(String page, String contains) throws IOException { + public ApplicationAssert pageContains(String page, String contains) throws IOException { URL appUrl = new URL(application.getApplicationUrl() + page); assertThat(application.waitForAccessible(APPLICATION_WAIT_TIMEOUT)).isTrue(); String content = StreamUtils.readToString(appUrl.openConnection().getInputStream()); diff --git a/src/test/java/com/openshift/client/utils/ApplicationTestUtils.java b/src/test/java/com/openshift/client/utils/ApplicationTestUtils.java index 0eef9b14..c63547ed 100755 --- a/src/test/java/com/openshift/client/utils/ApplicationTestUtils.java +++ b/src/test/java/com/openshift/client/utils/ApplicationTestUtils.java @@ -39,7 +39,11 @@ public static String createRandomApplicationName() { } public static IApplication createApplication(IStandaloneCartridge cartridge, IDomain domain) { - IApplication application = domain.createApplication(createRandomApplicationName(), cartridge); + return createApplication(createRandomApplicationName(), cartridge, domain); + } + + public static IApplication createApplication(String name, IStandaloneCartridge cartridge, IDomain domain) { + IApplication application = domain.createApplication(name, cartridge); assertTrue(application.waitForAccessible(WAIT_FOR_APPLICATION)); return application; } @@ -99,7 +103,7 @@ public static IApplication getOrCreateApplication(IDomain domain, IStandaloneCar } } - return domain.createApplication("app" + StringUtils.createRandomString(), cartridge); + return createApplication("app" + StringUtils.createRandomString(), cartridge, domain); } /** diff --git a/src/test/java/com/openshift/client/utils/FileUtils.java b/src/test/java/com/openshift/client/utils/FileUtils.java index 5c03bce1..9719b196 100644 --- a/src/test/java/com/openshift/client/utils/FileUtils.java +++ b/src/test/java/com/openshift/client/utils/FileUtils.java @@ -20,6 +20,8 @@ */ public class FileUtils { + private static final String JAVA_IO_TEMP = "java.io.tmpdir"; + public static void writeTo(String data, String path) throws IOException { writeTo(data, new File(path)); } @@ -45,7 +47,24 @@ public static void writeTo(String data, File file) throws IOException { } public static File createRandomTempFile() throws IOException { - return File.createTempFile(String.valueOf(System.currentTimeMillis()), null); + return createRandomTempFile(null); + } + + public static File createRandomTempFile(String suffix) throws IOException { + File file = File.createTempFile(createRandomFilename(), suffix); + file.deleteOnExit(); + return file; + } + + public static File createRandomTempDirectory() throws IOException { + File file = File.createTempFile(null, createRandomFilename()); + file.mkdir(); + file.deleteOnExit(); + return file; + } + + public static String createRandomFilename() { + return String.valueOf(System.currentTimeMillis()); } public static void silentlyDelete(File file) { @@ -54,4 +73,16 @@ public static void silentlyDelete(File file) { } file.delete(); } + + public static String getTempDirectory() { + return System.getProperty(JAVA_IO_TEMP); + } + + public static String getTempDirFilePath(String name) { + return new File(getTempDirectory(), name).getAbsolutePath(); + } + + public static String getTempDirFilePath() { + return getTempDirFilePath(createRandomFilename()); + } } diff --git a/src/test/java/com/openshift/client/utils/SSHKeyTestUtils.java b/src/test/java/com/openshift/client/utils/SSHKeyTestUtils.java index 11699bcb..80fbf9e0 100644 --- a/src/test/java/com/openshift/client/utils/SSHKeyTestUtils.java +++ b/src/test/java/com/openshift/client/utils/SSHKeyTestUtils.java @@ -11,59 +11,35 @@ package com.openshift.client.utils; import static com.openshift.client.utils.FileUtils.createRandomTempFile; -import static org.junit.Assert.assertEquals; +import static org.fest.assertions.Assertions.assertThat; +import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.util.List; -import org.fest.assertions.AssertExtension; - import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.KeyPair; import com.openshift.client.IOpenShiftSSHKey; import com.openshift.client.IUser; -import com.openshift.client.SSHKeyType; +import com.openshift.client.OpenShiftException; +import com.openshift.client.SSHPublicKey; /** * @author Andre Dietisheim */ public class SSHKeyTestUtils { + public static final String SSH_TEST_KEY_NAME = "OSJC_SSHKEY"; + public static final String SSH_TEST_PUBLICKEY = FileUtils.getTempDirFilePath(SSH_TEST_KEY_NAME + ".pub"); + public static final String SSH_TEST_PRIVATEKEY = FileUtils.getTempDirFilePath(SSH_TEST_KEY_NAME); + public static final String DEFAULT_PASSPHRASE = "12345"; public static final String SSH_RSA = "ssh-rsa"; public static final String SSH_DSA = "ssh-dss"; - public static class SSHPublicKeyAssertion implements AssertExtension { - - private IOpenShiftSSHKey sshKey; - - public SSHPublicKeyAssertion(IOpenShiftSSHKey key) { - this.sshKey = key; - } - - public SSHPublicKeyAssertion hasName(String name) { - assertEquals(name, sshKey.getName()); - return this; - } - - public SSHPublicKeyAssertion hasPublicKey(String publicKey) { - assertEquals(publicKey, sshKey.getPublicKey()); - return this; - } - - public SSHPublicKeyAssertion isType(String type) { - assertEquals(type, sshKey.getKeyType().getTypeId()); - return this; - } - - public SSHPublicKeyAssertion isType(SSHKeyType type) { - assertEquals(type, sshKey.getKeyType()); - return this; - } - } - /** * Returns the key with the given name out of the keys in the given list of * keys. Uses plain java means to look for the key (so that tests may limit @@ -95,11 +71,12 @@ public static IOpenShiftSSHKey getKey(String name, List keys) * @throws IOException * @throws JSchException */ - public static void createDsaKeyPair(String publicKeyPath, String privateKeyPath) throws IOException, JSchException { + public static KeyPair createDsaKeyPair(String publicKeyPath, String privateKeyPath) throws IOException, JSchException { KeyPair keyPair = KeyPair.genKeyPair(new JSch(), KeyPair.DSA, 1024); keyPair.setPassphrase(DEFAULT_PASSPHRASE); keyPair.writePublicKey(publicKeyPath, "created by " + IUser.ID); keyPair.writePrivateKey(privateKeyPath); + return keyPair; } public static String createDsaKeyPair() throws IOException, JSchException { @@ -123,4 +100,18 @@ public static void silentlyDestroyKey(IOpenShiftSSHKey key) { public static String createRandomKeyName() { return String.valueOf(System.currentTimeMillis()); } + + public static KeyPair createSSHTestKeys() throws IOException, JSchException { + new File(SSH_TEST_PUBLICKEY).createNewFile(); + new File(SSH_TEST_PRIVATEKEY).createNewFile(); + return createDsaKeyPair(SSH_TEST_PUBLICKEY, SSH_TEST_PRIVATEKEY); + } + + public static void addTestKeyToOpenShift(IUser user) throws OpenShiftException, FileNotFoundException, IOException, JSchException { + assertThat(user).isNotNull(); + createSSHTestKeys(); + user.removeSSHKey(SSH_TEST_KEY_NAME); + user.addSSHKey(SSH_TEST_KEY_NAME, new SSHPublicKey(SSH_TEST_PUBLICKEY)); + } + } diff --git a/src/test/java/com/openshift/client/utils/SSHPublicKeyAssertion.java b/src/test/java/com/openshift/client/utils/SSHPublicKeyAssertion.java new file mode 100644 index 00000000..6edb0171 --- /dev/null +++ b/src/test/java/com/openshift/client/utils/SSHPublicKeyAssertion.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2012 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.client.utils; + +import static org.fest.assertions.Assertions.assertThat; + +import org.fest.assertions.AssertExtension; + +import com.openshift.client.IOpenShiftSSHKey; +import com.openshift.client.SSHKeyType; + +/** + * @author Andre Dietisheim + */ +public class SSHPublicKeyAssertion implements AssertExtension { + + private IOpenShiftSSHKey sshKey; + + public SSHPublicKeyAssertion(IOpenShiftSSHKey key) { + this.sshKey = key; + } + + public SSHPublicKeyAssertion hasName(String name) { + assertThat(name).isEqualTo(sshKey.getName()); + return this; + } + + public SSHPublicKeyAssertion hasPublicKey(String publicKey) { + assertThat(publicKey).isEqualTo(sshKey.getPublicKey()); + return this; + } + + public SSHPublicKeyAssertion isType(String type) { + assertThat(type).isEqualTo(sshKey.getKeyType().getTypeId()); + return this; + } + + public SSHPublicKeyAssertion isType(SSHKeyType type) { + assertThat(type).isEqualTo(sshKey.getKeyType()); + return this; + } + } \ No newline at end of file diff --git a/src/test/java/com/openshift/client/utils/TarFileTestUtils.java b/src/test/java/com/openshift/client/utils/TarFileTestUtils.java new file mode 100644 index 00000000..cd1e5263 --- /dev/null +++ b/src/test/java/com/openshift/client/utils/TarFileTestUtils.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.client.utils; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import org.apache.commons.compress.archivers.ArchiveEntry; +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.compress.utils.IOUtils; + +import com.openshift.internal.client.utils.Assert; +import com.openshift.internal.client.utils.StreamUtils; + +/** + * @author Andre Dietisheim + */ +public class TarFileTestUtils { + + private TarFileTestUtils() { + // inhibit instantiation + } + + /** + * Replaces the given file(-name), that might exist anywhere nested in the + * given archive, by a new entry with the given content. The replacement is + * faked by adding a new entry into the archive which will overwrite the + * existing (older one) on extraction. + * + * @param name + * the name of the file to replace (no path required) + * @param newContent + * the content of the replacement file + * @param in + * @return + * @throws IOException + * @throws ArchiveException + * @throws CompressorException + */ + public static File fakeReplaceFile(String name, String newContent, InputStream in) throws IOException { + Assert.notNull(name); + Assert.notNull(in); + + File newArchive = FileUtils.createRandomTempFile(".tar.gz"); + newArchive.deleteOnExit(); + + TarArchiveOutputStream newArchiveOut = + new TarArchiveOutputStream(new GZIPOutputStream(new FileOutputStream(newArchive))); + newArchiveOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU); + + TarArchiveInputStream archiveIn = new TarArchiveInputStream(new GZIPInputStream(in)); + String pathToReplace = null; + try { + // copy the existing entries + for (ArchiveEntry nextEntry = null; (nextEntry = archiveIn.getNextEntry()) != null;) { + if (nextEntry.getName().endsWith(name)) { + pathToReplace = nextEntry.getName(); + } + newArchiveOut.putArchiveEntry(nextEntry); + IOUtils.copy(archiveIn, newArchiveOut); + newArchiveOut.closeArchiveEntry(); + } + + if (pathToReplace == null) { + throw new IllegalStateException("Could not find file " + name + " in the given archive."); + } + TarArchiveEntry newEntry = new TarArchiveEntry(pathToReplace); + newEntry.setSize(newContent.length()); + newArchiveOut.putArchiveEntry(newEntry); + IOUtils.copy(new ByteArrayInputStream(newContent.getBytes()), newArchiveOut); + newArchiveOut.closeArchiveEntry(); + + return newArchive; + } finally { + newArchiveOut.finish(); + newArchiveOut.flush(); + StreamUtils.close(archiveIn); + StreamUtils.close(newArchiveOut); + } + } + + /** + * Returns all paths within the given archive. + * + * @param in + * the archive + * @return all paths + * @throws IOException + * @throws CompressorException + */ + public static List getAllPaths(InputStream in) throws IOException { + Assert.notNull(in); + + List paths = new ArrayList(); + TarArchiveInputStream archiveIn = new TarArchiveInputStream(new GZIPInputStream(in)); + try { + for (ArchiveEntry nextEntry = null; (nextEntry = archiveIn.getNextEntry()) != null;) { + paths.add(nextEntry.getName()); + } + return paths; + } finally { + StreamUtils.close(archiveIn); + } + } +} diff --git a/src/test/java/com/openshift/internal/client/ApplicationResourceIntegrationTest.java b/src/test/java/com/openshift/internal/client/ApplicationResourceIntegrationTest.java index 30ad63ce..e9bf5e86 100755 --- a/src/test/java/com/openshift/internal/client/ApplicationResourceIntegrationTest.java +++ b/src/test/java/com/openshift/internal/client/ApplicationResourceIntegrationTest.java @@ -18,13 +18,13 @@ import java.net.MalformedURLException; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.junit.Before; import org.junit.Test; import com.openshift.client.ApplicationScale; +import com.openshift.client.DeploymentTypes; import com.openshift.client.IApplication; import com.openshift.client.IDomain; import com.openshift.client.IEnvironmentVariable; @@ -38,7 +38,6 @@ import com.openshift.client.utils.ApplicationTestUtils; import com.openshift.client.utils.DomainTestUtils; import com.openshift.client.utils.GearGroupsAssert; -import com.openshift.client.utils.StringUtils; import com.openshift.client.utils.TestConnectionFactory; /** @@ -457,4 +456,27 @@ public void shouldCanGetCanUpdateEnvironmentVariables() throws Throwable { //verify list environment variables assertThat(application.canGetEnvironmentVariables()).isTrue(); } + + @Test + public void shouldGetDeploymentType() throws Throwable { + // pre-conditions + IApplication application = ApplicationTestUtils.getOrCreateApplication(domain); + + // operation + // verifications + assertThat(application.getDeploymentType()).isIn(DeploymentTypes.getAll()); + } + + @Test + public void shouldUpdateDeploymentType() throws Throwable { + // pre-conditions + IApplication application = ApplicationTestUtils.getOrCreateApplication(domain); + String deploymentType = application.getDeploymentType(); + String newDeploymentType = DeploymentTypes.switchType(deploymentType); + + // operation + application.setDeploymentType(newDeploymentType); + // verifications + assertThat(application.getDeploymentType()).isEqualTo(newDeploymentType); + } } diff --git a/src/test/java/com/openshift/internal/client/ApplicationSSHSessionIntegrationTest.java b/src/test/java/com/openshift/internal/client/ApplicationSSHSessionIntegrationTest.java index c039f8f1..bdae639d 100644 --- a/src/test/java/com/openshift/internal/client/ApplicationSSHSessionIntegrationTest.java +++ b/src/test/java/com/openshift/internal/client/ApplicationSSHSessionIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Red Hat, Inc. + * Copyright (c) 2014 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -10,28 +10,166 @@ ******************************************************************************/ package com.openshift.internal.client; +import static org.fest.assertions.Assertions.assertThat; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.zip.GZIPInputStream; + +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.commons.compress.compressors.CompressorException; +import org.junit.After; import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; +import com.openshift.client.DeploymentTypes; +import com.openshift.client.IApplication; import com.openshift.client.IDomain; -import com.openshift.client.IOpenShiftConnection; import com.openshift.client.IUser; +import com.openshift.client.cartridge.query.LatestVersionOf; +import com.openshift.client.utils.ApplicationAssert; +import com.openshift.client.utils.ApplicationTestUtils; import com.openshift.client.utils.DomainTestUtils; +import com.openshift.client.utils.FileUtils; +import com.openshift.client.utils.SSHKeyTestUtils; +import com.openshift.client.utils.StringUtils; +import com.openshift.client.utils.TarFileTestUtils; import com.openshift.client.utils.TestConnectionFactory; +import com.openshift.internal.client.utils.StreamUtils; /** - * @author Corey Daley + * @author Andre Dietisheim */ public class ApplicationSSHSessionIntegrationTest extends TestTimer { - private IUser user; - private IDomain domain; + private static IUser user; + + private IApplication application; + private Session session; + + @BeforeClass + public static void createSSHKeys() throws IOException, JSchException { + user = new TestConnectionFactory().getConnection().getUser(); + SSHKeyTestUtils.addTestKeyToOpenShift(user); + } @Before public void setUp() throws Exception { - IOpenShiftConnection connection = new TestConnectionFactory().getConnection(); - this.user = connection.getUser(); - this.domain = DomainTestUtils.ensureHasDomain(user); + IDomain domain = DomainTestUtils.ensureHasDomain(user); + this.application = ApplicationTestUtils.getOrCreateApplication(domain, LatestVersionOf.php().get(user)); + this.session = createSSHSession(application.getSshUrl()); + } + + @After + public void tearDown() { + this.session.disconnect(); + } + + @Test + public void shouldSaveDeploymentSnapshot() throws IOException, CompressorException { + // pre-conditions + File snapshotFile = FileUtils.createRandomTempFile(".tar.gz"); + FileOutputStream snapshotFileOut = new FileOutputStream(snapshotFile); + + // operations + InputStream in = new ApplicationSSHSession(application, session).saveDeploymentSnapshot(); + writeTo(in, snapshotFileOut); + + // verifications + List allPaths = TarFileTestUtils.getAllPaths(new FileInputStream(snapshotFile)); + assertThat(allPaths).contains("./build-dependencies/", "./dependencies/", "./repo/"); + assertThat(allPaths).excludes("./git/"); } + @Test + public void shouldRestoreDeploymentSnapshot() throws IOException { + // pre-conditions + File snapshotFile = FileUtils.createRandomTempFile(".tar.gz"); + ApplicationSSHSession applicationSession = new ApplicationSSHSession(application, session); + InputStream snapshot = applicationSession.saveDeploymentSnapshot(); + writeTo(snapshot, new FileOutputStream(snapshotFile)); + String title = StringUtils.createRandomString(); + File newArchive = TarFileTestUtils.fakeReplaceFile( + "index.php", "

" + title + "

", new FileInputStream(snapshotFile)); + assertThat(newArchive).isNotNull(); + assertThat(newArchive.length()).isGreaterThan(0); + application.setDeploymentType(DeploymentTypes.binary()); + + // operations + InputStream restoreOutput = applicationSession.restoreDeploymentSnapshot(new FileInputStream(newArchive), true); + StreamUtils.writeTo(restoreOutput, System.out); + // verifications + new ApplicationAssert(application).pageContains("", title); + } + + @Test + public void shouldRestoreFullSnapshot() throws IOException, ArchiveException, CompressorException { + // pre-conditions + File snapshotFile = FileUtils.createRandomTempFile(".tar.gz"); + FileOutputStream snapshotFileOut = new FileOutputStream(snapshotFile); + ApplicationSSHSession applicationSession = new ApplicationSSHSession(application, session); + InputStream in = applicationSession.saveFullSnapshot(); + writeTo(in, snapshotFileOut); + assertThat(snapshotFile.length()).isGreaterThan(0); + + String title = StringUtils.createRandomString(); + File newArchive = TarFileTestUtils.fakeReplaceFile( + "index.php", "

" + title + "

", new FileInputStream(snapshotFile)); + assertThat(newArchive).isNotNull(); + assertThat(newArchive.length()).isGreaterThan(0); + + // operations + InputStream restoreResponse = + applicationSession.restoreFullSnapshot(new FileInputStream(newArchive), true); + StreamUtils.writeTo(restoreResponse, System.out); + + // verification + new ApplicationAssert(application).pageContains("", title); + } + + @Test + public void shouldSaveFullSnapshot() throws IOException { + // pre-conditions + File snapshotFile = FileUtils.createRandomTempFile(".tar.gz"); + FileOutputStream snapshotFileOut = new FileOutputStream(snapshotFile); + + // operations + // use gzip inputStream to assert valid gzip file + InputStream in = new GZIPInputStream( + new ApplicationSSHSession(application, session).saveFullSnapshot()); + writeTo(in, snapshotFileOut); + // verifications + assertThat(snapshotFile.length()).isGreaterThan(0); + } + + private void writeTo(InputStream inputStream, FileOutputStream fileOut) throws IOException { + try { + StreamUtils.writeTo(inputStream, fileOut); + } finally { + StreamUtils.close(inputStream); + fileOut.flush(); + StreamUtils.close(fileOut); + } + } + + private Session createSSHSession(String sshUrl) throws JSchException, URISyntaxException { + JSch.setConfig("StrictHostKeyChecking", "no"); + JSch jsch = new JSch(); + jsch.addIdentity(SSHKeyTestUtils.SSH_TEST_PRIVATEKEY, SSHKeyTestUtils.DEFAULT_PASSPHRASE); + URI sshUri = new URI(sshUrl); + Session session = jsch.getSession(sshUri.getUserInfo(), sshUri.getHost()); + session.connect(); + return session; + } } diff --git a/src/test/java/com/openshift/internal/client/ApplicationSSHSessionMockDirector.java b/src/test/java/com/openshift/internal/client/ApplicationSSHSessionMockDirector.java new file mode 100644 index 00000000..d8cba537 --- /dev/null +++ b/src/test/java/com/openshift/internal/client/ApplicationSSHSessionMockDirector.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2013 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.client; + +import java.io.ByteArrayInputStream; +import java.net.SocketTimeoutException; + +import org.mockito.Mockito; + +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; +import com.openshift.client.IApplication; +import com.openshift.internal.client.httpclient.HttpClientException; + +/** + * @author Andre Dietisheim + * @author Syed Iqbal + */ +public class ApplicationSSHSessionMockDirector { + + private ApplicationSSHSession applicationSession; + private ApplicationSSHSession spyedApplicationSession; + + public ApplicationSSHSessionMockDirector(IApplication application) throws SocketTimeoutException, + HttpClientException, JSchException { + ApplicationResource spyedApplication = Mockito.spy(((ApplicationResource) application)); + this.applicationSession = + new ApplicationSSHSession(spyedApplication, new JSch().getSession("mockuser", "mockhost", 22)); + this.spyedApplicationSession = Mockito.spy(((ApplicationSSHSession) applicationSession)); + Mockito.doReturn(true) + .when(spyedApplicationSession) + .isConnected(); + } + + public ApplicationSSHSessionMockDirector mockGetForwardablePorts(String response) { + Mockito.doReturn(new ByteArrayInputStream(response.getBytes())) + .when(spyedApplicationSession) + .execCommand(Mockito.anyString(), (ApplicationSSHSession.ChannelInputStreams) Mockito.any(), + (Session) Mockito.any()); + return this; + } + + public ApplicationSSHSessionMockDirector mockGetEnvironmentProperties(String response) { + Mockito.doReturn(new ByteArrayInputStream(response.getBytes())) + .when(spyedApplicationSession) + .execCommand(Mockito.anyString(), + (ApplicationSSHSession.ChannelInputStreams) Mockito.any(), + (Session) Mockito.any()); + return this; + } + + public ApplicationSSHSession getMock() { + return spyedApplicationSession; + } + +} diff --git a/src/test/java/com/openshift/internal/client/ApplicationSSHSessionTest.java b/src/test/java/com/openshift/internal/client/ApplicationSSHSessionTest.java index 88996f70..9d5579d6 100644 --- a/src/test/java/com/openshift/internal/client/ApplicationSSHSessionTest.java +++ b/src/test/java/com/openshift/internal/client/ApplicationSSHSessionTest.java @@ -16,7 +16,7 @@ import static com.openshift.client.utils.Samples.GET_DOMAINS_FOOBARZ_APPLICATIONS_SPRINGEAP6_CARTRIDGES_1EMBEDDED; import static org.fest.assertions.Assertions.assertThat; -import java.util.Arrays; +import java.io.ByteArrayInputStream; import java.util.List; import org.junit.Before; @@ -24,6 +24,7 @@ import org.mockito.Mockito; import com.jcraft.jsch.JSch; +import com.jcraft.jsch.Session; import com.openshift.client.IApplication; import com.openshift.client.IApplicationPortForwarding; import com.openshift.client.IApplicationSSHSession; @@ -54,36 +55,42 @@ public void shouldGetForwardablePorts() throws Throwable { // pre-conditions final IApplication app = domain.getApplicationByName("springeap6"); assertThat(app).isNotNull().isInstanceOf(ApplicationResource.class); - String[] rhcListPortsOutput = new String[] { - "haproxy -> 127.7.233.2:8080", - " haproxy -> 127.7.233.3:8080", - " java -> 127.7.233.1:3528", - " java -> 127.7.233.1:4447", - " java -> 127.7.233.1:5445", - " java -> 127.7.233.1:5455", - " java -> 127.7.233.1:8080", - " java -> 127.7.233.1:9990", - " java -> 127.7.233.1:9999", - " mysql -> 5190d701500446506a0000e4-foobarz.rhcloud.com:56756" }; + String rhcListPortsOutput = + "haproxy -> 127.7.233.2:8080\n" + + " haproxy -> 127.7.233.3:8080\n" + + " java -> 127.7.233.1:3528\n" + + " java -> 127.7.233.1:4447\n" + + " java -> 127.7.233.1:5445\n" + + " java -> 127.7.233.1:5455\n" + + " java -> 127.7.233.1:8080\n" + + " java -> 127.7.233.1:9990\n" + + " java -> 127.7.233.1:9999\n" + + " mysql -> 5190d701500446506a0000e4-foobarz.rhcloud.com:56756"; ApplicationResource spy = Mockito.spy(((ApplicationResource) app)); - JSch jsch = new JSch(); - final IApplicationSSHSession ses = new ApplicationSSHSession(spy, jsch.getSession("mockuser", "mockhost", 22)); - ApplicationSSHSession spyses = Mockito.spy(((ApplicationSSHSession) ses)); - Mockito.doReturn(Arrays.asList(rhcListPortsOutput)).when(spyses) - .sshExecCmd(Mockito.anyString(), (ApplicationSSHSession.SshStreams) Mockito.any()); + final IApplicationSSHSession session = + new ApplicationSSHSession(spy, new JSch().getSession("mockuser", "mockhost", 22)); + ApplicationSSHSession spyedSession = Mockito.spy(((ApplicationSSHSession) session)); + Mockito.doReturn(new ByteArrayInputStream(rhcListPortsOutput.getBytes())) + .when(spyedSession) + .execCommand(Mockito.anyString(), (ApplicationSSHSession.ChannelInputStreams) Mockito.any(), + (Session) Mockito.any()); + Mockito.doReturn(true) + .when(spyedSession) + .isConnected(); // operation - List forwardablePorts = spyses.getForwardablePorts(); + List forwardablePorts = spyedSession.getForwardablePorts(); // verification assertThat(forwardablePorts).isNotEmpty().hasSize(10); assertThat(forwardablePorts) - .onProperty("name").containsExactly("haproxy", "haproxy", "java", "java", "java", "java", "java", - "java", "java", "mysql"); + .onProperty("name") + .containsExactly("haproxy", "haproxy", "java", "java", "java", "java", "java", "java", "java", "mysql"); assertThat(forwardablePorts) - .onProperty("remoteAddress").containsExactly("127.7.233.2", "127.7.233.3", "127.7.233.1", - "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", - "5190d701500446506a0000e4-foobarz.rhcloud.com"); + .onProperty("remoteAddress").containsExactly( + "127.7.233.2", "127.7.233.3", "127.7.233.1", + "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", + "5190d701500446506a0000e4-foobarz.rhcloud.com"); assertThat(forwardablePorts) .onProperty("remotePort").containsExactly(8080, 8080, 3528, 4447, 5445, 5455, 8080, 9990, 9999, 56756); } @@ -93,63 +100,64 @@ public void shouldRefreshForwardablePorts() throws Throwable { // pre-conditions final IApplication app = domain.getApplicationByName("springeap6"); assertThat(app).isNotNull().isInstanceOf(ApplicationResource.class); - String[] rhcListPortsOutput = new String[] { - "haproxy -> 127.7.233.2:8080", - " haproxy -> 127.7.233.3:8080", - " java -> 127.7.233.1:3528", - " java -> 127.7.233.1:4447", - " java -> 127.7.233.1:5445", - " java -> 127.7.233.1:5455", - " java -> 127.7.233.1:8080", - " java -> 127.7.233.1:9990", - " java -> 127.7.233.1:9999", - " mysql -> 5190d701500446506a0000e4-foobarz.rhcloud.com:56756" }; - ApplicationResource spy = Mockito.spy(((ApplicationResource) app)); - JSch jsch = new JSch(); - final IApplicationSSHSession ses = new ApplicationSSHSession(spy, jsch.getSession("mockuser", "mockhost", 22)); - ApplicationSSHSession spyses = Mockito.spy(((ApplicationSSHSession) ses)); - Mockito.doReturn(Arrays.asList(rhcListPortsOutput)).when(spyses) - .sshExecCmd(Mockito.anyString(), (ApplicationSSHSession.SshStreams) Mockito.any()); + String rhcListPortsOutput = + "haproxy -> 127.7.233.2:8080\n" + + " haproxy -> 127.7.233.3:8080\n" + + " java -> 127.7.233.1:3528\n" + + " java -> 127.7.233.1:4447\n" + + " java -> 127.7.233.1:5445\n" + + " java -> 127.7.233.1:5455\n" + + " java -> 127.7.233.1:8080\n" + + " java -> 127.7.233.1:9990\n" + + " java -> 127.7.233.1:9999\n" + + " mysql -> 5190d701500446506a0000e4-foobarz.rhcloud.com:56756"; + ApplicationSSHSessionMockDirector mockDirector = + new ApplicationSSHSessionMockDirector(app).mockGetForwardablePorts(rhcListPortsOutput); // operation - List forwardablePorts = spyses.getForwardablePorts(); + ApplicationSSHSession applicationSession = mockDirector.getMock(); + List forwardablePorts = applicationSession.getForwardablePorts(); // verification assertThat(forwardablePorts).isNotEmpty().hasSize(10); assertThat(forwardablePorts) - .onProperty("name").containsExactly("haproxy", "haproxy", "java", "java", "java", "java", "java", - "java", "java", "mysql"); + .onProperty("name").containsExactly( + "haproxy", "haproxy", "java", "java", "java", "java", "java", "java", "java", "mysql"); assertThat(forwardablePorts) - .onProperty("remoteAddress").containsExactly("127.7.233.2", "127.7.233.3", "127.7.233.1", - "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", - "5190d701500446506a0000e4-foobarz.rhcloud.com"); + .onProperty("remoteAddress").containsExactly( + "127.7.233.2", "127.7.233.3", "127.7.233.1", + "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", "127.7.233.1", + "5190d701500446506a0000e4-foobarz.rhcloud.com"); assertThat(forwardablePorts) - .onProperty("remotePort").containsExactly(8080, 8080, 3528, 4447, 5445, 5455, 8080, 9990, 9999, 56756); + .onProperty("remotePort") + .containsExactly(8080, 8080, 3528, 4447, 5445, 5455, 8080, 9990, 9999, 56756); - String[] rhcListPortsOutputNew = new String[] { - "haproxy -> 127.7.233.2:8080", - " haproxy -> 127.7.233.3:8080", - " java -> 127.7.233.1:3528", - " java -> 127.7.233.1:4447", - " java -> 127.7.233.1:5445", - " mysql -> 5190d701500446506a0000e4-foobarz.rhcloud.com:56756" }; + // pre-conditions + String rhcListPortsOutputNew = + "haproxy -> 127.7.233.2:8080\n" + + " haproxy -> 127.7.233.3:8080\n" + + " java -> 127.7.233.1:3528\n" + + " java -> 127.7.233.1:4447\n" + + " java -> 127.7.233.1:5445\n" + + " mysql -> 5190d701500446506a0000e4-foobarz.rhcloud.com:56756"; - Mockito.doReturn(Arrays.asList(rhcListPortsOutputNew)).when(spyses) - .sshExecCmd(Mockito.anyString(), (ApplicationSSHSession.SshStreams) Mockito.any()); + mockDirector.mockGetForwardablePorts(rhcListPortsOutputNew); // operation - List refreshedForwardablePorts = spyses.refreshForwardablePorts(); + List refreshedForwardablePorts = applicationSession.refreshForwardablePorts(); // verification assertThat(refreshedForwardablePorts).isNotEmpty().hasSize(6); assertThat(refreshedForwardablePorts) .onProperty("name").containsExactly("haproxy", "haproxy", "java", "java", "java", "mysql"); assertThat(refreshedForwardablePorts) - .onProperty("remoteAddress").containsExactly("127.7.233.2", "127.7.233.3", "127.7.233.1", "127.7.233.1", "127.7.233.1", "5190d701500446506a0000e4-foobarz.rhcloud.com"); + .onProperty("remoteAddress") + .containsExactly( + "127.7.233.2", "127.7.233.3", "127.7.233.1", "127.7.233.1", "127.7.233.1", + "5190d701500446506a0000e4-foobarz.rhcloud.com"); assertThat(refreshedForwardablePorts) .onProperty("remotePort").containsExactly(8080, 8080, 3528, 4447, 5445, 56756); - } @Test @@ -157,26 +165,27 @@ public void shouldGetEnvironmentProperties() throws Throwable { // pre-conditions final IApplication app = domain.getApplicationByName("springeap6"); assertThat(app).isNotNull().isInstanceOf(ApplicationResource.class); - String[] environmentProperties = { - "OPENSHIFT_TMP_DIR=/tmp/", - "HOSTNAME=ex-std-node360.prod.rhcloud.com", - "BASH=/bin/bash", - "OPENSHIFT_BROKER_HOST=openshift.redhat.com", - "OPENSHIFT_APP_NAME=springeap6" - }; - ApplicationResource spy = Mockito.spy(((ApplicationResource) app)); - JSch jsch = new JSch(); - final IApplicationSSHSession ses = new ApplicationSSHSession(spy, jsch.getSession("mockuser", "mockhost", 22)); - ApplicationSSHSession spyses = Mockito.spy(((ApplicationSSHSession) ses)); - Mockito.doReturn(Arrays.asList(environmentProperties)).when(spyses) - .sshExecCmd(Mockito.anyString(), (ApplicationSSHSession.SshStreams) Mockito.any()); + String environmentProperties = + "OPENSHIFT_TMP_DIR=/tmp/\n" + + "HOSTNAME=ex-std-node360.prod.rhcloud.com\n" + + "BASH=/bin/bash\n" + + "OPENSHIFT_BROKER_HOST=openshift.redhat.com\n" + + "OPENSHIFT_APP_NAME=springeap6"; + ApplicationSSHSession applicationSession = + new ApplicationSSHSessionMockDirector(app).mockGetEnvironmentProperties(environmentProperties) + .getMock(); // operation - List environmentProperties2 = spyses.getEnvironmentProperties(); + List environmentProperties2 = applicationSession.getEnvironmentProperties(); // verification assertThat(environmentProperties2).isNotEmpty().hasSize(5); - assertThat(Arrays.asList(environmentProperties)) - .containsExactly(environmentProperties2.toArray()); + assertThat(environmentProperties2) + .containsExactly( + "OPENSHIFT_TMP_DIR=/tmp/", + "HOSTNAME=ex-std-node360.prod.rhcloud.com", + "BASH=/bin/bash", + "OPENSHIFT_BROKER_HOST=openshift.redhat.com", + "OPENSHIFT_APP_NAME=springeap6"); } } diff --git a/src/test/java/com/openshift/internal/client/DomainResourceIntegrationTest.java b/src/test/java/com/openshift/internal/client/DomainResourceIntegrationTest.java index e9dd6e59..2c2c95bc 100755 --- a/src/test/java/com/openshift/internal/client/DomainResourceIntegrationTest.java +++ b/src/test/java/com/openshift/internal/client/DomainResourceIntegrationTest.java @@ -285,7 +285,7 @@ public void shouldCreateNonScalableApplicationWithSmallGearAndGitUrl() throws Ex .hasInitialGitUrl(QUICKSTART_REVEALJS_GITURL) .hasEmbeddedCartridges() .hasAlias() - .hasContent(REVEALJS_INDEX, "Reveal.js"); + .pageContains(REVEALJS_INDEX, "Reveal.js"); } @Test diff --git a/src/test/java/com/openshift/internal/client/HttpClientMockDirector.java b/src/test/java/com/openshift/internal/client/HttpClientMockDirector.java index 3b6a2944..0455902c 100644 --- a/src/test/java/com/openshift/internal/client/HttpClientMockDirector.java +++ b/src/test/java/com/openshift/internal/client/HttpClientMockDirector.java @@ -544,7 +544,4 @@ public HttpClientMockDirector mockGetQuickstarts(Samples getQuickstartsResponse) .thenReturn(getQuickstartsResponse.getContentAsString()); return this; } - - - } diff --git a/src/test/java/com/openshift/internal/client/OpenShiftIntegrationTestSuite.java b/src/test/java/com/openshift/internal/client/OpenShiftIntegrationTestSuite.java index 64cb2cf8..c2b877eb 100755 --- a/src/test/java/com/openshift/internal/client/OpenShiftIntegrationTestSuite.java +++ b/src/test/java/com/openshift/internal/client/OpenShiftIntegrationTestSuite.java @@ -18,6 +18,7 @@ APIResourceIntegrationTest.class, LatestVersionQueryIntegrationTest.class, SSHKeyIntegrationTest.class, + ApplicationSSHSessionIntegrationTest.class, UserResourceIntegrationTest.class, DomainResourceIntegrationTest.class, ApplicationResourceIntegrationTest.class, diff --git a/src/test/java/com/openshift/internal/client/SSHKeyIntegrationTest.java b/src/test/java/com/openshift/internal/client/SSHKeyIntegrationTest.java index d0859b0c..22cc7fa6 100644 --- a/src/test/java/com/openshift/internal/client/SSHKeyIntegrationTest.java +++ b/src/test/java/com/openshift/internal/client/SSHKeyIntegrationTest.java @@ -13,23 +13,21 @@ import static com.openshift.client.utils.FileUtils.createRandomTempFile; import static org.fest.assertions.Assertions.assertThat; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.SocketTimeoutException; import java.util.List; import org.junit.Before; import org.junit.Test; -import com.jcraft.jsch.JSchException; import com.openshift.client.IOpenShiftSSHKey; import com.openshift.client.ISSHPublicKey; import com.openshift.client.IUser; -import com.openshift.client.OpenShiftException; +import com.openshift.client.OpenShiftEndpointException; +import com.openshift.client.OpenShiftSSHKeyException; import com.openshift.client.SSHKeyPair; import com.openshift.client.SSHKeyType; import com.openshift.client.SSHPublicKey; import com.openshift.client.utils.SSHKeyTestUtils; +import com.openshift.client.utils.SSHPublicKeyAssertion; import com.openshift.client.utils.TestConnectionFactory; import com.openshift.internal.client.httpclient.HttpClientException; @@ -41,7 +39,7 @@ public class SSHKeyIntegrationTest extends TestTimer { private IUser user; @Before - public void setUp() throws FileNotFoundException, IOException, OpenShiftException { + public void setUp() throws Exception { this.user = new TestConnectionFactory().getConnection().getUser(); } @@ -55,7 +53,7 @@ public void shouldReturnExistingKeys() throws HttpClientException, Throwable { } @Test - public void shouldAddKey() throws SocketTimeoutException, HttpClientException, Throwable { + public void shouldAddKey() throws Exception { IOpenShiftSSHKey key = null; try { // pre-conditions @@ -65,11 +63,11 @@ public void shouldAddKey() throws SocketTimeoutException, HttpClientException, T // operation String keyName = SSHKeyTestUtils.createRandomKeyName(); - key = user.putSSHKey(keyName, publicKey); + key = user.addSSHKey(keyName, publicKey); // verifications assertThat( - new SSHKeyTestUtils.SSHPublicKeyAssertion(key)) + new SSHPublicKeyAssertion(key)) .hasName(keyName) .hasPublicKey(publicKey.getPublicKey()) .isType(publicKey.getKeyType()); @@ -82,8 +80,44 @@ public void shouldAddKey() throws SocketTimeoutException, HttpClientException, T } } + @Test(expected=OpenShiftSSHKeyException.class) + public void shouldNotAddKeyTwice() throws Exception { + IOpenShiftSSHKey key = null; + try { + // pre-conditions + String keyName = SSHKeyTestUtils.createRandomKeyName(); + ISSHPublicKey publicKey = new SSHPublicKey(SSHKeyTestUtils.createDsaKeyPair()); + key = user.addSSHKey(keyName, publicKey); + + // operation + key = user.addSSHKey(keyName, publicKey); + + // verifications + } finally { + SSHKeyTestUtils.silentlyDestroyKey(key); + } + } + + @Test(expected=OpenShiftEndpointException.class) + public void shouldNotPutKeyTwice() throws Exception { + IOpenShiftSSHKey key = null; + try { + // pre-conditions + String keyName = SSHKeyTestUtils.createRandomKeyName(); + ISSHPublicKey publicKey = new SSHPublicKey(SSHKeyTestUtils.createDsaKeyPair()); + key = user.putSSHKey(keyName, publicKey); + + // operation + key = user.putSSHKey(keyName, publicKey); + + // verifications + } finally { + SSHKeyTestUtils.silentlyDestroyKey(key); + } + } + @Test - public void shouldUpdatePublicKey() throws SocketTimeoutException, HttpClientException, Throwable { + public void shouldUpdatePublicKey() throws Exception { IOpenShiftSSHKey key = null; try { // pre-conditions @@ -95,7 +129,7 @@ public void shouldUpdatePublicKey() throws SocketTimeoutException, HttpClientExc privateKeyPath, publicKeyPath); String keyName = SSHKeyTestUtils.createRandomKeyName(); - key = user.putSSHKey(keyName, keyPair); + key = user.addSSHKey(keyName, keyPair); // operation String publicKey = SSHKeyPair.create( @@ -109,7 +143,7 @@ public void shouldUpdatePublicKey() throws SocketTimeoutException, HttpClientExc assertThat(key.getPublicKey()).isEqualTo(publicKey); IOpenShiftSSHKey openshiftKey = user.getSSHKeyByName(keyName); assertThat( - new SSHKeyTestUtils.SSHPublicKeyAssertion(openshiftKey)) + new SSHPublicKeyAssertion(openshiftKey)) .hasName(keyName) .hasPublicKey(publicKey) .isType(openshiftKey.getKeyType()); @@ -120,7 +154,7 @@ public void shouldUpdatePublicKey() throws SocketTimeoutException, HttpClientExc } @Test - public void shouldReturnKeyForName() throws SocketTimeoutException, HttpClientException, Throwable { + public void shouldReturnKeyForName() throws Exception { IOpenShiftSSHKey key = null; try { // pre-conditions @@ -129,7 +163,7 @@ public void shouldReturnKeyForName() throws SocketTimeoutException, HttpClientEx // operation String keyName = SSHKeyTestUtils.createRandomKeyName(); - key = user.putSSHKey(keyName, publicKey); + key = user.addSSHKey(keyName, publicKey); IOpenShiftSSHKey keyByName = user.getSSHKeyByName(keyName); // verifications @@ -140,7 +174,7 @@ public void shouldReturnKeyForName() throws SocketTimeoutException, HttpClientEx } @Test - public void shouldReturnKeyForPublicKey() throws SocketTimeoutException, HttpClientException, Throwable { + public void shouldReturnKeyForPublicKey() throws Exception { IOpenShiftSSHKey key = null; try { // pre-conditions @@ -149,7 +183,7 @@ public void shouldReturnKeyForPublicKey() throws SocketTimeoutException, HttpCli // operation String keyName = SSHKeyTestUtils.createRandomKeyName(); - key = user.putSSHKey(keyName, publicKey); + key = user.addSSHKey(keyName, publicKey); IOpenShiftSSHKey keyByPublicKey = user.getSSHKeyByPublicKey(publicKey.getPublicKey()); // verifications @@ -161,7 +195,7 @@ public void shouldReturnKeyForPublicKey() throws SocketTimeoutException, HttpCli } @Test - public void shouldUpdateKeyTypeAndPublicKey() throws SocketTimeoutException, HttpClientException, Throwable { + public void shouldUpdateKeyTypeAndPublicKey() throws Exception { IOpenShiftSSHKey key = null; try { // pre-conditions @@ -171,7 +205,7 @@ public void shouldUpdateKeyTypeAndPublicKey() throws SocketTimeoutException, Htt ISSHPublicKey publicKey = new SSHPublicKey(publicKeyPath); assertThat(publicKey.getKeyType()).isEqualTo(SSHKeyType.SSH_DSA); String keyName = SSHKeyTestUtils.createRandomKeyName(); - key = user.putSSHKey(keyName, publicKey); + key = user.addSSHKey(keyName, publicKey); SSHKeyPair keyPair = SSHKeyPair.create( SSHKeyType.SSH_RSA, SSHKeyTestUtils.DEFAULT_PASSPHRASE, privateKeyPath, publicKeyPath); @@ -187,15 +221,13 @@ public void shouldUpdateKeyTypeAndPublicKey() throws SocketTimeoutException, Htt } @Test - public void shouldRemoveKey() throws IOException, JSchException, OpenShiftException { + public void shouldDestroyKey() throws Exception { IOpenShiftSSHKey key = null; try { // pre-conditions - String publicKeyPath = createRandomTempFile().getAbsolutePath(); - String privateKeyPath = createRandomTempFile().getAbsolutePath(); - SSHKeyTestUtils.createDsaKeyPair(publicKeyPath, privateKeyPath); + String publicKeyPath = SSHKeyTestUtils.createDsaKeyPair(); String keyName = SSHKeyTestUtils.createRandomKeyName(); - key = user.putSSHKey(keyName, new SSHPublicKey(publicKeyPath)); + key = user.addSSHKey(keyName, new SSHPublicKey(publicKeyPath)); // operation key.destroy(); @@ -209,15 +241,13 @@ public void shouldRemoveKey() throws IOException, JSchException, OpenShiftExcept } @Test - public void shouldRemoveKeybyName() throws IOException, JSchException, OpenShiftException { + public void shouldRemoveKeyByName() throws Exception { IOpenShiftSSHKey key = null; try { // pre-conditions - String publicKeyPath = createRandomTempFile().getAbsolutePath(); - String privateKeyPath = createRandomTempFile().getAbsolutePath(); - SSHKeyTestUtils.createDsaKeyPair(publicKeyPath, privateKeyPath); + String publicKeyPath = SSHKeyTestUtils.createDsaKeyPair(); String keyName = SSHKeyTestUtils.createRandomKeyName(); - key = user.putSSHKey(keyName, new SSHPublicKey(publicKeyPath)); + key = user.addSSHKey(keyName, new SSHPublicKey(publicKeyPath)); int numOfKeys = user.getSSHKeys().size(); // operation @@ -231,4 +261,26 @@ public void shouldRemoveKeybyName() throws IOException, JSchException, OpenShift } } + @Test + public void shouldRefreshKeys() throws Exception { + IOpenShiftSSHKey key = null; + int originalNumOfKeys = user.getSSHKeys().size(); + try { + // pre-conditions + String publicKeyPath = SSHKeyTestUtils.createDsaKeyPair(); + IUser user = new TestConnectionFactory().getConnection().getUser(); + + // operation + int newNumOfKeys = user.getSSHKeys().size(); + assertThat(user.getSSHKeys().size()).isEqualTo(originalNumOfKeys); + String newKeyName = SSHKeyTestUtils.createRandomKeyName(); + user.addSSHKey(newKeyName, new SSHPublicKey(publicKeyPath)); + newNumOfKeys = user.getSSHKeys().size(); + + // verification + assertThat(newNumOfKeys).isEqualTo(originalNumOfKeys + 1); + } finally { + SSHKeyTestUtils.silentlyDestroyKey(key); + } + } } diff --git a/src/test/java/com/openshift/internal/client/SSHKeyTest.java b/src/test/java/com/openshift/internal/client/SSHKeyTest.java index 226e13aa..519d1176 100644 --- a/src/test/java/com/openshift/internal/client/SSHKeyTest.java +++ b/src/test/java/com/openshift/internal/client/SSHKeyTest.java @@ -34,7 +34,7 @@ import com.openshift.client.SSHKeyType; import com.openshift.client.SSHPublicKey; import com.openshift.client.utils.SSHKeyTestUtils; -import com.openshift.client.utils.SSHKeyTestUtils.SSHPublicKeyAssertion; +import com.openshift.client.utils.SSHPublicKeyAssertion; import com.openshift.client.utils.Samples; import com.openshift.client.utils.TestConnectionFactory; import com.openshift.internal.client.httpclient.HttpClientException; @@ -203,7 +203,7 @@ public void shouldAddAndUpdateKey() throws SocketTimeoutException, HttpClientExc String keyName = "somekey"; // operation - user.putSSHKey(keyName, publicKey); + user.addSSHKey(keyName, publicKey); mockDirector.mockGetKeys(Samples.GET_USER_KEYS_1KEY); // verifications @@ -284,7 +284,7 @@ public void shouldNotAddKeyWithExistingName() throws SocketTimeoutException, Htt // operation assertThat(user.getSSHKeys()).hasSize(1); String existingKeyName = user.getSSHKeys().get(0).getName(); - user.putSSHKey(existingKeyName, publicKey); + user.addSSHKey(existingKeyName, publicKey); } @Test(expected = OpenShiftSSHKeyException.class) @@ -301,7 +301,7 @@ public void shouldNotAddKeyTwice() throws SocketTimeoutException, HttpClientExce // operation assertThat(user.getSSHKeys()).onProperty("name").contains(keyName); - user.putSSHKey(keyName, publicKey); // throws + user.addSSHKey(keyName, publicKey); // throws } }