1 /*
2 * Copyright 2010 Fraunhofer Gesellschaft, Munich, Germany,
3 * for its Fraunhofer Institute for Computer Architecture and Software
4 * Technology (FIRST), Berlin, Germany. All rights reserved.
5 * http://www.first.fraunhofer.de/
6 */
7 package net.kwfgrid.gwes.prorater;
8
9 import net.kwfgrid.gworkflowdl.structure.*;
10 import net.kwfgrid.gwes.*;
11 import org.apache.log4j.Logger;
12
13 /**
14 * This class implements the methods for spatial co-allocation, i.e., two or more subsequent workflow activities are
15 * supposed to be invoked on the same resource.
16 * @author Andreas Hoheisel
17 * (<a href="http://www.andreas-hoheisel.de">www.andreas-hoheisel.de</a>)
18 * @version $Id: ResourceCoAllocator.java 1419 2010-11-01 14:12:17Z hoheisel $
19 */
20 public class ResourceCoAllocator {
21
22 private final static Logger logger = Logger.getLogger(ResourceCoAllocator.class);
23
24 /**
25 * Co-Allocation based on resource allocation information stored in token properties.
26 * If the transition contains a resource.allocation.group property then this method checks if there are input
27 * or read tokens that contain a corresponding resource allocation for this group. Then the corresponding
28 * operation candidate is selected.
29 * @param to The transition occurrence.
30 * @param handler The parent workflow handler.
31 * @return The resource name to be used by the next operation of this transition or <code>null</code> if there
32 * is no resource name specified in one of the input tokens.
33 */
34 public static String blue2greenCoAllocationFromToken(TransitionOccurrence to, GWorkflowDLHandler handler) {
35 // get group ID from transition property
36 String groupID = to.transition.getProperties().get(Constants.PROP_TRANSITION_RESOURCE_ALLOCATION_GROUP);
37 if (groupID == null || groupID.length() < 1) return null;
38
39 if (logger.isDebugEnabled()) {
40 logger.debug("Resource co-allocation: transition \""+ to.transition.getID() + "\" belongs to allocation group \""+groupID+"\"");
41 }
42
43 // loop read/input/write edges and check for tokens with same resource.allocation.group
44 String allocateResource = null;
45 loop: for (TokenParameter tp : to.tokens) {
46 switch (tp.scope) {
47 case READ:
48 case INPUT:
49 case WRITE:
50 String resourceName = tp.token.getProperties().get(Constants.PROP_TOKEN_RESOURCE_ALLOCATION_GROUP_ + groupID);
51 if (resourceName != null && resourceName.length() > 0) {
52 if (logger.isDebugEnabled()) {
53 logger.debug("Resource co-allocation: token requires resource name \"" + resourceName + "\" for allocation group \"" + groupID + "\"");
54 }
55 // check conflicts between various tokens with different resource.allocation.group properties
56 if (allocateResource != null) {
57 if (resourceName.equals(allocateResource)) {
58 //everything is OK; proceed with next edge
59 continue loop;
60 } else {
61 handler.workflowWarnAndSuspend("Resource co-allocation warning: There are two or more resources requested for the resource allocation group \"" + groupID + "\" at transition \"" + to.transition.getID() + "\" but there can be only one.");
62 break loop;
63 }
64 }
65 // select the first operation candidate with corresponding resource name
66 synchronized (to.transition.getOperation()) {
67 OperationCandidate[] cands = ((OperationClass) to.transition.getOperation().get()).getOperationCandidates();
68 for (OperationCandidate cand : cands) {
69 // only the part after "@" is evaluated if available!
70 if (getUri(cand.getResourceName()).equals(getUri(resourceName))) {
71 if (logger.isDebugEnabled()) {
72 logger.debug("Resource co-allocation: The resource \"" + resourceName + "\" is requested for the resource allocation group \"" + groupID + "\" at transition \"" + to.transition.getID() + "\".");
73 }
74 cand.setSelected();
75 allocateResource = resourceName;
76 break;
77 }
78 }
79 if (allocateResource == null)
80 handler.workflowWarnAndSuspend("Resource co-allocation warning: The resource \"" + resourceName + "\" is requested for the resource allocation group \"" + groupID + "\" but is not available as operation candidate for transition \"" + to.transition.getID() + "\".");
81 }
82 }
83 break;
84 }
85 }
86
87 return allocateResource;
88 }
89
90 /**
91 * Returns the part after "@".
92 * Example inputs:
93 * <pre>
94 * resourceUri="hardware:clown.first.fraunhofer.de"
95 * resourceUri="http://fhrg.first.fraunhofer.de:8080/linuxtoolbox/services/Sort?wsdl"
96 * resourceUri="http://fhrg.first.fraunhofer.de:8080/linuxtoolbox/services/Sort?wsdl@hardware:clown.first.fraunhofer.de"
97 * </pre>
98 * @param resourceUri
99 * @return
100 */
101 private static String getUri(String resourceUri) {
102 if (resourceUri == null) return null;
103 int edIndex = resourceUri.indexOf("@");
104 return (edIndex >= 0 ? resourceUri.substring(edIndex) : resourceUri) ;
105 }
106
107 }