You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2013/10/22 16:45:18 UTC

svn commit: r1534649 - in /sling/trunk/tooling/ide: api/src/org/apache/sling/ide/osgi/ api/src/org/apache/sling/ide/osgi/impl/ eclipse-core/src/org/apache/sling/ide/eclipse/core/ eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/ eclipse-ui/s...

Author: rombert
Date: Tue Oct 22 14:45:17 2013
New Revision: 1534649

URL: http://svn.apache.org/r1534649
Log:
SLING-3134 - Bundle deployment mechanism does not deploy on the
configured server

With the latest fixes for SLING-3019, we no longer need to use Maven to
deploy bundles. Therefore we now pick up the directory and create a jar
file out of it.

This is faster and less error-prone than building and invoking maven
launch configurations.

Added:
    sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/JarBuilder.java   (with props)
Removed:
    sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/MavenLaunchHelper.java
Modified:
    sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/OsgiClient.java
    sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/impl/HttpOsgiClient.java
    sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/impl/TracingOsgiClient.java
    sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/InstallEditorSection.java

Modified: sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/OsgiClient.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/OsgiClient.java?rev=1534649&r1=1534648&r2=1534649&view=diff
==============================================================================
--- sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/OsgiClient.java (original)
+++ sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/OsgiClient.java Tue Oct 22 14:45:17 2013
@@ -42,4 +42,14 @@ public interface OsgiClient {
      */
     void installLocalBundle(String explodedBundleLocation) throws OsgiClientException;
 
+    /**
+     * Installs a local bundle from an already-built jar file
+     * 
+     * @param jarredBundle the contents of the jarred bundle
+     * @param sourceLocation the source location, for informative purposes only
+     * 
+     * @throws OsgiClientException
+     */
+    void installLocalBundle(InputStream jarredBundle, String sourceLocation) throws OsgiClientException;
+
 }
\ No newline at end of file

Modified: sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/impl/HttpOsgiClient.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/impl/HttpOsgiClient.java?rev=1534649&r1=1534648&r2=1534649&view=diff
==============================================================================
--- sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/impl/HttpOsgiClient.java (original)
+++ sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/impl/HttpOsgiClient.java Tue Oct 22 14:45:17 2013
@@ -146,32 +146,85 @@ public class HttpOsgiClient implements O
     }
 
     @Override
-    public void installLocalBundle(String explodedBundleLocation) throws OsgiClientException {
+    public void installLocalBundle(final String explodedBundleLocation) throws OsgiClientException {
 
         if (explodedBundleLocation == null) {
             throw new IllegalArgumentException("explodedBundleLocation may not be null");
         }
 
-        PostMethod method = new PostMethod(repositoryInfo.getUrl() + "system/sling/tooling/install");
-        method.addParameter("dir", explodedBundleLocation);
+        new LocalBundleInstaller(getHttpClient(), repositoryInfo) {
 
-        try {
-            int status = getHttpClient().executeMethod(method);
-            if (status != 200) {
-                throw new OsgiClientException("Method execution returned status " + status);
+            @Override
+            void configureRequest(PostMethod method) {
+                method.addParameter("dir", explodedBundleLocation);
             }
+        }.installBundle();
+    }
 
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
-            IOUtils.copy(method.getResponseBodyAsStream(), out);
-
-            System.out.println(new String(out.toByteArray(), "UTF-8"));
+    @Override
+    public void installLocalBundle(final InputStream jarredBundle, String sourceLocation) throws OsgiClientException {
 
-        } catch (IOException e) {
-            throw new OsgiClientException(e);
-        } finally {
-            method.releaseConnection();
+        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 StringPart("bundle", IOUtils.toString(jarredBundle, "UTF-8")) };
+                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) {
+                    throw new OsgiClientException("Method execution returned status " + status);
+                }
+
+                ByteArrayOutputStream out = new ByteArrayOutputStream();
+                IOUtils.copy(method.getResponseBodyAsStream(), out);
+
+                JSONObject obj = new JSONObject(new String(out.toByteArray(), "UTF-8"));
+
+                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();
+            }
+        }
+
+        abstract void configureRequest(PostMethod method) throws IOException;
+    }
 }

Modified: sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/impl/TracingOsgiClient.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/impl/TracingOsgiClient.java?rev=1534649&r1=1534648&r2=1534649&view=diff
==============================================================================
--- sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/impl/TracingOsgiClient.java (original)
+++ sling/trunk/tooling/ide/api/src/org/apache/sling/ide/osgi/impl/TracingOsgiClient.java Tue Oct 22 14:45:17 2013
@@ -54,6 +54,11 @@ public class TracingOsgiClient implement
     @Override
     public void installLocalBundle(String explodedBundleLocation) throws OsgiClientException {
 
+        logInstallLocalBundle(explodedBundleLocation);
+    }
+
+    private void logInstallLocalBundle(String explodedBundleLocation) throws OsgiClientException, Error {
+
         Map<String, Object> props = new HashMap<String, Object>();
         long start = System.currentTimeMillis();
         props.put(CommandExecutionProperties.ACTION_TYPE, "InstallLocalBundle");
@@ -82,4 +87,10 @@ public class TracingOsgiClient implement
         }
     }
 
+    @Override
+    public void installLocalBundle(InputStream jarredBundle, String sourceLocation) throws OsgiClientException {
+
+        logInstallLocalBundle(sourceLocation);
+    }
+
 }

Added: sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/JarBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/JarBuilder.java?rev=1534649&view=auto
==============================================================================
--- sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/JarBuilder.java (added)
+++ sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/JarBuilder.java Tue Oct 22 14:45:17 2013
@@ -0,0 +1,107 @@
+/*
+ * 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.eclipse.core.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.Deflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * The <tt>JarBuilder</tt> creates a Jar file from a directory structure using the Eclipse APIs
+ * 
+ */
+public class JarBuilder {
+
+    public InputStream buildJar(final IFolder sourceDir) throws CoreException {
+
+        ByteArrayOutputStream store = new ByteArrayOutputStream();
+
+        JarOutputStream zos = null;
+        InputStream manifestInput = null;
+        try {
+            IResource manifestResource = sourceDir.findMember(JarFile.MANIFEST_NAME);
+            if (manifestResource == null || manifestResource.getType() != IResource.FILE) {
+                throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "No file named "
+                        + JarFile.MANIFEST_NAME + " found under " + sourceDir));
+            }
+
+            manifestInput = ((IFile) manifestResource).getContents();
+            
+            Manifest manifest = new Manifest(manifestInput);
+
+            zos = new JarOutputStream(store);
+            zos.setLevel(Deflater.NO_COMPRESSION);
+            // manifest first
+            final ZipEntry anEntry = new ZipEntry(JarFile.MANIFEST_NAME);
+            zos.putNextEntry(anEntry);
+            manifest.write(zos);
+            zos.closeEntry();
+            zipDir(sourceDir, zos, "");
+        } catch (IOException e) {
+            throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
+        } finally {
+            IOUtils.closeQuietly(zos);
+            IOUtils.closeQuietly(manifestInput);
+        }
+
+        return new ByteArrayInputStream(store.toByteArray());
+    }
+
+    private void zipDir(final IFolder sourceDir, final ZipOutputStream zos, final String path) throws CoreException,
+            IOException {
+
+        for (final IResource f : sourceDir.members()) {
+            if (f.getType() == IResource.FOLDER) {
+                final String prefix = path + f.getName() + "/";
+                zos.putNextEntry(new ZipEntry(prefix));
+                zipDir((IFolder) f, zos, prefix);
+            } else if (f.getType() == IResource.FILE) {
+                final String entry = path + f.getName();
+                if (JarFile.MANIFEST_NAME.equals(entry)) {
+                    continue;
+                }
+                final InputStream fis = ((IFile) f).getContents();
+                try {
+                    final byte[] readBuffer = new byte[8192];
+                    int bytesIn = 0;
+                    final ZipEntry anEntry = new ZipEntry(entry);
+                    zos.putNextEntry(anEntry);
+                    while ((bytesIn = fis.read(readBuffer)) != -1) {
+                        zos.write(readBuffer, 0, bytesIn);
+                    }
+                } finally {
+                    IOUtils.closeQuietly(fis);
+                }
+            }
+        }
+    }
+}

Propchange: sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/JarBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/JarBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java?rev=1534649&r1=1534648&r2=1534649&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java (original)
+++ sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java Tue Oct 22 14:45:17 2013
@@ -16,7 +16,6 @@
  */
 package org.apache.sling.ide.eclipse.core.internal;
 
-import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -34,7 +33,6 @@ import java.util.Set;
 import org.apache.commons.io.IOUtils;
 import org.apache.sling.ide.artifacts.EmbeddedArtifactLocator;
 import org.apache.sling.ide.eclipse.core.ISlingLaunchpadServer;
-import org.apache.sling.ide.eclipse.core.MavenLaunchHelper;
 import org.apache.sling.ide.eclipse.core.ProjectUtil;
 import org.apache.sling.ide.eclipse.core.ResourceUtil;
 import org.apache.sling.ide.eclipse.core.ServerUtil;
@@ -248,48 +246,41 @@ public class SlingLaunchpadBehaviour ext
 	private void publishBundleModule(IModule[] module, IProgressMonitor monitor) throws CoreException {
 		final IProject project = module[0].getProject();
         boolean installLocally = getServer().getAttribute(ISlingLaunchpadServer.PROP_INSTALL_LOCALLY, true);
-		if (!installLocally) {
-            final String launchMemento = MavenLaunchHelper.createMavenLaunchConfigMemento(project.getLocation()
-                    .toString(), "package org.apache.sling:maven-sling-plugin:install", null, false, null);
-            IFolder dotLaunches = project.getFolder(".settings").getFolder(".launches");
-            if (!dotLaunches.exists()) {
-                dotLaunches.create(true, true, monitor);
-            }
-            IFile launchFile = dotLaunches.getFile("sling_install.launch");
-            InputStream in = new ByteArrayInputStream(launchMemento.getBytes());
-            if (!launchFile.exists()) {
-                launchFile.create(in, true, monitor);
-            }
-
-            ILaunchConfiguration launchConfig = DebugPlugin.getDefault().getLaunchManager()
-                    .getLaunchConfiguration(launchFile);
-            launchConfig.launch(ILaunchManager.RUN_MODE, monitor);
-		} else {
-			monitor.beginTask("deploying via local install", 5);
+		monitor.beginTask("deploying via local install", 5);
 
-            try {
-                OsgiClient osgiClient = Activator.getDefault().getOsgiClientFactory()
-                        .createOsgiClient(ServerUtil.getRepositoryInfo(getServer(), monitor));
+        try {
+            OsgiClient osgiClient = Activator.getDefault().getOsgiClientFactory()
+                    .createOsgiClient(ServerUtil.getRepositoryInfo(getServer(), monitor));
 
-                IJavaProject javaProject = ProjectHelper.asJavaProject(project);
+            IJavaProject javaProject = ProjectHelper.asJavaProject(project);
 
-                IPath outputLocation = project.getWorkspace().getRoot().findMember(javaProject.getOutputLocation())
-                        .getLocation();
-                monitor.worked(1);
+            IFolder outputFolder = (IFolder) project.getWorkspace().getRoot().findMember(javaProject.getOutputLocation());
+            IPath outputLocation = outputFolder.getLocation();
+            monitor.worked(1);
 
+            if ( installLocally ) {
                 osgiClient.installLocalBundle(outputLocation.toOSString());
                 monitor.worked(4);
-                setModulePublishState(module, IServer.PUBLISH_STATE_NONE);
+            } else {
 
-            } catch (URISyntaxException e1) {
-                throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e1.getMessage(), e1));
-            } catch (OsgiClientException e1) {
-                throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed installing bundle : "
-                        + e1.getMessage(), e1));
-            } finally {
-                monitor.done();
+                JarBuilder builder = new JarBuilder();
+                InputStream bundle = builder.buildJar(outputFolder);
+                monitor.worked(1);
+                
+                osgiClient.installLocalBundle(bundle, outputFolder.getLocation().toOSString());
+                monitor.worked(3);
             }
-		}
+
+            setModulePublishState(module, IServer.PUBLISH_STATE_NONE);
+
+        } catch (URISyntaxException e1) {
+            throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e1.getMessage(), e1));
+        } catch (OsgiClientException e1) {
+            throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed installing bundle : "
+                    + e1.getMessage(), e1));
+        } finally {
+            monitor.done();
+        }
 	}
 
     private void publishContentModule(int kind, int deltaKind, IModule[] module, IProgressMonitor monitor)

Modified: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/InstallEditorSection.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/InstallEditorSection.java?rev=1534649&r1=1534648&r2=1534649&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/InstallEditorSection.java (original)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/InstallEditorSection.java Tue Oct 22 14:45:17 2013
@@ -70,7 +70,7 @@ public class InstallEditorSection extend
     protected boolean _updating;
     protected PropertyChangeListener _listener;
 
-    private Button mvnSlingInstallButton;
+    private Button bundleLocalInstallButton;
     private Button quickLocalInstallButton;
     private Hyperlink installOrUpdateSupportBundleLink;
     private ISlingLaunchpadServer launchpadServer;
@@ -105,9 +105,9 @@ public class InstallEditorSection extend
         section.setClient(composite);
 
         
-        mvnSlingInstallButton = toolkit.createButton(composite, "Install bundles via mvn sling:install", SWT.RADIO);
+        bundleLocalInstallButton = toolkit.createButton(composite, "Install bundles via bundle upload", SWT.RADIO);
         GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
-        mvnSlingInstallButton.setLayoutData(data);
+        bundleLocalInstallButton.setLayoutData(data);
         
         quickLocalInstallButton = toolkit.createButton(composite, "Install bundles directly from local directory",
                 SWT.RADIO);
@@ -135,7 +135,7 @@ public class InstallEditorSection extend
 
                 if (ISlingLaunchpadServer.PROP_INSTALL_LOCALLY.equals(evt.getPropertyName())) {
             		quickLocalInstallButton.setSelection((Boolean)evt.getNewValue());
-            		mvnSlingInstallButton.setSelection(!(Boolean)evt.getNewValue());
+            		bundleLocalInstallButton.setSelection(!(Boolean)evt.getNewValue());
                 } else if (evt.getPropertyName().equals(
                         String.format(ISlingLaunchpadServer.PROP_BUNDLE_VERSION_FORMAT,
                                 EmbeddedArtifactLocator.SUPPORT_BUNDLE_SYMBOLIC_NAME))) {
@@ -166,7 +166,7 @@ public class InstallEditorSection extend
         final ISlingLaunchpadConfiguration config = launchpadServer.getConfiguration();
 
         quickLocalInstallButton.setSelection(config.bundleInstallLocally());
-        mvnSlingInstallButton.setSelection(!config.bundleInstallLocally());
+        bundleLocalInstallButton.setSelection(!config.bundleInstallLocally());
 
         SelectionListener listener = new SelectionAdapter() {
         	
@@ -177,7 +177,7 @@ public class InstallEditorSection extend
 		};
 
         quickLocalInstallButton.addSelectionListener(listener);
-        mvnSlingInstallButton.addSelectionListener(listener);
+        bundleLocalInstallButton.addSelectionListener(listener);
 
         Version serverVersion = launchpadServer.getBundleVersion(EmbeddedArtifactLocator.SUPPORT_BUNDLE_SYMBOLIC_NAME);
         final EmbeddedArtifact supportBundle = artifactLocator.loadToolingSupportBundle();
@@ -289,7 +289,7 @@ public class InstallEditorSection extend
     private void updateActionArea(Version serverVersion, final Version embeddedVersion) {
         if (serverVersion == null || embeddedVersion.compareTo(serverVersion) > 0) {
             supportBundleVersionLabel
-                    .setText("Installation support bundle is not present our outdated, local deployment will not work");
+                    .setText("Installation support bundle is not present our outdated, deployment will not work");
             installOrUpdateSupportBundleLink.setEnabled(true);
         } else {
             supportBundleVersionLabel.setText("Installation support bundle is present and up to date.");