package jp.co.worksap.workspace.wasinstall; import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import java.util.List; import jp.co.worksap.workspace.common.OperatingSystem; import jp.co.worksap.workspace.common.PipingDaemon; import jp.co.worksap.workspace.common.UnArchiver; import jp.co.worksap.workspace.common.download.AuthenticationInfoProvider; import jp.co.worksap.workspace.common.download.Downloader; import lombok.extern.slf4j.Slf4j; import com.google.common.io.Files; import com.google.common.io.Resources; @Slf4j public class WASInstaller { public void install(WASInstallConfiguration configuration, AuthenticationInfoProvider infoProvider) { // TODO check if already exists and if yes than do I install update // packages? try { URL downloadUrl = configuration.getUrlToDownload(); File downloadedFile = File.createTempFile("was", ".download"); Downloader downloader = Downloader.createFor(downloadUrl, infoProvider); downloader.download(downloadUrl, downloadedFile); // downloading and installing WAS if (wasExists(configuration)) { log.info("WAS already exists at install location."); } else { downloader.download(downloadUrl, downloadedFile); unpack(downloadedFile); setup(configuration, downloadedFile.getParentFile(), "WAS"); } if (!configuration.getUpdatePackages().isEmpty()) { // downloading and installing UpdateInstaller if (wasUpdaterExists(configuration)) { log.info("WAS update installer already exists."); } else { downloadUrl = configuration.getUpdateInstallerUrlToDownload(); downloader.download(downloadUrl, downloadedFile); unpack(downloadedFile); setup(configuration, downloadedFile.getParentFile(), "UpdateInstaller"); } StringBuilder packages = new StringBuilder(); // downloading and installing update packages for (UpdatePackage updatePack : updatePackageToInstall(configuration)) { downloadUrl = updatePack.getUrlToDownload(); downloadedFile = File.createTempFile("was", ".pak"); downloader.download(downloadUrl, downloadedFile); packages.append(downloadedFile.getAbsolutePath() + ";"); } update(configuration, packages.toString()); } } catch (IOException e) { throw new IllegalStateException(e); } } private void unpack(File downloadedFile) { try { log.info("Starting unpacking..."); new UnArchiver().extract(downloadedFile, downloadedFile.getParentFile()); } finally { log.info("Unpacking completed..."); } } private void setup(WASInstallConfiguration configuration, File location, String product) { try { OperatingSystem os = OperatingSystem.create(); String setupPath = location.getAbsolutePath() + "/" + product + "/" + os.appendExtensionTo("install"); File rspFile = File.createTempFile(product, ".rsp"); Resources.copy(WASInstaller.class.getResource(product + ".rsp"), Files.asByteSink(rspFile).openStream()); FileWriter rspFileWriter = new FileWriter(rspFile, true); rspFileWriter.write("\n-OPT installLocation=\"" + configuration.getInstallLocation() + "\\"); if (product.equals("WAS")) { rspFileWriter.write("AppServer\\\""); } else { rspFileWriter.write(product + "\""); } rspFileWriter.flush(); ProcessBuilder builder = new ProcessBuilder(setupPath, "-options", rspFile.getAbsolutePath(), "-silent"); log.info("execute command ({}) to install " + product, builder.command()); Process process = builder.start(); try { recordStdoutOf(process); recordStderrOf(process); process.getOutputStream().close(); int statusCode = process.waitFor(); if (statusCode != 0) { throw new IllegalArgumentException("Failed to install " + product + ", status code is " + statusCode); } } catch (InterruptedException e) { throw new IllegalStateException(e); } finally { process.destroy(); rspFileWriter.close(); } } catch (IOException e) { throw new IllegalStateException(e); } } private void update(WASInstallConfiguration configuration, String packages) { try { OperatingSystem os = OperatingSystem.create(); String setupPath = "\"" + configuration.getInstallLocation() + "\\UpdateInstaller\\" + os.appendExtensionTo("update") + "\""; File rspFile = File.createTempFile("WAS.update", ".rsp"); FileWriter rspFileWriter = new FileWriter(rspFile, true); rspFileWriter.write("\n-W product.location=\"" + configuration.getInstallLocation() + "\\AppServer\\\""); rspFileWriter.write("\n-W maintenance.package=\"" + packages + "\""); rspFileWriter.write("\n-W update.type=\"install\""); rspFileWriter.flush(); ProcessBuilder builder = new ProcessBuilder(setupPath, "-options", rspFile.getAbsolutePath(), "-silent"); log.info("execute command ({}) to install update packages", builder.command()); Process process = builder.start(); try { recordStdoutOf(process); recordStderrOf(process); process.getOutputStream().close(); int statusCode = process.waitFor(); if (statusCode != 0) { throw new IllegalArgumentException("Failed to install update packages, status code is " + statusCode); } } catch (InterruptedException e) { throw new IllegalStateException(e); } finally { process.destroy(); rspFileWriter.close(); } } catch (IOException e) { throw new IllegalStateException(e); } } private void recordStdoutOf(final Process process) throws IOException { Thread daemon = PipingDaemon.createThread(process.getInputStream(), "Websphere Install", "stdout"); daemon.start(); } private void recordStderrOf(final Process process) throws IOException { Thread daemon = PipingDaemon.createThread(process.getErrorStream(), "Websphere Install", "stderr"); daemon.start(); } private boolean wasExists(WASInstallConfiguration configuration) { return new File(configuration.getInstallLocation(), "AppServer").exists(); } private boolean wasUpdaterExists(WASInstallConfiguration configuration) { return new File(configuration.getInstallLocation(), "UpdateInstaller").exists(); } private List<UpdatePackage> updatePackageToInstall(WASInstallConfiguration configuration) { List<UpdatePackage> packages = new ArrayList<UpdatePackage>(); List<String> installedPackages = new ArrayList<String>(); try { String setupPath = "\"" + configuration.getInstallLocation() + "\\UpdateInstaller\\bin\\installRegistryUtils.bat\""; ProcessBuilder builder = new ProcessBuilder(setupPath, "-listPackages"); log.info("execute command ({}) to list update packages", builder.command()); Process process = builder.start(); try { process.getOutputStream().close(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = bufferedReader.readLine()) != null) { line = line.toLowerCase(); if (line.contains("package name")){ installedPackages.add(line.replace("package name", "").trim()); } } int statusCode = process.waitFor(); if (statusCode != 0) { throw new IllegalArgumentException("Failed to list packages, status code is " + statusCode); } } catch (InterruptedException | IOException e) { throw new IllegalStateException(e); } finally { process.destroy(); } } catch (IOException e) { throw new IllegalStateException(e); } for (UpdatePackage updatePackage : configuration.getUpdatePackages()) { if (!installedPackages.contains(updatePackage.getName().toLowerCase())) { packages.add(updatePackage); } } return packages; } }