View Javadoc

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 }