package org.jbosson.plugins.jbossesb;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.mc4j.ems.connection.bean.EmsBean;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.transfer.ContentResponseResult;
import org.rhq.core.domain.content.transfer.DeployIndividualPackageResponse;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.pluginapi.content.ContentContext;
import org.rhq.core.pluginapi.content.ContentFacet;
import org.rhq.core.pluginapi.content.ContentServices;
import org.rhq.core.pluginapi.event.EventContext;
import org.rhq.core.pluginapi.inventory.CreateResourceReport;
import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.operation.OperationContext;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.plugins.jmx.JMXComponent;
import org.rhq.plugins.jmx.MBeanResourceComponent;
public abstract class AbstractDeploymentComponent extends MBeanResourceComponent<JMXComponent> implements
OperationFacet, DeleteResourceFacet, ContentFacet {
public static final String JBOSS_WEB_NAME = "jbossWebName";
protected EmsBean jbossWebMBean;
protected File configPath;
private static final String PKG_TYPE_FILE = "file";
private static final String ARCHITECTURE = "noarch";
protected ResourceContext resourceContext;
protected ContentContext contentContext;
protected OperationContext operationContext;
protected EventContext eventContext;
// The following constants reference the exact name of the package types as defined in the plugin descriptor
protected static final String PACKAGE_TYPE_PATCH = "cumulativePatch";
protected static final String PACKAGE_TYPE_LIBRARY = "library";
protected static final String RESOURCE_TYPE_ESB = "Deployments";
public File getConfigurationPath() {
return this.configPath;
}
/**
* Check to see if the passed file is actually in jar format and contains a
* <ul>
* <li>WEB-INF/web.xml for .war </li>
* <li>META-INF/application.xml for .ear</li>
* <li>META-INF/jboss.service.xml for .sar</li>
* </ul>
* @param file File to check
* @param type Type to match - see RESOURCE_TYPE_SAR, RESOURCE_TYPE_WAR and RESOURCE_TYPE_EAR
* @return true is the file is in jar format and matches the type
*/
protected boolean isOfType(File file, String type) {
JarFile jfile = null;
try {
jfile = new JarFile(file);
JarEntry entry;
if (RESOURCE_TYPE_ESB.equals(type))
entry = jfile.getJarEntry("META-INF/jboss-esb.xml");
else {
entry = null; // unknown type
log.warn("isOfType: " + type + " is unknown - not a valid file");
}
if (entry != null)
return true;
return false;
} catch (Exception e) {
log.info(e.getMessage());
return false;
} finally {
if (jfile != null)
try {
jfile.close();
} catch (IOException e) {
log.info("Exception when trying to close the war file: " + e.getMessage());
}
}
}
protected void sleepAfterConfigXmlUpdate() {
// JBNADM-1984 - The contract with this method is that the newly created managed resource should be discoverable.
// Wait here so JBoss can recognize that the new managed resource has been created.
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
log.info("Sleep after Resource create interrupted", e);
}
}
@Override
public AvailabilityType getAvailability() {
// JBossASTomcatServerComponent parentTomcatComponent = (JBossASTomcatServerComponent) super.resourceContext
// .getParentResourceComponent();
// EmsConnection connection = parentTomcatComponent.getEmsConnection();
boolean isreg = bean.isRegistered();
return isreg ? AvailabilityType.UP : AvailabilityType.DOWN;
}
/**
* Recursively deletes a series of files. Any directories found in the list of files will be recursively deleted as
* well.
*
* @param contents list of files to delete
*/
public static void deleteDirectoryContents(File[] contents) {
for (File file : contents) {
if (file.isDirectory()) {
deleteDirectoryContents(file.listFiles());
}
file.delete();
}
}
public DeployPackagesResponse deployPackages(
Set<ResourcePackageDetails> packages,
ContentServices contentServices) {
ContentResponseResult overallResult = ContentResponseResult.SUCCESS;
List<DeployIndividualPackageResponse> individualResponses = new ArrayList<DeployIndividualPackageResponse>(
packages.size());
for (ResourcePackageDetails pkg : packages) {
log.info("Attempting to deploy package: " + pkg);
String packageTypeName = pkg.getPackageTypeName();
if (packageTypeName.equals(PACKAGE_TYPE_LIBRARY)) {
throw new UnsupportedOperationException("Deployment of new libraries is not supported by the plugin.");
}
}
DeployPackagesResponse response = new DeployPackagesResponse(overallResult);
response.getPackageResponses().addAll(individualResponses);
return response;
}
public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
final Set<ResourcePackageDetails> packages = new HashSet<ResourcePackageDetails>();
final ResourceContext<JMXComponent> resourceContext = getResourceContext();
final Configuration pluginConfiguration = resourceContext.getPluginConfiguration();
final String fullFileName = pluginConfiguration.getSimple("deployment").getStringValue();
if (fullFileName == null) {
throw new IllegalStateException("Plugin configuration does not contain the deployment name of the ESB file.");
}
final String version = getResourceContext().getVersion();
/*
* For now we assume it is in the deploy directory. This is not safe but it is
* an assumption made in other parts of the codebase and is consistent (for now).
* We need to rework this to discover the actual deployment location, but that will
* be part of a larger work.
*/
final AbstractESBComponent esbComponent = (AbstractESBComponent) resourceContext.getParentResourceComponent();
final File deploy = new File(esbComponent.getConfigurationPath(), "deploy");
final File file = new File(deploy, fullFileName);
if (file.exists())
{
// Package name and file name of the application are the same
String fileName = new File(fullFileName).getName();
PackageDetailsKey key = new PackageDetailsKey(fileName, version, PKG_TYPE_FILE, ARCHITECTURE);
ResourcePackageDetails details = new ResourcePackageDetails(key);
details.setFileName(fileName);
details.setLocation(file.getPath());
if (!file.isDirectory())
details.setFileSize(file.length());
details.setFileCreatedDate(file.lastModified()); // TODO: get created date via SIGAR
packages.add(details);
}
return packages;
}
public List<DeployPackageStep> generateInstallationSteps(
ResourcePackageDetails packageDetails) {
return null;
}
public RemovePackagesResponse removePackages(
Set<ResourcePackageDetails> packages) {
return null;
}
public InputStream retrievePackageBits(ResourcePackageDetails packageDetails) {
return null;
}
}