blob: 13eeec2b3e8b866edd6ed8567abb051ae5add1ef [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2011 The University of Manchester
*
* Modifications to the initial code base are copyright of their
* respective authors, or their employers as appropriate.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
******************************************************************************/
package uk.org.taverna.platform.execution.impl;
import java.net.URI;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import uk.org.taverna.platform.capability.api.ActivityConfigurationException;
import uk.org.taverna.platform.capability.api.ActivityNotFoundException;
import uk.org.taverna.platform.capability.api.DispatchLayerConfigurationException;
import uk.org.taverna.platform.capability.api.DispatchLayerNotFoundException;
import uk.org.taverna.platform.execution.api.ExecutionEnvironment;
import uk.org.taverna.platform.execution.api.ExecutionEnvironmentService;
import uk.org.taverna.platform.execution.api.ExecutionService;
import uk.org.taverna.scufl2.api.activity.Activity;
import uk.org.taverna.scufl2.api.common.NamedSet;
import uk.org.taverna.scufl2.api.common.Scufl2Tools;
import uk.org.taverna.scufl2.api.configurations.Configuration;
import uk.org.taverna.scufl2.api.core.Processor;
import uk.org.taverna.scufl2.api.profiles.ProcessorBinding;
import uk.org.taverna.scufl2.api.profiles.Profile;
import com.fasterxml.jackson.databind.JsonNode;
/**
* Implementation of the ExecutionEnvironmentService.
*
* @author David Withers
*/
public class ExecutionEnvironmentServiceImpl implements ExecutionEnvironmentService {
private static final Logger logger = Logger.getLogger(ExecutionEnvironmentServiceImpl.class.getName());
@SuppressWarnings("unused")
private final Scufl2Tools scufl2Tools = new Scufl2Tools();
private Set<ExecutionService> executionServices;
@Override
public Set<ExecutionEnvironment> getExecutionEnvironments() {
Set<ExecutionEnvironment> executionEnvironments = new HashSet<>();
for (ExecutionService executionService : executionServices)
executionEnvironments.addAll(executionService
.getExecutionEnvironments());
return executionEnvironments;
}
@Override
public Set<ExecutionEnvironment> getExecutionEnvironments(Profile profile) {
Set<ExecutionEnvironment> validExecutionEnvironments = new HashSet<>();
for (ExecutionEnvironment executionEnvironment : getExecutionEnvironments())
if (isValidExecutionEnvironment(executionEnvironment, profile))
validExecutionEnvironments.add(executionEnvironment);
return validExecutionEnvironments;
}
/**
* Sets the ExecutionServices that will be used to find ExecutionEnvironments.
*
* @param executionServices
* the ExecutionServices that will be used to find ExecutionEnvironments
*/
public void setExecutionServices(Set<ExecutionService> executionServices) {
this.executionServices = executionServices;
}
/**
* @param executionEnvironment
* @param profile
* @return
*/
private boolean isValidExecutionEnvironment(ExecutionEnvironment executionEnvironment,
Profile profile) {
NamedSet<ProcessorBinding> processorBindings = profile.getProcessorBindings();
for (ProcessorBinding processorBinding : processorBindings) {
Activity activity = processorBinding.getBoundActivity();
if (!executionEnvironment.activityExists(activity.getType())) {
logger.fine(MessageFormat.format("{0} does not contain activity {1}",
executionEnvironment.getName(), activity.getType()));
return false;
}
Configuration activityConfiguration = activity.getConfiguration();
if (!isValidActivityConfiguration(executionEnvironment, activityConfiguration, activity)) {
logger.fine(MessageFormat.format("Invalid activity configuration for {1} in {0}",
executionEnvironment.getName(), activity.getType()));
return false;
}
@SuppressWarnings("unused")
Processor processor = processorBinding.getBoundProcessor();
// TODO check that environment has required dispatch layers for processor configuration
// for (DispatchStackLayer dispatchStackLayer : processor.getDispatchStack()) {
// if (!executionEnvironment.dispatchLayerExists(dispatchStackLayer
// .getType())) {
// logger.fine(MessageFormat.format("{0} does not contain dispatch layer {1}",
// executionEnvironment.getName(),
// dispatchStackLayer.getType()));
// return false;
// }
//
// List<Configuration> dispatchLayerConfigurations = scufl2Tools.configurationsFor(dispatchStackLayer, profile);
// if (dispatchLayerConfigurations.size() > 1) {
// logger.fine(MessageFormat.format("{0} contains multiple configurations for dispatch layer {1}",
// executionEnvironment.getName(),
// dispatchStackLayer.getType()));
// } else if (dispatchLayerConfigurations.size() == 1) {
// if (!isValidDispatchLayerConfiguration(executionEnvironment, dispatchLayerConfigurations.get(0), dispatchStackLayer)) {
// logger.fine(MessageFormat.format("Invalid dispatch layer configuration for {1} in {0}",
// executionEnvironment.getName(), dispatchStackLayer.getType()));
// return false;
// }
// }
// }
}
return true;
}
private boolean isValidActivityConfiguration(ExecutionEnvironment executionEnvironment,
Configuration configuration, Activity activity) {
try {
configuration.getJson();
configuration.getJsonSchema();
@SuppressWarnings("unused")
JsonNode environmentSchema = executionEnvironment.getActivityConfigurationSchema(activity.getType());
// TODO validate against schema
} catch (ActivityNotFoundException e) {
logger.fine(MessageFormat.format("{0} does not contain activity {1}",
executionEnvironment.getName(), activity.getType()));
return false;
} catch (ActivityConfigurationException e) {
logger.fine(MessageFormat.format("Configuration for {1} is incorrect in {0}",
executionEnvironment.getName(), activity.getType()));
return false;
}
return true;
}
@SuppressWarnings("unused")
private boolean isValidDispatchLayerConfiguration(ExecutionEnvironment executionEnvironment,
Configuration configuration, URI dispatchLayerType) {
try {
JsonNode environmentSchema = executionEnvironment.getDispatchLayerConfigurationSchema(dispatchLayerType);
// TODO validate against schema
} catch (DispatchLayerNotFoundException e) {
logger.fine(MessageFormat.format("{0} does not contain dispatch layer {1}",
executionEnvironment.getName(), dispatchLayerType));
return false;
} catch (DispatchLayerConfigurationException e) {
logger.fine(MessageFormat.format("Configuration for {1} is incorrect in {0}",
executionEnvironment.getName(), dispatchLayerType));
return false;
}
return true;
}
// /**
// * @param propertyResourceDefinition
// * @param propertyResource
// * @return
// */
// private boolean isValidPropertyResource(Configuration configuration,
// PropertyResourceDefinition propertyResourceDefinition, PropertyResource propertyResource) {
// if (!propertyResourceDefinition.getTypeURI().equals(propertyResource.getTypeURI())) {
// logger.fine(MessageFormat.format(
// "Property type {0} does not equal property definition type {1}",
// propertyResource.getTypeURI(), propertyResourceDefinition.getTypeURI()));
// return false;
// }
// List<PropertyDefinition> propertyDefinitions = propertyResourceDefinition
// .getPropertyDefinitions();
// Map<URI, SortedSet<PropertyObject>> properties = propertyResource.getProperties();
// for (PropertyDefinition propertyDefinition : propertyDefinitions) {
// SortedSet<PropertyObject> propertySet = properties.get(propertyDefinition
// .getPredicate());
// if (propertySet == null) {
// if (propertyDefinition.isRequired()) {
// logger.fine(MessageFormat.format("Required property {0} is missing",
// propertyDefinition.getPredicate()));
// return false;
// }
// } else {
// if (propertySet.size() == 0 && propertyDefinition.isRequired()) {
// logger.fine(MessageFormat.format("Required property {0} is missing",
// propertyDefinition.getPredicate()));
// return false;
// }
// if (propertySet.size() > 1 && !propertyDefinition.isMultiple()) {
// logger.fine(MessageFormat.format(
// "{0} properties found for singleton property {1}", propertySet.size(),
// propertyDefinition.getPredicate()));
// return false;
// }
// if (propertySet.size() > 1 && propertyDefinition.isMultiple() && propertyDefinition.isOrdered()) {
// logger.fine(MessageFormat.format(
// "{0} property lists found for property {1}", propertySet.size(),
// propertyDefinition.getPredicate()));
// return false;
// }
// for (PropertyObject property : propertySet) {
// if (propertyDefinition.isMultiple() && propertyDefinition.isOrdered()) {
// if (property instanceof PropertyList) {
// PropertyList propertyList = (PropertyList) property;
// for (PropertyObject propertyObject : propertyList) {
// if (!isValidProperty(configuration, propertyDefinition, propertyObject)) {
// logger.fine(MessageFormat.format("Property {0} is invalid",
// propertyDefinition.getPredicate()));
// return false;
// }
// }
// }
//
// } else if (!isValidProperty(configuration, propertyDefinition, property)) {
// logger.fine(MessageFormat.format("Property {0} is invalid",
// propertyDefinition.getPredicate()));
// return false;
// }
// }
// }
// }
// return true;
// }
//
// /**
// * @param propertyDefinition
// * @param property
// * @return
// */
// private boolean isValidProperty(Configuration configuration,
// PropertyDefinition propertyDefinition, PropertyObject property) {
// if (propertyDefinition instanceof PropertyLiteralDefinition) {
// if (property instanceof PropertyLiteral) {
// PropertyLiteralDefinition propertyLiteralDefinition = (PropertyLiteralDefinition) propertyDefinition;
// PropertyLiteral propertyLiteral = (PropertyLiteral) property;
// if (!propertyLiteral.getLiteralType().equals(
// propertyLiteralDefinition.getLiteralType())) {
// logger.fine(MessageFormat.format(
// "Property type {0} does not equal property definition type {1}",
// propertyLiteral.getLiteralType(),
// propertyLiteralDefinition.getLiteralType()));
// return false;
// }
// LinkedHashSet<String> options = propertyLiteralDefinition.getOptions();
// if (options != null && options.size() > 0) {
// if (!options.contains(propertyLiteral.getLiteralValue())) {
// logger.fine(MessageFormat.format("Property value {0} is not permitted",
// propertyLiteral.getLiteralValue()));
// return false;
// }
// }
// } else {
// logger.fine(MessageFormat.format("Expected a PropertyLiteral but got a {0}",
// property.getClass().getSimpleName()));
// return false;
// }
// } else if (propertyDefinition instanceof PropertyReferenceDefinition) {
// if (property instanceof PropertyReference) {
// PropertyReferenceDefinition propertyReferenceDefinition = (PropertyReferenceDefinition) propertyDefinition;
// PropertyReference propertyReference = (PropertyReference) property;
// LinkedHashSet<URI> options = propertyReferenceDefinition.getOptions();
// if (options != null && options.size() > 0) {
// if (!options.contains(propertyReference.getResourceURI())) {
// logger.fine(MessageFormat.format("Property value {0} is not permitted",
// propertyReference.getResourceURI()));
// return false;
// }
// }
// } else {
// logger.fine(MessageFormat.format("Expected a PropertyReference but got a {0}",
// property.getClass().getSimpleName()));
// return false;
// }
// } else if (propertyDefinition instanceof PropertyResourceDefinition) {
// if (property instanceof PropertyResource) {
// PropertyResourceDefinition propertyResourceDefinition = (PropertyResourceDefinition) propertyDefinition;
// PropertyResource propertyResource = (PropertyResource) property;
// return isValidPropertyResource(configuration, propertyResourceDefinition,
// propertyResource);
// } else if (property instanceof PropertyReference) {
// // special cases where a PropertyResource is actually a reference to a WorkflowBundle component
// PropertyReference propertyReference = (PropertyReference) property;
// WorkflowBundle workflowBundle = scufl2Tools.findParent(WorkflowBundle.class,
// configuration);
// URI configUri = uriTools.uriForBean(configuration);
// URI referenceUri = configUri.resolve(propertyReference.getResourceURI());
// if (workflowBundle != null) {
// URI predicate = propertyDefinition.getPredicate();
// WorkflowBean workflowBean = uriTools.resolveUri(referenceUri, workflowBundle);
// if (workflowBean == null) {
// logger.fine(MessageFormat.format(
// "Cannot resolve {0} in WorkflowBundle {1}",
// propertyReference.getResourceURI(), workflowBundle.getName()));
// }
// if (predicate.equals(SCUFL2.resolve("#definesInputPort"))) {
// if (workflowBean == null) {
// return false;
// }
// if (!(workflowBean instanceof InputActivityPort)) {
// logger.fine(MessageFormat.format(
// "{0} resolved to a {1}, expected a InputActivityPort",
// propertyReference.getResourceURI(), workflowBean.getClass()
// .getSimpleName()));
// return false;
// }
// } else if (predicate.equals(SCUFL2.resolve("#definesOutputPort"))) {
// if (workflowBean == null) {
// return false;
// }
// if (!(workflowBean instanceof OutputActivityPort)) {
// logger.fine(MessageFormat.format(
// "{0} resolved to a {1}, expected a OutputActivityPort",
// propertyReference.getResourceURI(), workflowBean.getClass()
// .getSimpleName()));
// return false;
// }
// } else {
// logger.fine(MessageFormat.format("Unexpected reference to {0}", predicate));
// }
// } else {
// logger.fine(MessageFormat
// .format("Cannot resolve reference to {0} because Configuration {1} not contained within a WorkflowBundle",
// referenceUri, configuration.getName()));
// }
// } else {
// logger.fine(MessageFormat.format("Expected a PropertyResource or PropertyReference but got a {0}",
// property.getClass().getSimpleName()));
// return false;
// }
// } else {
// logger.fine(MessageFormat.format("Unknown propery definition class {0}",
// propertyDefinition.getClass().getSimpleName()));
// return false;
// }
// return true;
// }
}