001/* 002 * (C) Copyright 2006-2010 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * bstefanescu 018 */ 019package org.nuxeo.connect.update.task.live.commands; 020 021import java.io.File; 022import java.io.IOException; 023import java.util.Arrays; 024import java.util.List; 025import java.util.Map; 026import java.util.stream.Collector; 027import java.util.stream.Collectors; 028 029import org.apache.commons.logging.Log; 030import org.apache.commons.logging.LogFactory; 031import org.nuxeo.connect.update.PackageException; 032import org.nuxeo.connect.update.task.Command; 033import org.nuxeo.connect.update.task.Task; 034import org.nuxeo.connect.update.task.standalone.commands.CompositeCommand; 035import org.nuxeo.connect.update.task.standalone.commands.DeployPlaceholder; 036import org.nuxeo.runtime.api.Framework; 037import org.nuxeo.runtime.reload.ReloadContext; 038import org.nuxeo.runtime.reload.ReloadResult; 039import org.nuxeo.runtime.reload.ReloadService; 040import org.osgi.framework.BundleException; 041 042/** 043 * Deploy a runtime bundle, or a directory containing runtime bundles. 044 * <p> 045 * The inverse of this command is Undeploy. 046 * 047 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 048 */ 049public class Deploy extends DeployPlaceholder { 050 051 private static final Log log = LogFactory.getLog(Deploy.class); 052 053 public Deploy() { 054 super(); 055 } 056 057 public Deploy(File file) { 058 super(file); 059 } 060 061 /** 062 * @deprecated since 9.3, reload mechanism has changed, keep it for backward compatibility 063 */ 064 @Deprecated 065 protected Undeploy deployFile(File file, ReloadService service) throws PackageException { 066 String name = service.getOSGIBundleName(file); 067 if (name == null) { 068 // not an OSGI bundle => ignore 069 return null; 070 } 071 try { 072 service.deployBundle(file, true); 073 } catch (BundleException e) { 074 throw new PackageException("Failed to deploy bundle " + file, e); 075 } 076 return new Undeploy(file); 077 } 078 079 /** 080 * @deprecated since 9.3, reload mechanism has changed, keep it for backward compatibility 081 */ 082 @Deprecated 083 protected CompositeCommand deployDirectory(File dir, ReloadService service) throws PackageException { 084 CompositeCommand cmd = new CompositeCommand(); 085 File[] files = dir.listFiles(); 086 if (files != null) { 087 for (File fileInDir : files) { 088 Command ud = deployFile(fileInDir, service); 089 if (ud != null) { 090 cmd.addCommand(ud); 091 } 092 } 093 } 094 if (cmd.isEmpty()) { 095 // nothing to rollback 096 return null; 097 } 098 return cmd; 099 } 100 101 @Override 102 protected Command doRun(Task task, Map<String, String> prefs) throws PackageException { 103 if (!file.exists()) { 104 log.warn("Can't deploy file " + file + ". File is missing."); 105 return null; 106 } 107 ReloadService srv = Framework.getService(ReloadService.class); 108 boolean useCompatReload = Framework.isBooleanPropertyTrue(ReloadService.USE_COMPAT_HOT_RELOAD); 109 if (useCompatReload) { 110 return doCompatRun(srv); 111 } 112 if (file.isDirectory()) { 113 return _deployDirectory(file, srv); 114 } else { 115 return _deployFile(file, srv); 116 } 117 } 118 119 /** 120 * @deprecated since 9.3, reload mechanism has changed, keep it for backward compatibility 121 */ 122 @Deprecated 123 protected Command doCompatRun(ReloadService srv) throws PackageException { 124 Command rollback; 125 if (file.isDirectory()) { 126 rollback = deployDirectory(file, srv); 127 } else { 128 rollback = deployFile(file, srv); 129 } 130 if (rollback != null) { 131 // some deployments where done 132 try { 133 srv.runDeploymentPreprocessor(); 134 } catch (IOException e) { 135 throw new PackageException(e.getMessage(), e); 136 } 137 } 138 return rollback; 139 } 140 141 // TODO change the method name when removing deployFile 142 protected Undeploy _deployFile(File file, ReloadService service) throws PackageException { 143 String name = service.getOSGIBundleName(file); 144 if (name == null) { 145 // not an OSGI bundle => ignore 146 return null; 147 } 148 try { 149 ReloadResult result = service.reloadBundles(new ReloadContext().deploy(file)); 150 return result.deployedFilesAsStream().map(Undeploy::new).findFirst().orElseThrow( 151 () -> new IllegalStateException("Bundle " + file + " wasn't deployed")); 152 } catch (BundleException e) { 153 throw new PackageException("Failed to deploy bundle " + file, e); 154 } 155 } 156 157 // TODO change the method name when removing deployDirectory 158 protected CompositeCommand _deployDirectory(File dir, ReloadService service) throws PackageException { 159 File[] files = dir.listFiles(); 160 if (files != null) { 161 List<File> bundles = Arrays.stream(files) 162 .filter(f -> service.getOSGIBundleName(f) != null) 163 .collect(Collectors.toList()); 164 if (bundles.isEmpty()) { 165 // nothing to deploy 166 return null; 167 } 168 try { 169 ReloadResult result = service.reloadBundles(new ReloadContext().deploy(bundles)); 170 return result.deployedFilesAsStream().map(Undeploy::new).collect( 171 Collector.of(CompositeCommand::new, CompositeCommand::addCommand, CompositeCommand::combine)); 172 } catch (BundleException e) { 173 throw new PackageException("Failed to deploy bundles " + bundles, e); 174 } 175 } 176 return null; 177 } 178 179}