Integer.toString(serverId.getHostPort()), serverId.getUserName(),
serverId.getPassword(), module);
}
public void run() {
ConnectionSource dasConnection= (ConnectionSource) args[0];
Archive deployArchive = (Archive) args[1];
Archive deployPlan = (Archive) args[2];
Map deployOptions = (Map) args[3];
SunTarget[] targetList = (SunTarget[]) args[4];
SunTarget domain = (SunTarget) args[5];
boolean isLocalConnectionSource = ((Boolean) args[6]).booleanValue();
ServerConnectionIdentifier serverId =
(ServerConnectionIdentifier) args[7];
Object archiveUploadID = null;
Object planUploadID = null;
Map deployedTargets = null;
Object deployActionID = null;
boolean isDirectoryDeploy = false;
boolean isRedeploy = false;
//Make sure the file permission is correct when deploying a file
//Note that if using JSR88 deploying from InputStream, the
//deployArchive.getArchiveUri() would be null, and not directory
//deploy
if (deployArchive == null) {
setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.archive_not_specified"), domain);
return;
}
if (deployArchive.getURI() != null) {
File tmpFile = new File(deployArchive.getURI().getPath());
if(!tmpFile.exists()) {
setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.archive_not_in_location"), domain);
return;
}
if(!tmpFile.canRead()) {
setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.archive_no_read_permission"), domain);
return;
}
if (tmpFile.isDirectory()) {
isDirectoryDeploy = true;
}
}
try {
// Get the module ID
this.moduleID = (String)deployOptions.get(DeploymentProperties.DEPLOY_OPTION_NAME_KEY);
boolean isModuleDeployed = isModuleDeployed(dasConnection, moduleID);
// for redeploy, force should be true - enforce it here it self
if(("false".equals(deployOptions.get(DeploymentProperties.DEPLOY_OPTION_FORCE_KEY))) &&
(isModuleDeployed) ) {
setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.deploy_error_module_exists"), domain);
return;
}
deplMgr = ProxyFactory.getInstance(dasConnection).getDomainRoot().getDeploymentMgr();
/**
* If there is only one target and that target is a stand alone server target, set WSDL_TARGET_HINT
* in options to enable WSDL generation with the target's host and port. Refer to bug 6157923 for more info
*/
if( (targetList.length == 1) && (TargetType.STAND_ALONE_SERVER.equals(targetList[0].getTargetType())) && !("server".equals(targetList[0].getName())) ) {
deployOptions.put(DeploymentProperties.WSDL_TARGET_HINT, targetList[0].getName());
}
// Do redeploy if force=true and the module is already deployed
if( ("true".equals(deployOptions.get(DeploymentProperties.DEPLOY_OPTION_FORCE_KEY))) &&
(isModuleDeployed) ) {
isRedeploy = true;
// Get list of all targets on which this module is already deployed
deployedTargets = DeploymentClientUtils.getDeployedTargetList(dasConnection, moduleID);
// Check if any of the specified targets is not part of the deployed target list
// If so, it means user has to use create-app-ref and not redeploy; flag error
if(DeploymentClientUtils.isNewTarget(deployedTargets, targetList)) {
setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.useCreateAppRef",
moduleID), domain);
}
// if there is already app ref associated with this app
if (deployedTargets.size() > 0) {
// if it's redeploy to domain, then it's equivalent
// to redeploy to all targets
if ((TargetType.DOMAIN.equals(targetList[0].getName()))) {
DeploymentFacility deploymentFacility;
if(isLocalConnectionSource) {
deploymentFacility = DeploymentFacilityFactory.getLocalDeploymentFacility();
} else {
deploymentFacility = DeploymentFacilityFactory.getDeploymentFacility();
}
deploymentFacility.connect(
targetList[0].getConnectionInfo());
Set nameSet = deployedTargets.keySet();
String[] targetNames = (String[])nameSet.toArray(
new String[nameSet.size()]);
Target[] targetList2 =
deploymentFacility.createTargets(targetNames);
if (targetList2 == null) {
setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.createTargetsFailed"), domain);
return;
}
targetList = new SunTarget[targetList2.length];
for (int ii = 0; ii < targetList2.length; ii++) {
targetList[ii] = (SunTarget)targetList2[ii];
}
}
// if all targets on which the app is deployed is not
// given, return error
else if (!DeploymentClientUtils.isTargetListComplete(
deployedTargets, targetList)) {
setupForAbnormalExit(
localStrings.getString("enterprise.deployment.client.specifyAllTargets", moduleID, "redeploy"),
domain);
return;
}
// Stop all apps;
Map options = new HashMap();
options.putAll(deployOptions);
options.put(DeploymentProperties.REDEPLOY, Boolean.toString(isModuleDeployed));
RollBackAction undeplRollback = new RollBackAction(RollBackAction.DELETE_APP_REF_OPERATION,
moduleID, deployOptions);
for(int i=0; i<targetList.length; i++) {
options.put(DeploymentProperties.DEPLOY_OPTION_CASCADE_KEY, "true");
// We dont rollback for stop failure because the failure may be because of server being down
// We just add DeploymentStatus of this phase to the complete DeploymentStatus
DeploymentClientUtils.setResourceOptions(
options,
DeploymentProperties.RES_UNDEPLOYMENT,
targetList[i].getName());
DeploymentStatus stat =
DeploymentClientUtils.stopApplication(
dasConnection.getExistingMBeanServerConnection(),
moduleID, targetList[i], options);
if (!checkStatusAndAddStage(targetList[i], null, localStrings.getString("enterprise.deployment.client.redeploy_stop", targetList[i].getName()) , dasConnection, stat)) {
return;
}
// del-app-ref from all targets
options.put(DeploymentProperties.DEPLOY_OPTION_CASCADE_KEY, "false");
// set enable flag of options as per state of the app
// before redeploy
options.put(DeploymentProperties.DEPLOY_OPTION_ENABLE_KEY, deployedTargets.get(targetList[i].getName()).toString());
stat = DeploymentClientUtils.deleteApplicationReference(
dasConnection.getExistingMBeanServerConnection(),
moduleID, targetList[i], options);
if(!checkStatusAndAddStage(targetList[i], undeplRollback, localStrings.getString("enterprise.deployment.client.redeploy_remove_ref", targetList[i].getName()), dasConnection, stat)) {
return;
}
undeplRollback.addTarget(targetList[i], RollBackAction.APP_REF_DELETED);
}
}
}
// Get a deploy ID
deployActionID = deplMgr.initDeploy();
// Make a copy of deployOptions and set the ENABLE flag in this copy to true
// This is so that the enabled flag during deploy-to-domain is always true
// This might need to be replaced with an efficient logic to look up the current enabled flag
// using AMX
Map dupOptions = new HashMap();
dupOptions.putAll(deployOptions);
dupOptions.put(DeploymentProperties.DEPLOY_OPTION_ENABLE_KEY, Boolean.TRUE.toString());
dupOptions.put(DeploymentProperties.REDEPLOY, Boolean.toString(isModuleDeployed));
// if deploy to "domain" or redeploy to "domain" with no
// existing application-ref
if ((TargetType.DOMAIN.equals(targetList[0].getName()))) {
if (isRedeploy) {
DeploymentClientUtils.setResourceOptions(
dupOptions,
DeploymentProperties.RES_REDEPLOYMENT,
targetList);
} else {
DeploymentClientUtils.setResourceOptions(
dupOptions,
DeploymentProperties.RES_DEPLOYMENT,
targetList);
}
} else {
DeploymentClientUtils.setResourceOptions(
dupOptions,
DeploymentProperties.RES_NO_OP,
targetList);
}
// Now start a fresh deploy in domain
// upload file only if this not a directory deploy AND it is not a local connection source (not from gui)
String uploadProp = (String) deployOptions.get(DeploymentProperties.UPLOAD);
boolean upload = new Boolean((uploadProp != null) ? uploadProp : DeploymentProperties.DEFAULT_UPLOAD).booleanValue();
if(!isDirectoryDeploy && !isLocalConnectionSource && upload) {
// upload the archive
long startTime = System.currentTimeMillis();
long endTime = startTime;
// we use jmx upload for following scenarios:
// 1. for secure connection: https
// 2. if the JMX_UPLOAD_CHUNK_SIZE system property is set
// 3. if the HTTP_PROXYHOST system property is set
if ( serverId.isSecure() ||
(jmxUploadChunkSizeProp != null &&
jmxUploadChunkSizeProp.length() > 0) ||
(httpProxyHostProp != null &&
httpProxyHostProp.length() > 0) ){
// using jmx
archiveUploadID = uploadArchive(deployArchive);
// If there is a plan, upload the plan
if (deployPlan != null){
if (deployPlan.getURI()!=null) {
File f = new File(deployPlan.getURI().getPath());
if (f.length()!= 0) {
planUploadID = uploadArchive(deployPlan);
}
}
}
endTime = System.currentTimeMillis();
// Call DeploymentMgr to start deploy
deplMgr.startDeploy(deployActionID, archiveUploadID, planUploadID, dupOptions);
} else {
// using http
String archivePath = uploadArchiveOverHTTP(serverId,
deployArchive);
DeploymentSourceImpl archiveSource =
new DeploymentSourceImpl(archivePath, true,
new String[1], new String[1], new String[1],
new HashMap());
String planPath = null;
DeploymentSourceImpl planSource = null;
// If there is a plan, upload the plan
if (deployPlan != null){
if (deployPlan.getURI()!=null){
File f = new File(deployPlan.getURI().getPath());
if (f.length()!= 0) {
planPath = uploadArchiveOverHTTP(serverId, deployPlan);
planSource =
new DeploymentSourceImpl(planPath, true,
new String[1], new String[1], new String[1],
new HashMap());
}
}
}
endTime = System.currentTimeMillis();
deplMgr.startDeploy(deployActionID, archiveSource.asMap(),
planSource == null ? null : planSource.asMap(),
dupOptions);
}
_logger.log(Level.FINE,
"time in upload: " + (endTime-startTime));
} else {
// Directory deploy is supported only on DAS - check that here
if((isDirectoryDeploy) && (!isDomainLocal(domain))) {
setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.domainNotLocal"),
domain);
return;
}
DeploymentSourceImpl archive = new DeploymentSourceImpl(deployArchive.getURI().getPath(), true,
new String[1], new String[1], new String[1], new HashMap());
// we do not support deployment plan for directory deployment
// currently
deplMgr.startDeploy(deployActionID, archive.asMap(), null, dupOptions);
}
// if deployActionID is still null, then there is some failure - report this and die
if(deployActionID == null) {
setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.no_deployment_id"), domain);
return;
}
// Wait till deploy is over
boolean done = false;
int waitLoopCount = 0;
com.sun.appserv.management.deploy.DeploymentStatus finalStatusFromMBean = null;
do {
Notification[] notifs = deplMgr.takeNotifications(deployActionID);
for(int i=0; i<notifs.length; i++) {
Map notifType = (Map) notifs[i].getUserData();
if(notifType.get(deplMgr.NOTIF_DEPLOYMENT_COMPLETED_STATUS_KEY) != null) {
finalStatusFromMBean =
DeploymentSupport.mapToDeploymentStatus((Map)deplMgr.getFinalDeploymentStatus(deployActionID));
done = true;
} else if(notifType.get(deplMgr.NOTIF_DEPLOYMENT_PROGRESS_KEY) != null) {
DeploymentProgress prog = DeploymentSupport.mapToDeploymentProgress((Map)notifType.get(deplMgr.NOTIF_DEPLOYMENT_PROGRESS_KEY));
String progStr = prog.getDescription() + " : " + prog.getProgressPercent() + "%";
fireProgressEvent(StateType.RUNNING, progStr, domain);
}
}
if(!done) {
if(waitLoopCount > TIMEOUT_LOOPS) {
setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.deployment_time_out"), domain);
return;
}
try {
Thread.sleep(SLEEP_TIME);
} catch(InterruptedException e) {
//Swallowing this exception deliberately; we dont want to do anything but wait
}
}
waitLoopCount++;
} while(!done);
DeploymentStatus tmp = DeploymentClientUtils.getDeploymentStatusFromAdminStatus(finalStatusFromMBean);
if(!checkStatusAndAddStage(
domain, null,
localStrings.getString("enterprise.deployment.client.deploy_in_domain"),
dasConnection, tmp)) {
return;
}
//Take the one returned from the server
if (moduleID == null) {
moduleID = tmp.getProperty(DeploymentStatus.MODULE_ID);
}
String key = moduleID + DeploymentStatus.KEY_SEPARATOR +
DeploymentStatus.MODULE_TYPE;
String xKey = moduleID + DeploymentStatus.KEY_SEPARATOR +
DeploymentStatus.XMODULE_TYPE;
this.moduleType =
DeploymentClientUtils.getXModuleType(tmp, key, xKey);
// Start keeping track of actions to be rolled back
RollBackAction rollback = new RollBackAction(RollBackAction.DEPLOY_OPERATION, moduleID, deployOptions);
// Deploy is done; create app ref if target[0] was not a domain
if(!(TargetType.DOMAIN.equals(targetList[0].getName()))) {
for(int i=0; i<targetList.length; i++) {
// If this is a redeploy, set enable flag of options as per state of the app before redeploy
if(deployedTargets != null) {
dupOptions.put(DeploymentProperties.DEPLOY_OPTION_ENABLE_KEY, deployedTargets.get(targetList[i].getName()).toString());
} else {
dupOptions.put(DeploymentProperties.DEPLOY_OPTION_ENABLE_KEY, deployOptions.get(DeploymentProperties.DEPLOY_OPTION_ENABLE_KEY));
}
DeploymentStatus stat =
DeploymentClientUtils.createApplicationReference(
dasConnection.getExistingMBeanServerConnection(),
moduleID, targetList[i], dupOptions);
if(!checkStatusAndAddStage(targetList[i], rollback,
localStrings.getString("enterprise.deployment.client.deploy_create_ref", targetList[i].getName()), dasConnection, stat)) {
return;
}
rollback.addTarget(targetList[i], rollback.APP_REF_CREATED);
/*
XXX Start the application regardless the value of "enable"
Otherwise no DeployEvent would be sent to the listeners on
a remote instance, which would in turn synchronize the app
bits. Note that the synchronization is only called during
applicationDeployed, not applicationEnabled. To make sure
the deployment code can work with both the new and the old
mbeans, we will call the start for now (as the old mbeans
would do). The backend listeners are already enhanced to
make sure the apps are not actually loaded unless the enable
attributes are true for both the application and
application-ref elements.
*/
// We dont rollback for start failure because start failure may be because of server being down
// We just add DeploymentStatus of this phase to the complete DeploymentStatus
if (isRedeploy) {
DeploymentClientUtils.setResourceOptions(
deployOptions,
DeploymentProperties.RES_REDEPLOYMENT,
targetList[i].getName());
} else {
DeploymentClientUtils.setResourceOptions(
deployOptions,
DeploymentProperties.RES_DEPLOYMENT,
targetList[i].getName());
}
stat = DeploymentClientUtils.startApplication(
dasConnection.getExistingMBeanServerConnection(),
moduleID, targetList[i], deployOptions);
checkStatusAndAddStage(targetList[i], null,
localStrings.getString("enterprise.deployment.client.deploy_start", targetList[i].getName()), dasConnection, stat, true);
}
}
// Do WSDL publishing only if the caller is not GUI
if ( !isLocalConnectionSource ) {
try {
DeploymentClientUtils.doWsdlFilePublishing(tmp, dasConnection);
} catch (Exception wsdlEx) {
DeploymentStatus newStatus = new DeploymentStatus();
newStatus.setStageStatus(DeploymentStatus.FAILURE);
newStatus.setStageStatusMessage(wsdlEx.getMessage());
newStatus.setStageException(wsdlEx);
checkStatusAndAddStage(domain, rollback,
localStrings.getString("enterprise.deployment.client.deploy_publish_wsdl"), dasConnection, newStatus);
String msg = localStrings.getString("enterprise.deployment.client.deploy_publish_wsdl_exception", wsdlEx.getMessage());
setupForAbnormalExit(msg, domain);
return;
}
}
initializeTargetModuleIDForAllServers(
tmp, dasConnection.getMBeanServerConnection(false));
setupForNormalExit(localStrings.getString("enterprise.deployment.client.deploy_application", moduleID), domain);
} catch (Throwable ioex) {
finalDeploymentStatus.setStageException(ioex);
setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.deploy_application_failed", ioex.getMessage()), domain);