Bug 389423 - [bulk] Adapt the Nano Simple Deployer
diff --git a/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/SimpleDeployer.java b/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/SimpleDeployer.java
index 9a69160..562fe8f 100644
--- a/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/SimpleDeployer.java
+++ b/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/SimpleDeployer.java
@@ -7,13 +7,16 @@
import org.eclipse.virgo.nano.deployer.api.core.DeploymentIdentity;
import org.osgi.framework.Bundle;
-
public interface SimpleDeployer {
public final int HOT_DEPLOYED_ARTIFACTS_START_LEVEL = 5;
public boolean deploy(URI path);
+ public boolean install(URI path);
+
+ public boolean start(URI path);
+
public boolean update(URI path);
public boolean undeploy(Bundle bundle);
diff --git a/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/BundleDeployer.java b/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/BundleDeployer.java
index 8e0e38d..8ac1211 100644
--- a/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/BundleDeployer.java
+++ b/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/BundleDeployer.java
@@ -9,6 +9,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarFile;
@@ -48,6 +49,8 @@
private static final String UNKNOWN = "unknown";
private static final String INSTALL_BY_REFERENCE_PREFIX = "reference:file:";
+
+ private static final String FRAGMEN_HOST_HEADER = "Fragment-Host";
private final EventLogger eventLogger;
@@ -75,7 +78,123 @@
String staging = "staging";
this.workBundleInstallLocation = new File(kernelHomeFile, "work" + File.separator + thisBundleName + File.separator + staging);
}
+
+ private Boolean createInstallationFolder(){
+ if (!this.workBundleInstallLocation.exists()) {
+ if (!this.workBundleInstallLocation.mkdirs()) {
+ this.logger.error("Failed to create staging directory '" + this.workBundleInstallLocation.getAbsolutePath()
+ + "' for bundle deployment.");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean validateUri(URI uri){
+ if (!canWrite(uri)) {
+ this.logger.error("Cannot open the file " + uri + " for writing. The configured timeout is " + this.largeFileCopyTimeout + ".");
+ return false;
+ }
+ return true;
+ }
+
+ private Boolean isFragment(FragmentHost hostHolder){
+ return (hostHolder != null && hostHolder.getBundleSymbolicName() != null);
+ }
+
+ private Boolean isFragment(Bundle bundle){
+ Enumeration<String> keys = bundle.getHeaders().keys();
+ while (keys.hasMoreElements()){
+ if (keys.nextElement().equalsIgnoreCase(FRAGMEN_HOST_HEADER) ){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void refreshHosts(FragmentHost hostHolder, Bundle fragment){
+ try {
+ Bundle[] hosts = this.packageAdmin.getBundles(hostHolder.getBundleSymbolicName(), null);
+ if (hosts != null) {
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_REFRESHING_HOST, fragment.getSymbolicName(), fragment.getVersion());
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_REFRESHING_HOST, fragment.getSymbolicName(), fragment.getVersion());
+ this.packageAdmin.refreshPackages(hosts);
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_REFRESHED_HOST, fragment.getSymbolicName(), fragment.getVersion());
+ }
+ } catch (Exception e) {
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_REFRESH_HOST_ERROR, e, fragment.getSymbolicName(), fragment.getVersion());
+ }
+ try {
+ if (this.bundleInfosUpdater != null && this.bundleInfosUpdater.isAvailable()) {
+ registerToBundlesInfo(fragment, true);
+ }
+ } catch (Exception e) {
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_PERSIST_ERROR, e, fragment.getSymbolicName(), fragment.getVersion());
+ }
+ }
+
+ private void updateBundleInfo(Bundle bundle, Boolean isFragment){
+ try {
+ if (this.bundleInfosUpdater != null && this.bundleInfosUpdater.isAvailable()) {
+ registerToBundlesInfo(bundle, true);
+ }
+ } catch (Exception ex) {
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_PERSIST_ERROR, ex, bundle.getSymbolicName(), bundle.getVersion());
+ }
+ }
+
+ @Override
+ public boolean install(URI uri) {
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_INSTALLING, new File(uri).toString());
+ try{
+ if (!validateUri(uri) || !(createInstallationFolder())) {
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_INSTALLING_ERROR, uri);
+ return STATUS_ERROR;
+ }
+ // copy bundle to work folder
+ File stagedFile = new File(workBundleInstallLocation, extractJarFileNameFromString(uri.toString()));
+ FileCopyUtils.copy(new File(uri), stagedFile);
+
+ // install the bundle
+ final Bundle installed = this.bundleContext.installBundle(createInstallLocation(stagedFile));
+ final FragmentHost hostHolder = getFragmentHostFromDeployedBundleIfExsiting(stagedFile);
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_INSTALLED, installed.getSymbolicName(), installed.getVersion());
+
+ //if fragment, refresh hosts and update bundles.info
+ if (isFragment(hostHolder)){
+ refreshHosts(hostHolder, installed);
+ updateBundleInfo(installed, true);
+ }
+ } catch (Exception e) {
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_INSTALLING_ERROR, e, uri);
+ return STATUS_ERROR;
+ }
+ return STATUS_OK;
+ }
+
+ @Override
+ public boolean start(URI uri) {
+ Bundle installedBundle = getInstalledBundle(uri);
+ if (installedBundle != null){
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_STARTING, installedBundle.getSymbolicName(), installedBundle.getVersion());
+ try {
+ if (!isFragment(installedBundle)){
+ installedBundle.start();
+ updateBundleInfo(installedBundle, false);
+ }else{
+ this.logger.warn("The installed bundle for the given url ["+ uri +"] is a fragment bundle. Start operation for this url failed. ");
+ return STATUS_ERROR;
+ }
+ } catch (Exception e) {
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_STARTING_ERROR, e, installedBundle.getSymbolicName(), installedBundle.getVersion());
+ return STATUS_ERROR;
+ }
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_STARTED, installedBundle.getSymbolicName(), installedBundle.getVersion());
+ }
+ return STATUS_OK;
+ }
+
@Override
public boolean deploy(URI path) {
this.eventLogger.log(NanoDeployerLogEvents.NANO_INSTALLING, new File(path).toString());
@@ -233,6 +352,11 @@
public boolean canServeFileType(String fileType) {
return JAR.equals(fileType);
}
+
+ private Bundle getInstalledBundle(URI uri){
+ File matchingStagingBundle = new File(this.workBundleInstallLocation, extractJarFileNameFromString(uri.toString()));
+ return this.bundleContext.getBundle(createInstallLocation(matchingStagingBundle));
+ }
@Override
public boolean isDeployed(URI path) {
@@ -344,4 +468,6 @@
types.add(JAR);
return types;
}
+
+
}
diff --git a/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/StandardApplicationDeployer.java b/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/StandardApplicationDeployer.java
index cd7ed15..0e0423b 100644
--- a/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/StandardApplicationDeployer.java
+++ b/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/StandardApplicationDeployer.java
@@ -84,15 +84,36 @@
}
}
if (!isThereSuitableDeployer) {
- List<String> acceptedTypes = new ArrayList<String>();
- for (SimpleDeployer deployer : this.simpleDeployers) {
- acceptedTypes.addAll(deployer.getAcceptedFileTypes());
- }
- this.eventLogger.log(NanoDeployerLogEvents.NANO_UNRECOGNIZED_TYPE, uri, acceptedTypes);
+ handleUnsupportedFileType(uri);
}
return null;
}
-
+
+ @Override
+ public DeploymentIdentity[] bulkDeploy(List<URI> uris,
+ DeploymentOptions options) throws DeploymentException {
+ if (uris != null && !uris.isEmpty()) {
+ installDeployables(uris);
+ startDeployables(uris);
+ return getDeploymentIdentities(uris);
+ }else{
+ this.logger
+ .warn("Cannot perform bulk deploy operation of the given URIs list as it is either empty or null.");
+ return null;
+ }
+ }
+
+ private DeploymentIdentity[] getDeploymentIdentities(List<URI> uris){
+ List<DeploymentIdentity> accumulatedDIs = new ArrayList<DeploymentIdentity>();
+ for(URI uri:uris){
+ DeploymentIdentity di = getDeploymentIdentity(uri);
+ if (di != null){
+ accumulatedDIs.add(di);
+ }
+ }
+ return accumulatedDIs.toArray(new DeploymentIdentity[0]);
+ }
+
@Override
public void undeploy(DeploymentIdentity deploymentIdentity) throws DeploymentException {
if (this.bundleContext != null) {
@@ -234,5 +255,55 @@
public void unbindSimpleDeployer(SimpleDeployer deployer) {
this.simpleDeployers.remove(deployer);
}
+
+ private void handleUnsupportedFileType(URI uri){
+ List<String> acceptedTypes = new ArrayList<String>();
+ for (SimpleDeployer deployer : this.simpleDeployers) {
+ acceptedTypes.addAll(deployer.getAcceptedFileTypes());
+ }
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_UNRECOGNIZED_TYPE, uri, acceptedTypes);
+ }
+
+ private void installDeployables(List<URI> uris){
+ for (URI uri:uris){
+ boolean isThereSuitableDeployer = false;
+ for (SimpleDeployer deployer : this.simpleDeployers) {
+ if (deployer.canServeFileType(getFileTypeFromUri(uri))) {
+ isThereSuitableDeployer = true;
+ if (!deployer.isDeployFileValid(new File(uri))) {
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_INVALID_FILE);
+ } else {
+ if (deployer.isDeployed(uri)) {
+ deployer.update(uri);
+ } else {
+ deployer.install(uri);
+ }
+ }
+ }
+ }
+ if (!isThereSuitableDeployer) {
+ handleUnsupportedFileType(uri);
+ }
+ }
+ }
+
+ private void startDeployables (List<URI> uris){
+ for (URI uri:uris){
+ boolean isThereSuitableDeployer = false;
+ for (SimpleDeployer deployer : this.simpleDeployers) {
+ if (deployer.canServeFileType(getFileTypeFromUri(uri))) {
+ isThereSuitableDeployer = true;
+ if (!deployer.isDeployFileValid(new File(uri))) {
+ this.eventLogger.log(NanoDeployerLogEvents.NANO_INVALID_FILE);
+ } else {
+ deployer.start(uri);
+ }
+ }
+ }
+ if (!isThereSuitableDeployer) {
+ handleUnsupportedFileType(uri);
+ }
+ }
+ }
}