Package org.apache.sling.ide.osgi.impl

Source Code of org.apache.sling.ide.osgi.impl.HttpOsgiClient$LocalBundleInstaller

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.sling.ide.osgi.impl;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.PartSource;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.io.IOUtils;
import org.apache.sling.ide.osgi.OsgiClient;
import org.apache.sling.ide.osgi.OsgiClientException;
import org.apache.sling.ide.transport.RepositoryInfo;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.osgi.framework.Version;

public class HttpOsgiClient implements OsgiClient {

    private static final int DEFAULT_SOCKET_TIMEOUT_SECONDS = 30;
    private static final int DEFAULT_CONNECT_TIMEOUT_SECONDS = 30;

    private RepositoryInfo repositoryInfo;

    public HttpOsgiClient(RepositoryInfo repositoryInfo) {

        this.repositoryInfo = repositoryInfo;
    }

    @Override
    public Version getBundleVersion(String bundleSymbolicName) throws OsgiClientException {

        GetMethod method = new GetMethod(repositoryInfo.getUrl() + "system/console/bundles.json");
        HttpClient client = getHttpClient();
        InputStream input = null;

        try {
            int result = client.executeMethod(method);
            if (result != HttpStatus.SC_OK) {
                throw new HttpException("Got status code " + result + " for call to " + method.getURI());
            }

            input = method.getResponseBodyAsStream();

            JSONObject object = new JSONObject(new JSONTokener(new InputStreamReader(input)));

            JSONArray bundleData = object.getJSONArray("data");
            for (int i = 0; i < bundleData.length(); i++) {
                JSONObject bundle = bundleData.getJSONObject(i);
                String remotebundleSymbolicName = bundle.getString("symbolicName");
                Version bundleVersion = new Version(bundle.getString("version"));

                if (bundleSymbolicName.equals(remotebundleSymbolicName)) {
                    return bundleVersion;
                }
            }

            return null;
        } catch (HttpException e) {
            throw new OsgiClientException(e);
        } catch (IOException e) {
            throw new OsgiClientException(e);
        } catch (JSONException e) {
            throw new OsgiClientException(e);
        } finally {
            IOUtils.closeQuietly(input);
            method.releaseConnection();
        }
    }

    private HttpClient getHttpClient() {

        HttpClient client = new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(DEFAULT_CONNECT_TIMEOUT_SECONDS * 1000);
        client.getHttpConnectionManager().getParams().setSoTimeout(DEFAULT_SOCKET_TIMEOUT_SECONDS * 1000);
        client.getParams().setAuthenticationPreemptive(true);
        Credentials defaultcreds = new UsernamePasswordCredentials(repositoryInfo.getUsername(),
                repositoryInfo.getPassword());
        client.getState().setCredentials(
                new AuthScope(repositoryInfo.getHost(), repositoryInfo.getPort(), AuthScope.ANY_REALM), defaultcreds);
        return client;
    }

    @Override
    public void installBundle(InputStream in, String fileName) throws OsgiClientException {

        if (in == null) {
            throw new IllegalArgumentException("in may not be null");
        }

        if (fileName == null) {
            throw new IllegalArgumentException("fileName may not be null");
        }

        // append pseudo path after root URL to not get redirected for nothing
        final PostMethod filePost = new PostMethod(repositoryInfo.getUrl()+"system/console/install");

        try {
            // set referrer
            filePost.setRequestHeader("referer", "about:blank");

            List<Part> partList = new ArrayList<Part>();
            partList.add(new StringPart("action", "install"));
            partList.add(new StringPart("_noredir_", "_noredir_"));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            IOUtils.copy(in, baos);
            PartSource partSource = new ByteArrayPartSource(fileName, baos.toByteArray());
            partList.add(new FilePart("bundlefile", partSource));
            partList.add(new StringPart("bundlestart", "start"));

            Part[] parts = partList.toArray(new Part[partList.size()]);

            filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));

            int status = getHttpClient().executeMethod(filePost);
            if (status != 200) {
                throw new OsgiClientException("Method execution returned status " + status);
            }
        } catch (IOException e) {
            throw new OsgiClientException(e);
        } finally {
            filePost.releaseConnection();
        }
    }

    @Override
    public void installLocalBundle(final String explodedBundleLocation) throws OsgiClientException {

        if (explodedBundleLocation == null) {
            throw new IllegalArgumentException("explodedBundleLocation may not be null");
        }

        new LocalBundleInstaller(getHttpClient(), repositoryInfo) {

            @Override
            void configureRequest(PostMethod method) {
                method.addParameter("dir", explodedBundleLocation);
            }
        }.installBundle();
    }

    @Override
    public void installLocalBundle(final InputStream jarredBundle, String sourceLocation) throws OsgiClientException {

        if (jarredBundle == null) {
            throw new IllegalArgumentException("jarredBundle may not be null");
        }
       
        new LocalBundleInstaller(getHttpClient(), repositoryInfo) {

            @Override
            void configureRequest(PostMethod method) throws IOException {

                Part[] parts = new Part[] { new FilePart("bundle", new ByteArrayPartSource("bundle.jar",
                        IOUtils.toByteArray(jarredBundle))) };
                method.setRequestEntity(new MultipartRequestEntity(parts, method.getParams()));
            }
        }.installBundle();       
    }

    static abstract class LocalBundleInstaller {

        private final HttpClient httpClient;
        private final RepositoryInfo repositoryInfo;

        public LocalBundleInstaller(HttpClient httpClient, RepositoryInfo repositoryInfo) {
            this.httpClient = httpClient;
            this.repositoryInfo = repositoryInfo;
        }

        void installBundle() throws OsgiClientException {

            PostMethod method = new PostMethod(repositoryInfo.getUrl() + "system/sling/tooling/install");

            try {
                configureRequest(method);

                int status = httpClient.executeMethod(method);
                if (status != 200) {
                    try {
                        JSONObject result = parseResult(method);
                        if (result.has("message")) {
                            throw new OsgiClientException(result.getString("message"));
                        }
                    } catch (JSONException e) {
                        // ignore, fallback to status code reporting
                    }
                    throw new OsgiClientException("Method execution returned status " + status);
                }

                JSONObject obj = parseResult(method);

                if ("OK".equals(obj.getString("status"))) {
                    return;
                }

                String errorMessage = obj.has("message") ? "Bundle deployment failed, please check the Sling logs"
                        : obj.getString("message");

                throw new OsgiClientException(errorMessage);

            } catch (IOException e) {
                throw new OsgiClientException(e);
            } catch (JSONException e) {
                throw new OsgiClientException(
                        "Response is not valid JSON. The InstallServlet is probably not installed at the expected location",
                        e);
            } finally {
                method.releaseConnection();
            }
        }

        private JSONObject parseResult(PostMethod method) throws IOException, JSONException {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            IOUtils.copy(method.getResponseBodyAsStream(), out);

            return new JSONObject(new String(out.toByteArray(), "UTF-8"));
        }

        abstract void configureRequest(PostMethod method) throws IOException;
    }
}
TOP

Related Classes of org.apache.sling.ide.osgi.impl.HttpOsgiClient$LocalBundleInstaller

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.