/*
* Copyright (c) 2011-2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed 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.wso2.carbon.humantask.core.store;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.deployment.DeploymentEngine;
import org.apache.axis2.deployment.util.Utils;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.AxisServiceGroup;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.WSDL11ToAxisServiceBuilder;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.commons.schema.resolver.DefaultURIResolver;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.bpel.common.ServiceConfigurationUtil;
import org.wso2.carbon.bpel.common.config.EndpointConfiguration;
import org.wso2.carbon.humantask.TNotification;
import org.wso2.carbon.humantask.TTask;
import org.wso2.carbon.humantask.core.HumanTaskConstants;
import org.wso2.carbon.humantask.core.dao.DeploymentUnitDAO;
import org.wso2.carbon.humantask.core.dao.HumanTaskDAOConnection;
import org.wso2.carbon.humantask.core.dao.TaskDAO;
import org.wso2.carbon.humantask.core.dao.TaskPackageStatus;
import org.wso2.carbon.humantask.core.deployment.ArchiveBasedHumanTaskDeploymentUnitBuilder;
import org.wso2.carbon.humantask.core.deployment.DeploymentUtil;
import org.wso2.carbon.humantask.core.deployment.HumanTaskDeploymentException;
import org.wso2.carbon.humantask.core.deployment.HumanTaskDeploymentUnit;
import org.wso2.carbon.humantask.core.deployment.SimpleTaskDefinitionInfo;
import org.wso2.carbon.humantask.core.engine.HumanTaskEngine;
import org.wso2.carbon.humantask.core.engine.runtime.api.HumanTaskRuntimeException;
import org.wso2.carbon.humantask.core.integration.AxisHumanTaskMessageReceiver;
import org.wso2.carbon.humantask.core.integration.CallBackServiceImpl;
import org.wso2.carbon.humantask.core.integration.HumanTaskWSDLLocator;
import org.wso2.carbon.humantask.core.internal.HumanTaskServiceComponent;
import org.wso2.carbon.humantask.core.store.repository.HumanTaskPackageRepository;
import org.wso2.carbon.humantask.core.store.repository.HumanTaskPackageRepositoryUtils;
import org.wso2.carbon.humantask.core.utils.HumanTaskStoreUtils;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.config.RegistryContext;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.utils.RegistryClientUtils;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.FileManipulator;
import org.wso2.carbon.utils.ServerConstants;
import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.CacheManagerFactory;
import javax.cache.Caching;
import javax.persistence.EntityManager;
import javax.wsdl.Definition;
import javax.wsdl.OperationType;
import javax.xml.namespace.QName;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
/**
* Manages human task deployments for a tenant. There will be HumanTaskStore per tenant. Handles the deployment
* of human tasks, and management of deployed tasks.
*/
public class HumanTaskStore {
private static final Log log = LogFactory.getLog(HumanTaskStore.class);
private int tenantId;
private ConfigurationContext configContext;
private List<HumanTaskBaseConfiguration> taskConfigurations =
new ArrayList<HumanTaskBaseConfiguration>();
// HumanTaskConfiguration QName with HumanTaskBaseConfiguration
// TaskConfiguration QName is constructed by appending the task version to local name
private Map<QName, HumanTaskBaseConfiguration> taskBaseConfigurationHashMap =
new HashMap<QName, HumanTaskBaseConfiguration>();
// Store the current task task version string ( TaskPackageName +"-" version ) against taskpackagename
private Map<String, String> loadedPackages = new HashMap<String, String>();
// List of TaskConfiguration QNames vs versioned taskPackageName
private Map<String, List<QName>> taskConfigurationsInTaskPackage = new HashMap<String, List<QName>>();
private Map<QName, QName> activeTaskConfigurationQNameMap = new HashMap<QName, QName>();
// This is the human task deployment repository
private File humanTaskDeploymentRepo;
private HumanTaskEngine engine;
// Tenant's config registry
private Registry tenantConfigRegistry;
// Tenant's registry based human task repository
private HumanTaskPackageRepository repository;
public HumanTaskStore(int tenantId, ConfigurationContext configContext) throws RegistryException {
this.tenantId = tenantId;
this.configContext = configContext;
this.engine = HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine();
tenantConfigRegistry = HumanTaskServiceComponent.getRegistryService().getConfigSystemRegistry(tenantId);
if (HumanTaskServiceComponent.getHumanTaskServer().getServerConfig().isCachingEnabled()) {
initializeCaches();
}
}
public void init() {
this.humanTaskDeploymentRepo = new File(CarbonUtils.getCarbonHome() + File.separator + "repository" +
File.separator + HumanTaskConstants.HUMANTASK_REPO_DIRECTORY +
File.separator + tenantId);
if (!humanTaskDeploymentRepo.exists() && !humanTaskDeploymentRepo.mkdirs()) {
log.warn("Cannot create tenant " + tenantId + " HumanTask deployment unit repository.");
}
repository = new HumanTaskPackageRepository(tenantConfigRegistry, humanTaskDeploymentRepo);
}
/**
* This will simply deploy the new task and will not perform removal of existing tasks, which should be done prior to
* deploying this task
* @param humanTaskDU
* @return List of task configuration Qnames deployed
* @throws HumanTaskDeploymentException
*/
public List<QName> deploy(HumanTaskDeploymentUnit humanTaskDU) throws HumanTaskDeploymentException {
List<QName> taskConfigsInPackage = new ArrayList<QName>();
TTask[] tasks = humanTaskDU.getTasks();
List<HumanTaskBaseConfiguration> configurations = new ArrayList<HumanTaskBaseConfiguration>();
if (tasks != null) {
for (TTask task : tasks) {
QName taskQName = new QName(humanTaskDU.getNamespace(), task.getName());
if (log.isDebugEnabled()) {
log.debug(" Adding task " + task.getName() + "to task configuration");
}
TaskConfiguration taskConf =
new TaskConfiguration(task,
humanTaskDU.getTaskServiceInfo(taskQName),
humanTaskDU.getHumanInteractionsDefinition(),
humanTaskDU.getWSDLs(),
humanTaskDU.getNamespace(),
humanTaskDU.getName(),
getTenantAxisConfig(),
humanTaskDU.getPackageName(),
humanTaskDU.getVersion(),
humanTaskDU.getHumanTaskDefinitionFile());
taskConf.setPackageStatus(humanTaskDU.getTaskPackageStatus());
configurations.add(taskConf);
// taskConfigurations.add(taskConf);
//
// // Aggregate task configurations in the hash map
// taskBaseConfigurationHashMap.put(taskConf.getName(), taskConf);
// taskConfigsInPackage.add(taskConf.getName());
if (!taskConf.isErroneous()) {
createCallBackService(taskConf);
if(taskConf.getPackageStatus() == TaskPackageStatus.ACTIVE) {
deploy(taskConf);
// activeTaskConfigurationQNameMap.put(taskQName, taskConf.getName());
}
}
}
}
TNotification[] notifications = humanTaskDU.getNotifications();
if (notifications != null) {
for (TNotification notification : notifications) {
QName notificationQName = new QName(humanTaskDU.getNamespace(), notification.getName());
NotificationConfiguration notificationConf =
new NotificationConfiguration(notification,
humanTaskDU.getNotificationServiceInfo(notificationQName),
humanTaskDU.getHumanInteractionsDefinition(),
humanTaskDU.getWSDLs(),
humanTaskDU.getNamespace(),
humanTaskDU.getName(),
getTenantAxisConfig(),
humanTaskDU.getPackageName(),
humanTaskDU.getVersion(),
humanTaskDU.getHumanTaskDefinitionFile());
notificationConf.setPackageStatus(humanTaskDU.getTaskPackageStatus());
configurations.add(notificationConf);
// taskConfigurations.add(notificationConf);
// taskBaseConfigurationHashMap.put(notificationConf.getName(), notificationConf);
// taskConfigsInPackage.add(notificationConf.getName());
if (!notificationConf.isErroneous()) {
// Deploy the axis2 service only for the active version of the task/notification
if(notificationConf.getPackageStatus() == TaskPackageStatus.ACTIVE) {
deploy(notificationConf);
// activeTaskConfigurationQNameMap.put(notificationQName, notificationConf.getName());
}
}
}
}
// Add task configuration to runtime only after axis2 service deployment is complete.This avoids the error
// condition if a service name is deployed with same name outside of this task package
for(HumanTaskBaseConfiguration configuration:configurations){
taskConfigurations.add(configuration);
taskBaseConfigurationHashMap.put(configuration.getName(), configuration);
taskConfigsInPackage.add(configuration.getName());
if(configuration.getPackageStatus() == TaskPackageStatus.ACTIVE) {
activeTaskConfigurationQNameMap.put(configuration.getDefinitionName(), configuration.getName());
}
}
for (TNotification inlineNotification : humanTaskDU.getInlineNotifications()) {
QName notificationQName = new QName(humanTaskDU.getNamespace(), inlineNotification.getName());
NotificationConfiguration notificationConf =
new NotificationConfiguration(inlineNotification,
humanTaskDU.getNotificationServiceInfo(notificationQName),
humanTaskDU.getHumanInteractionsDefinition(),
humanTaskDU.getWSDLs(),
humanTaskDU.getNamespace(),
humanTaskDU.getName(),
getTenantAxisConfig(),
humanTaskDU.getPackageName(),
humanTaskDU.getVersion(),
humanTaskDU.getHumanTaskDefinitionFile());
notificationConf.setPackageStatus(humanTaskDU.getTaskPackageStatus());
taskConfigurations.add(notificationConf);
taskConfigsInPackage.add(notificationConf.getName());
taskBaseConfigurationHashMap.put(notificationConf.getName(), notificationConf);
if(notificationConf.getPackageStatus() == TaskPackageStatus.ACTIVE){
activeTaskConfigurationQNameMap.put(notificationQName, notificationConf.getName());
}
}
taskConfigurationsInTaskPackage.put(humanTaskDU.getName(), taskConfigsInPackage);
return taskConfigsInPackage;
}
/**
* Performance a test deployment of the task in order to avoid deployment issues due to invalid task packages
* @param humanTaskDU
* @return
* @throws HumanTaskDeploymentException
*/
public void validateTaskConfig(HumanTaskDeploymentUnit humanTaskDU) throws HumanTaskDeploymentException, AxisFault {
boolean validateTask = HumanTaskServiceComponent.getHumanTaskServer().getServerConfig().getEnableTaskValidationBeforeDeployment();
if(validateTask){
TTask[] tasks = humanTaskDU.getTasks();
if (tasks != null) {
for (TTask task : tasks) {
QName taskQName = new QName(humanTaskDU.getNamespace(), task.getName());
TaskConfiguration taskConf =
new TaskConfiguration(task,
humanTaskDU.getTaskServiceInfo(taskQName),
humanTaskDU.getHumanInteractionsDefinition(),
humanTaskDU.getWSDLs(),
humanTaskDU.getNamespace(),
humanTaskDU.getName(),
getTenantAxisConfig(),
humanTaskDU.getPackageName(),
humanTaskDU.getVersion(),
humanTaskDU.getHumanTaskDefinitionFile());
if(taskConf.isErroneous()){
throw new HumanTaskDeploymentException(taskConf.getDeploymentError());
}
validateServiceCreationForTaskConfig(taskConf);
}
}
TNotification[] notifications = humanTaskDU.getNotifications();
if (notifications != null) {
for (TNotification notification : notifications) {
QName notificationQName = new QName(humanTaskDU.getNamespace(), notification.getName());
NotificationConfiguration notificationConf =
new NotificationConfiguration(notification,
humanTaskDU.getNotificationServiceInfo(notificationQName),
humanTaskDU.getHumanInteractionsDefinition(),
humanTaskDU.getWSDLs(),
humanTaskDU.getNamespace(),
humanTaskDU.getName(),
getTenantAxisConfig(),
humanTaskDU.getPackageName(),
humanTaskDU.getVersion(),
humanTaskDU.getHumanTaskDefinitionFile());
if (notificationConf.isErroneous()) {
throw new HumanTaskDeploymentException(notificationConf.getDeploymentError());
}
validateServiceCreationForTaskConfig(notificationConf);
}
}
for (TNotification inlineNotification : humanTaskDU.getInlineNotifications()) {
QName notificationQName = new QName(humanTaskDU.getNamespace(), inlineNotification.getName());
NotificationConfiguration notificationConf =
new NotificationConfiguration(inlineNotification,
humanTaskDU.getNotificationServiceInfo(notificationQName),
humanTaskDU.getHumanInteractionsDefinition(),
humanTaskDU.getWSDLs(),
humanTaskDU.getNamespace(),
humanTaskDU.getName(),
getTenantAxisConfig(),
humanTaskDU.getPackageName(),
humanTaskDU.getVersion(),
humanTaskDU.getHumanTaskDefinitionFile());
notificationConf.setPackageStatus(humanTaskDU.getTaskPackageStatus());
if(notificationConf.isErroneous()){
throw new HumanTaskDeploymentException(notificationConf.getDeploymentError());
}
validateServiceCreationForTaskConfig(notificationConf);
}
}
return;
}
/**
* When wsdl errors are there in the package, we use a dummy service creation step to validate all required parts
* are available in the wsdl
* @param taskConfig Task configuration object for this task package
* @throws HumanTaskDeploymentException HumanTaskDeployment Exception is thrown when an error happens
*/
private void validateServiceCreationForTaskConfig(HumanTaskBaseConfiguration taskConfig) throws HumanTaskDeploymentException {
try {
WSDL11ToAxisServiceBuilder serviceBuilder = createAxisServiceBuilder(taskConfig, taskConfig.getWSDL());
serviceBuilder.populateService();
} catch (AxisFault e) {
String errorMsg = "Error validating wsdl " + e.getMessage();
throw new HumanTaskDeploymentException(errorMsg, e);
}
}
/**
* Handles the deployment steps for the master node and salve node in the cluster
* @param humanTaskFile
* @throws Exception
*/
public void deploy(File humanTaskFile) throws Exception {
// Currently using the registry read/write mount property to determine whether this node is a master node
// or a salve node.
// Handle this properly with hazelcast leader for cluster scenario TODO
boolean isMasterServer = !isServerReadOnly();
// Versions of this ht package is already deployed
boolean isExistingPackage = false;
// Exactly matching ht package already exists
boolean isPackageReload = false;
DeploymentUnitDAO currentlyActiveTaskPackage = null;
String md5sum = HumanTaskStoreUtils.getMD5Checksum(humanTaskFile);
String packageName = FilenameUtils.removeExtension(humanTaskFile.getName());
List<DeploymentUnitDAO> existingDeploymentUnitsForPackage = getExistingDeploymentUnitsForPackage(packageName.trim());
if (existingDeploymentUnitsForPackage != null && existingDeploymentUnitsForPackage.size() > 0) {
isExistingPackage = true;
for (DeploymentUnitDAO dao : existingDeploymentUnitsForPackage) {
if ((dao.getStatus() == (TaskPackageStatus.ACTIVE))) {
// extract the currently active task package
currentlyActiveTaskPackage = dao;
if(dao.getChecksum().equals(md5sum)){
// Check whether the md5sum matches the active task package.
isPackageReload = true;
}
}
}
}
// We will only allow writes to db only for the master node to avoid duplicate version creation
if (isExistingPackage && isPackageReload) {
// Reload the existing versions of the human task package . No need of creating a new version of the package
// This could be due to server restart, deployment of the same package or master node has already deployed the
// new version of the package
// First check if the currently active task package is already loaded
String activePackageName = loadedPackages.get(currentlyActiveTaskPackage.getPackageName());
if (activePackageName!= null && activePackageName.equals(currentlyActiveTaskPackage.getName())) {
if(log.isDebugEnabled()) {
log.debug("This task package and its previous versions are already loaded " + activePackageName);
}
// This task package and its previous versions are already loaded , hence return
return;
}
// Load the existing versions of the package
reloadExistingTaskVersions(existingDeploymentUnitsForPackage, humanTaskFile, md5sum, isMasterServer);
return;
}
// New version of the package is being deployed on top of the existing version
if (isExistingPackage && !isPackageReload) {
if (isMasterServer) {
// Retire the existing version of the package and deploy the new version
// This could be two scenarios. Server restart with new version and deploying on existing version.
String activePackageName = loadedPackages.get(currentlyActiveTaskPackage.getPackageName());
if(activePackageName == null) {
// This is a server restart, we need to load existing versions
reloadExistingTaskVersions(existingDeploymentUnitsForPackage, humanTaskFile, md5sum, isMasterServer);
}
long newVersion = getNextVersion();
HumanTaskDeploymentUnit newDeploymentUnit = createNewDeploymentUnit(humanTaskFile, tenantId, newVersion, md5sum);
validateTaskConfig(newDeploymentUnit);
retireTaskPackageConfigurations(currentlyActiveTaskPackage.getName());
currentlyActiveTaskPackage.setStatus(TaskPackageStatus.RETIRED);
updateDeploymentUnitDao(currentlyActiveTaskPackage);
// Retiring of currently active package is complete.
// Create and deploy new version
deployNewTaskVersion(newDeploymentUnit, newVersion);
// Add new version of human task package to registry
// Update the zip and package properties in the registry
repository.handleNewHumanTaskPackageAddition(newDeploymentUnit, humanTaskFile);
// Successfully deployed the packages.
return;
} else {
// Cannot allow creation of a new version from slave nodes, deploy the new version on the master node
// first to avoid duplicate version creation
// Write log, issue warning and return
log.warn("Cannot deploy new version of the task in slave node. Hence deploy the task archive in master" +
"node fist");
return;
}
}
// First version of a new package is being deployed
if (!isMasterServer) {
// Issue warning, write warn message and return as we cannot allow deployment of new versions on slave nodes
// before deployment of the ht package in the master node
log.warn("Cannot deploy a new version on the package on the salve node first, " +
"Deploy the package on the master node first");
return;
}
// Create new version of deployment unit
// Process the human task configurations
// Store deployment unit information to the db
// Deploy axis2 services
// Adding HumanTask package the registry.
long newVersion = getNextVersion();
HumanTaskDeploymentUnit newDeploymentUnit = createNewDeploymentUnit(humanTaskFile, tenantId, newVersion, md5sum);
validateTaskConfig(newDeploymentUnit);
deployNewTaskVersion(newDeploymentUnit, newVersion);
repository.handleNewHumanTaskPackageAddition(newDeploymentUnit, humanTaskFile);
return;
}
/**
* Creates a new deployment unit from the given information
* @param humanTaskFile
* @param tenantId
* @param version
* @param md5sum
* @return
* @throws HumanTaskDeploymentException
*/
public HumanTaskDeploymentUnit createNewDeploymentUnit(File humanTaskFile, int tenantId, long version,
String md5sum) throws HumanTaskDeploymentException {
try {
ArchiveBasedHumanTaskDeploymentUnitBuilder builder = new ArchiveBasedHumanTaskDeploymentUnitBuilder(
humanTaskFile, tenantId, version, md5sum);
HumanTaskDeploymentUnit newHumanTaskDeploymentUnit = builder.createNewHumanTaskDeploymentUnit();
return newHumanTaskDeploymentUnit;
} catch (HumanTaskDeploymentException deploymentException) {
if (log.isDebugEnabled()) {
log.debug("humanTask:" + humanTaskFile.getName()
+ " deployment failed, removing the extracted human task directory.");
}
String versionedName = FilenameUtils.removeExtension(humanTaskFile.getName())
+ HumanTaskConstants.VERSION_SEPARATOR + version;
deleteHumanTaskPackageFromRepo(versionedName);
throw deploymentException;
}
}
/**
* Deploy the new task version using the given deployment unit
* This method will do the deployment of axis2 services, updating the task configuration lists, and updating the db
* @param deploymentUnit
* @param version
* @throws Exception
*/
public void deployNewTaskVersion(HumanTaskDeploymentUnit deploymentUnit ,long version) throws Exception {
if(log.isDebugEnabled()) {
log.debug("Deploying new package version " + deploymentUnit.getName());
}
deploy(deploymentUnit);
setNextVersion(version);
createDeploymentUnitDAO(deploymentUnit);
loadedPackages.put(deploymentUnit.getPackageName(), deploymentUnit.getName());
}
/**
* Retire the task configurations in a given task package
* @param versionedPackageName
*/
public void retireTaskPackageConfigurations(String versionedPackageName) {
if (versionedPackageName == null)
return;
if(log.isDebugEnabled()) {
log.debug("Retiring task package configuration for package" + versionedPackageName);
}
List<QName> qNames = taskConfigurationsInTaskPackage.get(versionedPackageName);
if (qNames != null) {
for (QName taskQName : qNames) {
HumanTaskBaseConfiguration humanTaskBaseConfiguration = taskBaseConfigurationHashMap.get(taskQName);
removeAxisServiceForTaskConfiguration(humanTaskBaseConfiguration);
humanTaskBaseConfiguration.setPackageStatus(TaskPackageStatus.RETIRED);
}
}
}
/**
* Reload existing task versions for a given deployment unit
* @param existingDeploymentUnitsForPackage
* @param archiveFile
* @param md5sum
* @throws HumanTaskDeploymentException
*/
public void reloadExistingTaskVersions(List<DeploymentUnitDAO> existingDeploymentUnitsForPackage,
File archiveFile, String md5sum, boolean isMasterServer) throws Exception {
// deployment units list should not be null, having a safety check anyway
if (existingDeploymentUnitsForPackage == null) {
return;
}
if(log.isDebugEnabled()) {
log.debug("Reloading existing task versions for human task archive [ " + archiveFile.getName() + "]");
}
for (DeploymentUnitDAO dao : existingDeploymentUnitsForPackage) {
if(!isMasterServer){
// We need to avoid deployment of already loaded packages
String versionedName = dao.getName();
List<QName> qNames = taskConfigurationsInTaskPackage.get(versionedName);
if(qNames!= null && qNames.size() > 0){
// This dao is already loaded
if(log.isDebugEnabled()){
log.debug("This is already loaded package, skipping " + versionedName);
}
continue;
}
}
try {
File taskDirectory = findHumanTaskPackageInFileSystem(dao,archiveFile);
ArchiveBasedHumanTaskDeploymentUnitBuilder deploymentUnitBuilder = null;
if (log.isDebugEnabled()) {
log.debug("Loading task : " + dao.getName());
}
if (taskDirectory.exists()) {
// This is an existing task configuration
deploymentUnitBuilder =
new ArchiveBasedHumanTaskDeploymentUnitBuilder(taskDirectory, tenantId, dao.getVersion(),
dao.getPackageName(), dao.getChecksum());
} else if(dao.getStatus() == TaskPackageStatus.ACTIVE){
// This node is a salve node and task is being reloaded or new version has been deployed on master
deploymentUnitBuilder = new ArchiveBasedHumanTaskDeploymentUnitBuilder(archiveFile,
tenantId, dao.getVersion(), md5sum);
} else {
String errMsg = "Error loading task. Cannot find the task directory for retired task " +
dao.getName();
log.error(errMsg);
throw new HumanTaskDeploymentException(errMsg);
}
// Check whether this is a new version deployment on a slave node
if(!isMasterServer && dao.getStatus() == TaskPackageStatus.ACTIVE){
String currentDeployedVersion = loadedPackages.get(dao.getPackageName());
if(currentDeployedVersion != null && currentDeployedVersion.equals(dao.getName()) == false) {
// This is a new version on the salve node , retire the existing version
retireTaskPackageConfigurations(currentDeployedVersion);
}
}
HumanTaskDeploymentUnit taskDeploymentUnit =
deploymentUnitBuilder.createNewHumanTaskDeploymentUnit();
taskDeploymentUnit.setTaskPackageStatus(dao.getStatus());
deploy(taskDeploymentUnit);
if(dao.getStatus() == TaskPackageStatus.ACTIVE) {
// Add the active package to the loaded packages
loadedPackages.put(dao.getPackageName(), dao.getName());
}
} catch (HumanTaskDeploymentException e) {
String errMsg = "Error loading the task configuration ";
log.error(errMsg, e);
throw e;
}
}
}
private void createCallBackService(TaskConfiguration taskConf)
throws HumanTaskDeploymentException {
EndpointConfiguration endpointConfig =
taskConf.getEndpointConfiguration(taskConf.getCallbackServiceName().getLocalPart(),
taskConf.getCallbackPortName());
CallBackServiceImpl callbackService = new CallBackServiceImpl(tenantId,
taskConf.getCallbackServiceName(), taskConf.getCallbackPortName(),
taskConf.getName(), taskConf.getResponseWSDL(), taskConf.getResponseOperation(),
endpointConfig);
taskConf.setCallBackService(callbackService);
}
private void deploy(HumanTaskBaseConfiguration taskConfig) throws HumanTaskDeploymentException {
if (taskConfig != null) {
/**
* Creating AxisService for HI
*/
if (log.isDebugEnabled()) {
log.debug("Deploying task " + taskConfig.getName());
}
AxisService axisService;
Definition wsdlDef = taskConfig.getWSDL();
if (taskConfig instanceof TaskConfiguration) {
//to get the task id as response
wsdlDef.getPortType(taskConfig.getPortType()).getOperation(
taskConfig.getOperation(),
null, null).setStyle(OperationType.REQUEST_RESPONSE);
} else {
//ONE_WAY no feed back for NOTIFICATIONS
wsdlDef.getPortType(taskConfig.getPortType()).getOperation(
taskConfig.getOperation(),
null, null).setStyle(OperationType.ONE_WAY);
}
WSDL11ToAxisServiceBuilder serviceBuilder = createAxisServiceBuilder(taskConfig, wsdlDef);
try {
axisService = createAxisService(serviceBuilder, taskConfig);
ServiceConfigurationUtil.configureService(axisService,
taskConfig.getEndpointConfiguration(
taskConfig.getServiceName().getLocalPart(),
taskConfig.getPortName()),
getConfigContext());
ArrayList<AxisService> serviceList = new ArrayList<AxisService>();
serviceList.add(axisService);
DeploymentEngine.addServiceGroup(createServiceGroupForService(axisService), serviceList,
null, null, getTenantAxisConfig());
if (log.isDebugEnabled()) {
log.debug(" Published axis2 service " + axisService.getName() + " for task " + taskConfig.getName());
}
} catch (AxisFault axisFault) {
String errMsg = "Error populating the service";
log.error(errMsg);
throw new HumanTaskDeploymentException(errMsg, axisFault);
}
}
}
//Creates the AxisServiceBuilder object.
private WSDL11ToAxisServiceBuilder createAxisServiceBuilder(
HumanTaskBaseConfiguration taskConfig, Definition wsdlDef) {
WSDL11ToAxisServiceBuilder serviceBuilder =
new WSDL11ToAxisServiceBuilder(wsdlDef,
taskConfig.getServiceName(), taskConfig.getPortName());
String wsdlBaseURI = wsdlDef.getDocumentBaseURI();
serviceBuilder.setBaseUri(wsdlBaseURI);
/*we don't need custom resolvers since registry takes care of it*/
serviceBuilder.setCustomResolver(new DefaultURIResolver());
URI wsdlBase = null;
try {
wsdlBase = new URI(convertToVaildURI(wsdlBaseURI));
} catch (Exception e) {
String error = "Error occurred while creating AxisServiceBuilder.";
log.error(error);
}
serviceBuilder.setCustomWSDLResolver(new HumanTaskWSDLLocator(wsdlBase));
serviceBuilder.setServerSide(true);
return serviceBuilder;
}
//Creates the AxisService object from the provided ServiceBuilder object.
private AxisService createAxisService(WSDL11ToAxisServiceBuilder serviceBuilder, HumanTaskBaseConfiguration config)
throws AxisFault {
AxisService axisService;
axisService = serviceBuilder.populateService();
axisService.setParent(getTenantAxisConfig());
axisService.setWsdlFound(true);
axisService.setCustomWsdl(true);
//axisService.setFileName(new URL(taskConfig.getWsdlDefLocation()));
axisService.setClassLoader(getTenantAxisConfig().getServiceClassLoader());
Utils.setEndpointsToAllUsedBindings(axisService);
axisService.addParameter(new Parameter("modifyUserWSDLPortAddress", "true"));
/* Setting service type to use in service management*/
axisService.addParameter(ServerConstants.SERVICE_TYPE, "humantask");
/* Fix for losing of security configuration when updating human-task package*/
axisService.addParameter(new Parameter(CarbonConstants.PRESERVE_SERVICE_HISTORY_PARAM,
"true"));
Iterator operations = axisService.getOperations();
AxisHumanTaskMessageReceiver msgReceiver = new AxisHumanTaskMessageReceiver();
msgReceiver.setHumanTaskEngine(HumanTaskServiceComponent.getHumanTaskServer().
getTaskEngine());
// Setting the task configuration to the message receiver. Hence no need to search for task configuration, when
// the actual task invocation happens, we will already have the task configuration attached to the message receiver
// itself
msgReceiver.setTaskBaseConfiguration(config);
while (operations.hasNext()) {
AxisOperation operation = (AxisOperation) operations.next();
// Setting Message Receiver even if operation has a message receiver specified.
// This is to fix the issue when build service configuration using services.xml(Always RPCMessageReceiver
// is set to operations).
operation.setMessageReceiver(msgReceiver);
getTenantAxisConfig().getPhasesInfo().setOperationPhases(operation);
}
Set<String> exposedTransports = getTenantAxisConfig().getTransportsIn().keySet();
//Add the transports to axis2 service by reading from the tenant transport config
for (String transport : exposedTransports) {
axisService.addExposedTransport(transport);
}
if (HumanTaskServiceComponent.getHumanTaskServer().getServerConfig().isHtCoordinationEnabled()
&& HumanTaskServiceComponent.getHumanTaskServer().getServerConfig().isTaskRegistrationEnabled()
&& config.getConfigurationType() == HumanTaskBaseConfiguration.ConfigurationType.TASK) {
// Only Engage coordination module in-case of Tasks. Coordination module is not required for notifications
axisService.engageModule(getConfigContext().getAxisConfiguration().getModule("htcoordination"));
}
return axisService;
}
private AxisServiceGroup createServiceGroupForService(AxisService svc) throws AxisFault {
AxisServiceGroup svcGroup = new AxisServiceGroup();
svcGroup.setServiceGroupName(svc.getName());
svcGroup.addService(svc);
svcGroup.addParameter(new Parameter(CarbonConstants.PRESERVE_SERVICE_HISTORY_PARAM, "true"));
return svcGroup;
}
public HumanTaskBaseConfiguration getTaskConfiguration(QName portType, String operation) {
for (HumanTaskBaseConfiguration taskConf : taskConfigurations) {
if (taskConf.getPortType().equals(portType) && taskConf.getOperation().equals(operation)) {
return taskConf;
}
}
return null;
}
/**
* @return : The tenant id of this task store.
*/
public int getTenantId() {
return tenantId;
}
/**
* @return : The tenant axis configuration of this task store.
*/
public AxisConfiguration getTenantAxisConfig() {
return configContext.getAxisConfiguration();
}
/**
* @return : The deployement repository location.
*/
public File getHumanTaskDeploymentRepo() {
return humanTaskDeploymentRepo;
}
/**
* @param humanTaskDeploymentRepo : The deployment repository location to set.
*/
public void setHumanTaskDeploymentRepo(File humanTaskDeploymentRepo) {
this.humanTaskDeploymentRepo = humanTaskDeploymentRepo;
}
/**
* @return : The list of task configurations in the store.
*/
public List<HumanTaskBaseConfiguration> getTaskConfigurations() {
return this.taskConfigurations;
}
/**
* Gets the simple task definition information for a given package name.
*
* @param packageName : The package name.
* @return : The matching package information list.
*/
public List<SimpleTaskDefinitionInfo> getTaskConfigurationInfoListForPackage(
String packageName) {
List<SimpleTaskDefinitionInfo> matchingTaskDefinitions = new ArrayList<SimpleTaskDefinitionInfo>();
for (HumanTaskBaseConfiguration taskBaseConfiguration : this.taskConfigurations) {
if (taskBaseConfiguration.getPackageName().equals(packageName)) {
matchingTaskDefinitions.add(DeploymentUtil.getSimpleTaskDefinitionInfo(taskBaseConfiguration));
}
}
return matchingTaskDefinitions;
}
/**
* Gets the list of SimpleTaskDefinitionInfo objects for the all the HumanTaskBaseConfiguration objects in this store.
*
* @return :
*/
public List<SimpleTaskDefinitionInfo> getTaskConfigurationInfoList() {
return DeploymentUtil.getTaskConfigurationsInfoList(this.getTaskConfigurations());
}
/**
* Un Deploys a given HumanTask package.
* If the config is hard undeployment,delete all instance information from the db and delete the task configs
* If the config is soft undeployment, leave all task instances and undeploy the service and the configuration only
*
*
* @param packageName : The package name to be unDeployed.
*/
public void unDeploy(String packageName) {
if(log.isDebugEnabled()){
log.debug("Un deploying task package : "+ packageName);
}
try {
removeMatchingPackage(packageName);
} catch (Exception e) {
log.error("Error in deploying task package", e);
}
}
/**
* Gets the HumanTaskBaseConfiguration object for the given task QName.
*
* @param taskName : The task name of which the task configuration is to be retrieved.
* @return : The matching HumanTaskBaseConfiguration object.
*/
public HumanTaskBaseConfiguration getTaskConfiguration(QName taskName) {
return taskBaseConfigurationHashMap.get(taskName);
}
public HumanTaskBaseConfiguration getActiveTaskConfiguration(QName taskQname){
QName qName = activeTaskConfigurationQNameMap.get(taskQname);
if(qName != null){
return taskBaseConfigurationHashMap.get(qName);
}
return null;
}
private void removeMatchingPackageVersion(String versionedPackageName, TaskPackageStatus status){
List<QName> taskConfigurationQNameList = taskConfigurationsInTaskPackage.get(versionedPackageName);
if(taskConfigurationQNameList != null){
for(QName name:taskConfigurationQNameList){
HumanTaskBaseConfiguration humanTaskBaseConfiguration = taskBaseConfigurationHashMap.get(name);
if(humanTaskBaseConfiguration != null){
taskConfigurations.remove(humanTaskBaseConfiguration);
if(status == TaskPackageStatus.ACTIVE){
removeAxisServiceForTaskConfiguration(humanTaskBaseConfiguration);
}
activeTaskConfigurationQNameMap.remove(humanTaskBaseConfiguration.getDefinitionName());
}
taskBaseConfigurationHashMap.remove(name);
}
}
taskConfigurationsInTaskPackage.remove(versionedPackageName);
// Now delete the file from repository
deleteHumanTaskPackageFromRepo(versionedPackageName);
}
private boolean removeMatchingPackage(final String packageName) throws Exception {
if(!isServerReadOnly()){
// This is the master server
engine.getScheduler().execTransaction(new Callable<Object>() {
public Object call() throws Exception {
HumanTaskDAOConnection connection = engine.getDaoConnectionFactory().getConnection();
List<DeploymentUnitDAO> deploymentUnitsForPackageName = connection.getDeploymentUnitsForPackageName(tenantId, packageName);
for(DeploymentUnitDAO deploymentUnitDAO:deploymentUnitsForPackageName){
removeMatchingPackageVersion(deploymentUnitDAO.getName(), deploymentUnitDAO.getStatus());
}
List<TaskDAO> matchingTaskInstances = connection.getMatchingTaskInstances(packageName, tenantId);
for(TaskDAO taskDAO:matchingTaskInstances){
taskDAO.deleteInstance();
}
connection.deleteDeploymentUnits(packageName, tenantId);
return null;
}
});
loadedPackages.remove(packageName);
repository.handleHumanTaskPackageUndeploy(packageName);
} else {
// Slave nodes
List<HumanTaskBaseConfiguration> matchingTaskConfigurations = new ArrayList<HumanTaskBaseConfiguration>();
for(HumanTaskBaseConfiguration configuration:taskConfigurations){
if(configuration.getPackageName().equals(packageName)){
matchingTaskConfigurations.add(configuration);
}
}
for(HumanTaskBaseConfiguration configuration:matchingTaskConfigurations){
String taskPackageName = configuration.getPackageName();
long version = configuration.getVersion();
String versionedPackageName = taskPackageName + "-" + version;
removeMatchingPackageVersion(versionedPackageName, configuration.getPackageStatus());
}
loadedPackages.remove(packageName);
}
return true;
}
private boolean removeMatchingPackageAfterTaskObsoletion(String packageName) {
final HumanTaskEngine taskEngine = HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine();
boolean matchingPackagesFound = false;
final int tId = this.tenantId;
List<HumanTaskBaseConfiguration> matchingTaskConfigurations =
new ArrayList<HumanTaskBaseConfiguration>();
for (final HumanTaskBaseConfiguration configuration : this.getTaskConfigurations()) {
if (configuration.getPackageName().equals(packageName)) {
matchingTaskConfigurations.add(configuration);
try {
taskEngine.getScheduler().execTransaction(new Callable<Object>() {
public Object call() throws Exception {
taskEngine.getDaoConnectionFactory().getConnection().obsoleteTasks(
configuration.getName().toString(), tId);
return null;
}
});
} catch (Exception e) {
String errMsg = "Error occurred while making tasks obsolete";
log.error(errMsg);
throw new HumanTaskRuntimeException(errMsg, e);
}
// we don't want the associated service once the task configuration is removed!
removeAxisServiceForTaskConfiguration(configuration);
matchingPackagesFound = true;
}
}
// remove the task configurations with the matching package name.
for (HumanTaskBaseConfiguration removableConfiguration : matchingTaskConfigurations) {
this.getTaskConfigurations().remove(removableConfiguration);
}
return matchingPackagesFound;
}
/**
* Remove the service associated with the task configuration.
*
* @param removableConfiguration : The task configuration.
*/
public void removeAxisServiceForTaskConfiguration(
HumanTaskBaseConfiguration removableConfiguration) {
try {
//If there are matching axis services we remove them.
if (removableConfiguration.getServiceName() != null &&
StringUtils.isNotEmpty(removableConfiguration.getServiceName().getLocalPart())) {
String axisServiceName = removableConfiguration.getServiceName().getLocalPart();
AxisService axisService = getTenantAxisConfig().getService(axisServiceName);
if (axisService != null) {
axisService.releaseSchemaList();
getTenantAxisConfig().stopService(axisServiceName);
getTenantAxisConfig().removeServiceGroup(axisServiceName);
if (log.isDebugEnabled()) {
log.debug("Un deployed axis2 service " + axisServiceName);
}
} else {
log.warn("Could not find matching AxisService in " +
"Tenant AxisConfiguration for service name :" + axisServiceName);
}
} else {
log.warn(String.format("Could not find a associated service name for " +
"[%s] configuration [%s]",
removableConfiguration.getConfigurationType(),
removableConfiguration.getName().toString()));
}
} catch (AxisFault axisFault) {
String error = "Error occurred while removing the axis service " +
removableConfiguration.getServiceName();
log.error(error);
throw new HumanTaskRuntimeException(error, axisFault);
}
}
/**
* deletes the human task package archive from the repository.
*
* @param packageName : The package name to be deleted.
*/
public void deleteHumanTaskArchive(String packageName) {
File humanTaskArchive = getHumanTaskArchiveLocation(packageName);
log.info("UnDeploying HumanTask package " + packageName + ". Deleting HumanTask archive " +
humanTaskArchive.getName() + "....");
if (humanTaskArchive.exists()) {
if (!humanTaskArchive.delete()) {
//For windows
humanTaskArchive.deleteOnExit();
}
} else {
log.warn("HumanTask archive [" + humanTaskArchive.getAbsolutePath() +
"] not found. This can happen if you delete " +
"the HumanTask archive from the file system.");
}
}
/**
* Return the human task archive file for the given package name.
*
* @param packageName : The human task archive package name.
* @return : The matching human task archive file.
*/
public File getHumanTaskArchiveLocation(String packageName) {
String repoPath = getTenantAxisConfig().getRepository().getPath();
int length = repoPath.length();
String lastChar = repoPath.substring(length - 1);
if (!File.separator.equals(lastChar)) {
repoPath += File.separator;
}
String htArchiveLocation = repoPath + HumanTaskConstants.HUMANTASK_REPO_DIRECTORY + File.separator +
packageName + "." + HumanTaskConstants.HUMANTASK_PACKAGE_EXTENSION;
return new File(htArchiveLocation);
}
public ConfigurationContext getConfigContext() {
return configContext;
}
public Cache getCache(String cacheName) {
CacheManager cacheManager = Caching.getCacheManagerFactory().getCacheManager(HumanTaskConstants.HT_CACHE_MANAGER);
if (cacheManager != null) {
return cacheManager.getCache(cacheName);
}
return null;
}
private void initializeCaches() {
Caching.getCacheManagerFactory().getCacheManager(HumanTaskConstants.HT_CACHE_MANAGER);
// Currently there is no way to obtain the same cache again since when all the objects in the cache are removed, the
// cache is also removed.Hence using the default cache
// final int cacheExpiryDuration = HumanTaskServiceComponent.getHumanTaskServer().getServerConfig().getCacheExpiryDuration();
// CacheManager humantaskCacheManager = Caching.getCacheManagerFactory().getCacheManager(HumanTaskConstants.HT_CACHE_MANAGER);
// humantaskCacheManager.<String, Boolean>createCacheBuilder(HumanTaskConstants.HT_CACHE_ROLE_NAME_LIST)
// .setExpiry(CacheConfiguration.ExpiryType.MODIFIED, new CacheConfiguration.Duration(TimeUnit.SECONDS, cacheExpiryDuration))
// .setStoreByValue(false)
// .build();
//
// humantaskCacheManager.<String, Boolean>createCacheBuilder(HumanTaskConstants.HT_CACHE_USER_NAME_LIST)
// .setExpiry(CacheConfiguration.ExpiryType.MODIFIED, new CacheConfiguration.Duration(TimeUnit.SECONDS, cacheExpiryDuration))
// .setStoreByValue(false)
// .build();
//
// humantaskCacheManager.<String, List<String>>createCacheBuilder(HumanTaskConstants.HT_CACHE_ROLE_NAME_LIST_FOR_USER)
// .setExpiry(CacheConfiguration.ExpiryType.MODIFIED, new CacheConfiguration.Duration(TimeUnit.SECONDS, cacheExpiryDuration))
// .setStoreByValue(false)
// .build();
//
// humantaskCacheManager.<String, List<String>>createCacheBuilder(HumanTaskConstants.HT_CACHE_USER_NAME_LIST_FOR_ROLE)
// .setExpiry(CacheConfiguration.ExpiryType.MODIFIED, new CacheConfiguration.Duration(TimeUnit.SECONDS, cacheExpiryDuration))
// .setStoreByValue(false)
// .build();
}
public void unloadCaches(){
if(HumanTaskServiceComponent.getHumanTaskServer().getServerConfig().isCachingEnabled()){
CacheManagerFactory cacheManagerFactory = Caching.getCacheManagerFactory();
if(cacheManagerFactory != null){
if(log.isDebugEnabled()) {
log.debug("Closing the cache manager factory for the tenant");
}
cacheManagerFactory.close();
}
}
}
//removes the package from the human task package repository.
private void deleteHumanTaskPackageFromRepo(String packageName) {
String humanTaskPackageLocation = this.humanTaskDeploymentRepo.getAbsolutePath() +
File.separator + packageName;
File humanTaskPackageDirectory = new File(humanTaskPackageLocation);
if(log.isDebugEnabled()) {
log.debug("Deleting human task package from directory " + humanTaskPackageDirectory);
}
log.info("UnDeploying HumanTask package. " + "Deleting " + packageName + " HumanTask package");
if (humanTaskPackageDirectory.exists()) {
FileManipulator.deleteDir(humanTaskPackageDirectory);
} else {
log.warn("HumanTask package " + humanTaskPackageDirectory.getAbsolutePath() +
" not found. This can happen if you delete " +
"the HumanTask package from the file system.");
}
}
/**
* Update the task configurations with the given package status.
*
* @param packageName : package Name.
* @param status : The new status
*/
public void updateTaskStatusForPackage(String packageName, TaskPackageStatus status) {
for (HumanTaskBaseConfiguration taskBaseConfiguration : this.taskConfigurations) {
if (taskBaseConfiguration.getPackageName().equals(packageName)) {
taskBaseConfiguration.setPackageStatus(status);
}
}
}
private String convertToVaildURI(String filePath) {
File tmpFile = new File(filePath);
if (tmpFile.exists()) {
return tmpFile.toURI().toString();
}
// if not a file path
return filePath;
}
public long getNextVersion() throws Exception {
long version = HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine().getScheduler().
execTransaction(new Callable<Long>() {
public Long call() throws Exception {
HumanTaskEngine engine = HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine();
HumanTaskDAOConnection daoConn = engine.getDaoConnectionFactory().getConnection();
return daoConn.getNextVersion();
}
});
return version;
}
public void setNextVersion(final Long version) throws Exception {
HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine().getScheduler().
execTransaction(new Callable<Long>() {
public Long call () throws Exception {
HumanTaskEngine engine = HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine();
HumanTaskDAOConnection daoConn = engine.getDaoConnectionFactory().getConnection();
daoConn.setNextVersion(version.longValue());
return version;
}
});
}
private List<DeploymentUnitDAO> getExistingDeploymentUnitsForPackage(final String packageName) throws Exception {
List<DeploymentUnitDAO> deploymentUnitsForPackageName = engine.getScheduler().
execTransaction(new Callable<List<DeploymentUnitDAO>>() {
public List<DeploymentUnitDAO> call() throws Exception {
HumanTaskDAOConnection daoConnection = engine.getDaoConnectionFactory().getConnection();
List<DeploymentUnitDAO> deploymentUnitsForPackageName = null;
if (daoConnection != null) {
deploymentUnitsForPackageName = daoConnection.
getDeploymentUnitsForPackageName(tenantId, packageName);
}
return deploymentUnitsForPackageName;
}
});
return deploymentUnitsForPackageName;
}
private boolean isServerReadOnly() {
try {
RegistryContext registryContext = HumanTaskServiceComponent.getRegistryService().getConfigSystemRegistry().getRegistryContext();
if (registryContext.isReadOnly()) {
return true;
}
} catch (RegistryException e) {
log.error("Error while reading registry status");
}
return false;
}
public DeploymentUnitDAO createDeploymentUnitDAO(final HumanTaskDeploymentUnit deploymentUnit) throws Exception {
return HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine().getScheduler().
execTransaction(new Callable<DeploymentUnitDAO>() {
public DeploymentUnitDAO call() throws Exception {
HumanTaskEngine engine = HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine();
HumanTaskDAOConnection daoConn = engine.getDaoConnectionFactory().getConnection();
return daoConn.createDeploymentUnitDAO(deploymentUnit, tenantId);
}
});
}
public void updateDeploymentUnitDao(final DeploymentUnitDAO deploymentUnit) throws Exception {
HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine().getScheduler().
execTransaction(new Callable<DeploymentUnitDAO>() {
public DeploymentUnitDAO call() throws Exception {
EntityManager entityManager = engine.getDaoConnectionFactory().getConnection().getEntityManager();
entityManager.merge(deploymentUnit);
return deploymentUnit;
}
});
}
/**
* This method provides the extracted human task package location in file system.
* If human task package does not exist in file system then package will be exported from registry.
* If human task package does not exist in registry then package will be imported to registry from file system.
* If registry and file location don't have extracted human task package content then exception will be thrown
*
* @param dudao
* @return File
* @throws HumanTaskDeploymentException
*/
private File findHumanTaskPackageInFileSystem(DeploymentUnitDAO dudao, File archiveFile) throws Exception {
String duName = dudao.getName();
log.info("Looking for HumanTask package in file system for deployment unit " + duName);
File humanTaskDUDirectory = new File(humanTaskDeploymentRepo, duName);
String registryCollectionPath = HumanTaskPackageRepositoryUtils.getResourcePathForHumanTaskPackageContent
(dudao.getPackageName(), dudao.getName());
try {
if (humanTaskDUDirectory.exists()) {
if (!tenantConfigRegistry.resourceExists(registryCollectionPath)) {
// Import human task package content to registry from file system
repository.restoreHumanTaskPackageContentInRegistry(dudao, archiveFile);
}
return humanTaskDUDirectory;
} else {
if (tenantConfigRegistry.resourceExists(registryCollectionPath)) {
if (!humanTaskDUDirectory.exists() && !humanTaskDUDirectory.mkdirs()) {
String errMsg = "Error creating HumanTask deployment unit repository for " + "tenant " +
tenantId;
log.error(errMsg);
log.error("Failed to load HumanTask deployment unit " + duName + " due to above error.");
throw new HumanTaskDeploymentException(errMsg);
}
// Export human task package content from registry to file system
RegistryClientUtils.exportFromRegistry(humanTaskDUDirectory, registryCollectionPath,
tenantConfigRegistry);
return humanTaskDUDirectory;
} else {
String errMsg = "Expected resource: " + registryCollectionPath + " not found in the registry";
log.error(errMsg);
throw new HumanTaskDeploymentException(errMsg);
}
}
} catch (RegistryException re) {
String errMsg = "Error while exporting deployment unit: " + duName + " to file system from the " +
"registry.";
log.error(errMsg, re);
throw new HumanTaskDeploymentException(errMsg, re);
}
}
}