com.sixsq.slipstream.DeploymentController.java Source code

Java tutorial

Introduction

Here is the source code for com.sixsq.slipstream.DeploymentController.java

Source

/*
 * Copyright 2012 SixSq Sarl
 *
 * 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.sixsq.slipstream;

import static javax.xml.xpath.XPathConstants.STRING;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.xml.sax.InputSource;

public class DeploymentController implements Closeable {

    private URI serverUri;
    private String username;
    private String password;

    private DefaultHttpClient client;

    private static final int BUFFER_SIZE = 1024;

    private static final String STATUS_ATTRS = "concat(//run/@state, ',',  //run/@status)";

    public DeploymentController(URI serverUri, String username, String password) {
        this.serverUri = serverUri;
        this.username = username;
        this.password = password;

        client = new DefaultHttpClient();
    }

    public void checkServerResponds() throws MojoExecutionException {
        checkValidResponse(serverUri);
    }

    public void verifyModuleExists(String module) throws MojoExecutionException {
        URI moduleUri = relativeURI("module/" + module);
        checkValidResponse(moduleUri);
    }

    public void checkLogin() throws MojoExecutionException {
        URI moduleUri = relativeURI("module");
        checkValidResponse(moduleUri);
    }

    public URI runModule(String module) throws MojoExecutionException {

        try {
            URI postUri = relativeURI("run");

            HttpPost httppost = new HttpPost(postUri);

            List<NameValuePair> formInfo = new ArrayList<NameValuePair>();
            formInfo.add(new BasicNameValuePair("refqname", module));

            httppost.setEntity(new UrlEncodedFormEntity(formInfo, HTTP.UTF_8));

            HttpResponse response = client.execute(httppost);
            HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);

            Header location = response.getFirstHeader("location");
            if (location == null) {
                throw new MojoExecutionException("running module failed; no redirect given");
            }

            URI runUri = new URI(location.getValue());

            return runUri;

        } catch (IOException e) {
            throw new MojoExecutionException("IO exception when trying to contact server", e);
        } catch (URISyntaxException e) {
            throw new MojoExecutionException("invalid URI syntax", e);
        }
    }

    public List<URI> getReports(URI runUri) throws MojoExecutionException {

        try {

            String runUriString = runUri.toString();
            String reportsUriString = runUriString.replaceFirst("/run/", "/reports/");
            URI reportsUri = new URI(reportsUriString);

            String uriList = getResource(reportsUri, "text/uri-list");

            List<URI> reportUris = new ArrayList<URI>();

            StringReader sreader = new StringReader(uriList);
            BufferedReader reader = new BufferedReader(sreader);
            String line;
            while ((line = reader.readLine()) != null) {
                if (!line.startsWith("#")) {
                    reportUris.add(new URI(line));
                }
            }

            return reportUris;

        } catch (IOException e) {
            throw new MojoExecutionException("IO exception when trying to contact server", e);
        } catch (URISyntaxException e) {
            throw new MojoExecutionException("invalid URI syntax", e);
        }
    }

    public String getResource(URI uri, String accept) throws MojoExecutionException {

        String acceptValue = accept;
        if (acceptValue == null) {
            acceptValue = "application/xml";
        }

        try {

            HttpGet httpget = new HttpGet(uri);

            Header acceptHeader = new BasicHeader("accept", acceptValue);
            httpget.addHeader(acceptHeader);

            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            return client.execute(httpget, responseHandler);

        } catch (IOException e) {
            String fmt = "error using GET to access %s for representation(s) %s";
            String msg = String.format(fmt, uri.toString(), accept);
            throw new MojoExecutionException(msg, e);
        }
    }

    public void login() throws MojoExecutionException {

        try {

            URI loginUri = relativeURI("login");

            HttpPost httppost = new HttpPost(loginUri);

            List<NameValuePair> formInfo = new ArrayList<NameValuePair>();
            formInfo.add(new BasicNameValuePair("username", username));
            formInfo.add(new BasicNameValuePair("password", password));

            httppost.setEntity(new UrlEncodedFormEntity(formInfo, HTTP.UTF_8));

            int cookiesBefore = client.getCookieStore().getCookies().size();

            HttpResponse response = client.execute(httppost);
            HttpEntity entity = response.getEntity();

            EntityUtils.consume(entity);

            int cookiesAfter = client.getCookieStore().getCookies().size();

            if (cookiesAfter - cookiesBefore <= 0) {
                throw new MojoExecutionException("login failed; authorization cookie NOT set in client");
            }

        } catch (MalformedURLException e) {
            throw new MojoExecutionException("invalid login URI", e);
        } catch (UnsupportedEncodingException e) {
            throw new MojoExecutionException("internal error during login", e);
        } catch (ClientProtocolException e) {
            throw new MojoExecutionException("client protocol exception during login", e);
        } catch (IOException e) {
            throw new MojoExecutionException("IO exception during login", e);
        }

    }

    private void checkValidResponse(URI uri) throws MojoExecutionException {

        String responseBody = getResource(uri, "text/html");
        if ("".equals(responseBody) || responseBody == null) {
            String fmt = "server (%s) responded with empty or null response";
            String msg = String.format(fmt, uri);
            throw new MojoExecutionException(msg);
        }
    }

    public String[] getRunStatus(URI uri) throws MojoExecutionException {
        String status = getResource(uri, "application/xml");
        return extractRunStatusAndState(status);
    }

    public File downloadFile(URI uri, File dir) throws MojoExecutionException {

        String path = uri.getPath();
        Pattern pattern = Pattern.compile(".*/(.*)");
        Matcher matcher = pattern.matcher(path);
        String filename = "";
        if (matcher.matches()) {
            filename = matcher.group(1);
        }

        File file = new File(dir, filename);

        InputStream is = null;
        FileOutputStream out = null;

        try {

            HttpGet httpget = new HttpGet(uri);
            HttpResponse response = client.execute(httpget);
            HttpEntity entity = response.getEntity();

            is = entity.getContent();
            out = new FileOutputStream(file);

            byte[] buffer = new byte[BUFFER_SIZE];
            int count = -1;
            while ((count = is.read(buffer)) != -1) {
                out.write(buffer, 0, count);
            }
            out.flush();
            out.close();
        } catch (IOException e) {
            String msg = "error writing file " + uri.toString();
            throw new MojoExecutionException(msg, e);
        } finally {
            closeReliably(is);
            closeReliably(out);
        }

        return file;
    }

    public void close() throws IOException {
        if (client != null) {
            client.getConnectionManager().shutdown();
        }
    }

    public URI relativeURI(String relativePath) throws MojoExecutionException {

        try {

            URL url = new URL(serverUri.toURL(), relativePath);
            return url.toURI();

        } catch (MalformedURLException e) {
            String fmt = "cannot create valid URI from %s and %s";
            String msg = String.format(fmt, serverUri.toString(), relativePath);
            throw new MojoExecutionException(msg, e);
        } catch (URISyntaxException e) {
            String fmt = "cannot create valid URI from %s and %s";
            String msg = String.format(fmt, serverUri.toString(), relativePath);
            throw new MojoExecutionException(msg, e);
        }
    }

    private String[] extractRunStatusAndState(String xml) {

        try {

            InputSource xmlSource = new InputSource(new StringReader(xml));

            XPathFactory xpfactory = XPathFactory.newInstance();
            XPath xpath = xpfactory.newXPath();
            Object result = xpath.evaluate(STATUS_ATTRS, xmlSource, STRING);
            String data = result.toString();
            return data.split(",");

        } catch (XPathExpressionException consumed) {
            return new String[] { "", "" };
        }
    }

    private void closeReliably(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException consumed) {

            }
        }
    }

}