/* * Copyright (c) 2013-2017 Cinchapi Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cinchapi.concourse.util; import java.io.File; import java.io.FileOutputStream; import java.net.URI; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.file.Files; import java.nio.file.Paths; import java.text.MessageFormat; import java.util.Iterator; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Throwables; /** * A utility class that can download Concourse Server binaries from Github. * * @author jnelson */ public final class ConcourseServerDownloader { /** * Download the Concourse Server binary of the specified {@code version} to * the user's home directory. * * @param version * @return the absolute path to the downloaded file */ public static String download(String version) { return download(version, System.getProperty("user.home")); } /** * Download the Concourse Server binary of the specified {@code version} to * the * specified {@code location}. * * @param version * @param location * @return the absolute path to the downloaded file */ public static String download(String version, String location) { String file = location + File.separator + "concourse-server-" + version + ".bin"; if(!Files.exists(Paths.get(file))) { log.info(MessageFormat.format("Did not find an installer for " + "ConcourseServer v{0} in {1}", version, location)); URL url; try (FileOutputStream stream = new FileOutputStream(file)) { url = new URI(getDownloadUrl(version)).toURL(); ReadableByteChannel channel = Channels.newChannel(url .openStream()); stream.getChannel().transferFrom(channel, 0, Long.MAX_VALUE); log.info(MessageFormat.format("Downloaded the installer for " + "Concourse Server v{0} from {1}. The installer is " + "stored in {2}", version, url.toString(), location)); } catch (Exception e) { throw Throwables.propagate(e); } } return file; } /** * Return the download URL for the specified {@code version} of Concourse * Server. * * @param version * @return the download URL */ private static String getDownloadUrl(String version) { String page = RELEASE_PAGE_URL_BASE + version; try { Document doc = Jsoup.parse(new URI(page).toURL(), 10000); Elements links = doc.select("a[href]"); Iterator<Element> it = links.iterator(); while (it.hasNext()) { Element element = it.next(); String url = element.attr("href"); if(url.endsWith(".bin")) { return DOWNLOAD_URL_BASE + url; } } throw new Exception("Could not determine download URL for version " + version); } catch (Exception e) { throw Throwables.propagate(e); } } /** * The base Github URL for the release page. */ private static final String RELEASE_PAGE_URL_BASE = "https://github.com/cinchapi/concourse/releases/tag/v"; /** * The base Github URL for the download page. */ private static final String DOWNLOAD_URL_BASE = "https://github.com"; // ---logger private static final Logger log = LoggerFactory .getLogger(ConcourseServerDownloader.class); private ConcourseServerDownloader() {} }