Package eu.planets_project.tb.impl.system

Source Code of eu.planets_project.tb.impl.system.ServiceExecutionHandlerImpl

/*******************************************************************************
* Copyright (c) 2007, 2010 The Planets Project Partners.
*
* All rights reserved. This program and the accompanying
* materials are made available under the terms of the
* Apache License, Version 2.0 which accompanies
* this distribution, and is available at
* http://www.apache.org/licenses/LICENSE-2.0
*
*******************************************************************************/
/**
*
*/
package eu.planets_project.tb.impl.system;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eu.planets_project.tb.api.data.util.DataHandler;
import eu.planets_project.tb.api.model.Experiment;
import eu.planets_project.tb.api.model.ExperimentExecutable;
import eu.planets_project.tb.api.model.benchmark.BenchmarkGoal;
import eu.planets_project.tb.api.services.TestbedServiceTemplate;
import eu.planets_project.tb.api.services.TestbedServiceTemplate.ServiceOperation;
import eu.planets_project.tb.api.services.mockups.workflow.Workflow;
import eu.planets_project.tb.api.system.ServiceExecutionHandler;
import eu.planets_project.tb.api.system.batch.BatchProcessor;
import eu.planets_project.tb.gui.backing.admin.wsclient.faces.WSClientBean;
import eu.planets_project.tb.impl.data.util.DataHandlerImpl;
import eu.planets_project.tb.impl.exceptions.ServiceInvocationException;
import eu.planets_project.tb.impl.services.mockups.workflow.ExperimentWorkflow;
import eu.planets_project.tb.impl.services.mockups.workflow.WorkflowDroidXCDLExtractorComparator;
import eu.planets_project.tb.impl.system.batch.TestbedBatchProcessorManager;

/**
* @author Andrew Lindley, ARC
* This class is responsible for taking the experiment's executable part, building the request,
* invoking the actual service, extracting the results from the responds and wrting
* information back to the experiment's executable
*
*/
public class ServiceExecutionHandlerImpl implements ServiceExecutionHandler{

  //A Log for this - transient: it's not persisted with this entity
    private Log log = LogFactory.getLog(ServiceExecutionHandlerImpl.class);
    private String sOutputDir = "";
    //this will only be modified once, so therefore the relative position of its elements will not change
    //which is important for mapping them to their output files.
    Map<String,String> hmInputFiles = new HashMap<String,String>();
    //A DataHandler util class for decoding base64 or similar value (and not ref) results
    DataHandler dh = new DataHandlerImpl();
   
    public ServiceExecutionHandlerImpl(){
    }
 
  /* (non-Javadoc)
   * @see eu.planets_project.tb.api.system.ExperimentInvoker#executeExperiment(eu.planets_project.tb.api.model.Experiment)
   */
  public void executeExperiment(Experiment exp){
     
     //1) Get the required data and build the request
      //ExperimentExecutable already contains the input data
      ExperimentExecutable executable = exp.getExperimentExecutable();
      if( executable == null ) {
          log.error("executeExperiment: executable is null!");
          return;
      }
     
      //DECIDE UPON WHICH BATCH_QUEUE WAS CHOSEN WHAT PROCESSOR TO CALL
      // Look for the batch system...
      TestbedBatchProcessorManager tbBatchManager = TestbedBatchProcessorManager.getInstance();
      BatchProcessor bp;
     
      //a) TB-experiment types before version1.0 - these use the ExperimentWorkflow
      if(executable.getBatchSystemIdentifier().equals(BatchProcessor.BATCH_IDENTIFIER_TESTBED_LOCAL)){
        //get the specific batchProcessor implementation
        bp = tbBatchManager.getBatchProcessor(BatchProcessor.BATCH_IDENTIFIER_TESTBED_LOCAL);
        // Invoke, depending on the experiment type:
        ExperimentWorkflow ewf = executable.getWorkflow();
        log.info("Submitting workflow: "+ewf+" to batch processor: "+BatchProcessor.BATCH_IDENTIFIER_TESTBED_LOCAL);
        log.info("Got inputs #"+executable.getInputData().size());
        String queue_key = bp.submitBatch( exp.getEntityID(), ewf , executable.getInputData());
        //already set: executable.setBatchQueueIdentifier(BatchProcessor.BATCH_QUEUE_TESTBED_LOCAL);
        executable.setBatchExecutionIdentifier(queue_key);
              executable.setExecutableInvoked(true);
              executable.setExecutionCompleted(false);
              log.info("Got key: "+queue_key);
      }
     
      //b) TB-experiment types using the wee batch processor
      if(executable.getBatchSystemIdentifier().equals(BatchProcessor.BATCH_QUEUE_TESTBED_WEE_LOCAL)){
        //get the specific batchProcessor implementation
        bp = tbBatchManager.getBatchProcessor(BatchProcessor.BATCH_QUEUE_TESTBED_WEE_LOCAL);
        log.info("Submitting workflow to batch processor: "+BatchProcessor.BATCH_QUEUE_TESTBED_WEE_LOCAL);
        log.info("Got inputs #"+executable.getInputData().size());
        //DataHandler dh = new DataHandlerImpl();
        //NOTE: previously submitting digital objects...
        //List<DigitalObject> digos = dh.convertFileRefsToURLAccessibleDigos(executable.getInputData());
        //submit the batch process to the WEE
        //String queue_key = bp.sumitBatch(exp.getEntityID(), digos, executable.getWEEWorkflowConfig());
       
        //NOTE: changed to submitting by data registry references..
        //submit the batch process to the WEE passing objects by reference (shared data registry pointers)
        List<URI> digoRefs = new ArrayList<URI>();
        for(String inputDataRef : executable.getInputData()){
          try{
            digoRefs.add(new URI(inputDataRef));
          }catch(URISyntaxException err){
            log.debug("this shouldn't happen - conversion String -> URI failed for "+inputDataRef);
          }
        }
        String queue_key = bp.sumitBatchByReference(exp.getEntityID(), digoRefs, executable.getWEEWorkflowConfig());
       
        if((queue_key!=null)&&(!queue_key.equals(""))){
          executable.setBatchExecutionIdentifier(queue_key);
          //executable.setExecutableInvoked(true);
                executable.setExecutionCompleted(false);
                log.info("Got key: "+queue_key);
        }else{
          //something on the batch processor went wrong....
          //FIXME: This is not really sufficient... inform notify_failed?
          executable.setExecutionCompleted(true);
          executable.setExecutionSuccess(false);
        }
             
      }
  }
 

 

    /**
   * Takes the added data and builds up a map structure with the position number
   * as key and the fileRef as value - this is required to create an input - output mapping
   * Map<String position+"", String localInputFileRef>
   * @param inputData
   */
  @SuppressWarnings("unused")
  private void createInputDataMap(Collection<String> inputData) {
    if(inputData!=null){
      Iterator<String> fileRefs = inputData.iterator();
      int count=0;
      while(fileRefs.hasNext()){
        this.hmInputFiles.put(count+"", fileRefs.next());
        count++;
      }
    }
   
  }
 
  /**
   * Takes the information provided within the TestbedServiceTEmplate to build
   * the web service client.
   * @return
   */
  @SuppressWarnings("unused")
  private WSClientBean createWSClient(TestbedServiceTemplate serviceTemplate, ServiceOperation selOperation) throws ServiceInvocationException{
    WSClientBean wsclient = initWSClient();
    wsclient.setWsdlURI(serviceTemplate.getEndpoint());
    String message = wsclient.analyzeWsdl();
   
    if(!message.equals("success-analyze")){
      log.error("creating WSClientbean error-analzye");
      throw new ServiceInvocationException("error-analyze");
    }
   
    wsclient.setServiceSelectItemValue(serviceTemplate.getName());
    wsclient.setOperationSelectItemValue(selOperation.getName());
   
    return wsclient;
  }
 
  /**
   * Creates a new WSClientBean ant sets its  working dir
   */
  private WSClientBean initWSClient(){

    //load properties from BackendResources.properties file
    Properties properties = new Properties();
    try {
      java.io.InputStream ResourceFile = getClass().getClassLoader().getResourceAsStream("eu/planets_project/tb/impl/BackendResources.properties");
      properties.load(ResourceFile);

        //Note: sFileDirBase = ifr_server/bin/../server/default/deploy/jbossweb-tomcat55.sar/ROOT.war
        String sFileDirBase = BackendProperties.getTBFileDir();
        ResourceFile.close();

        //create a new client bean
        WSClientBean wcb = new WSClientBean();
        wcb.setWorkDir(sFileDirBase+"/planets/wsexecution");
       
        return wcb;
       
     } catch (IOException e) {
        log.error("read JBoss.FiledirBase from BackendResources.properties failed!"+e.toString());
     }
     return null;
  }
 
  /**
   * Take the migrated file output (produced by the ServiceRespondsBuilder) and copy the
   *  service's migration output to the Testbed's experiment/output direcotry.
   * 
   * If the migration output does not correspond to a local file but rather to a URI the content is downloaded
   * and copied into the Testbed's experiment/output direcotry.
   * 
   *  This methods also calls renameOutput which produces an outpuf file with the same name as it's input file.
   * @return updated migrationResult with file refs to the Testbed's output dir.
   */
  @SuppressWarnings("unused")
  private Map<String,String> copyFileOutputToOutputDir(Map<String,String> migrationResults) throws IOException{
    Map<String,String> ret = new HashMap<String,String>();
    if(migrationResults!=null){
      Iterator<String> itKeys = migrationResults.keySet().iterator();
      while(itKeys.hasNext()){
        String key = itKeys.next();
        try {
          //1)get the File ref, rename it to it's corresponding input file name and
          //move it within the testbed's output dir
          String fileRef = migrationResults.get(key);
          File fMigrationOutput = new File(fileRef);
          //VM needs to be able to access this ref as file
          if(!fMigrationOutput.canRead()){
            //this item did not produce a valid migration output
            throw new IOException("Error reading migration output file from file ref for key: "+key);
          }
          //now copy its binary data
          String ref  = dh.storeFile(fMigrationOutput).toString();
         
          //finally update the returned migration output reference
          ret.put(key, ref);
         
        } catch (IOException e) {
          //2)no valid output FILE for this input file - no problem
          //in this case, test if it's an URI and if this is downloadable
          try{
            String suriRef = migrationResults.get(key);
            URI uriRef = new URI(suriRef);
           
                        //write the file's content as read from the stream
                        String newFileName = dh.storeUriContent(uriRef).toString();
           
            //finally update the returned migration output reference
            ret.put(key, newFileName);
          }
          catch(Exception e2){
            //no problem - we're not able to handle this output
            //not output for this input element
            log.debug(e2.toString());
          }
        }
      }
    }
    return ret;
  }  
 
 
  /**
   * Specifies the directory where to copy the migration output files
   * @throws IOException
   */
  @SuppressWarnings("unused")
  private void setDir() throws IOException{
    Properties properties = new Properties();
      try {
          java.io.InputStream ResourceFile = getClass().getClassLoader().getResourceAsStream("eu/planets_project/tb/impl/BackendResources.properties");
          properties.load(ResourceFile);
         
          //Note: sFileDirBaase = ifr_server/bin/../server/default/deploy/jbossweb-tomcat55.sar/ROOT.war
          String sFileDirBase = BackendProperties.getTBFileDir();
          sOutputDir = sFileDirBase+properties.getProperty("JBoss.FileOutDir");
         
          ResourceFile.close();
         
          //create if it does not already exist
          createOutputDir();
         
      } catch (IOException e) {
        log.error("read JBossFileDirs from BackendResources.proerties failed!"+e.toString());
        throw e;
      }
  }
 
    /**
     * Checks if output dir (as defined in the properties file)
     * e.g. C:\DATA\Implementation\ifr_server\server\default\deploy\jbossweb-tomcat55.sar\ROOT.war\planets-testbed\outputdata
     * exists and otherwise creates it.
     */
    private void createOutputDir(){
      File dir = new File(sOutputDir);
      if(!dir.exists()){
        log.info("Dir does not exist: mkdirs: "+dir.toString());
        dir.mkdirs();   
      }
    }
   

  /**
   * Takes a given http URI and tries to download its binary content.
   * @param uri
   * @return
   * @throws FileNotFoundException
   * @throws IOException
   */
  @SuppressWarnings("unused")
  private byte[] downloadBinaryFromURI(URI uri)throws FileNotFoundException, IOException{
   
    InputStream in = null;
    try{
      if(!uri.getScheme().equals("http")){
        throw new FileNotFoundException("URI schema "+uri.getScheme()+" not supported");
      }

      URLConnection c = uri.toURL().openConnection();
      in = c.getInputStream();
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      byte[] buf = new byte[1024];
      int len;
      while ((len = in.read(buf)) > 0) {
        bos.write(buf, 0, len);
      }
      byte[] data = bos.toByteArray();
     
      return data;
    }
    finally{
      in.close();
    }
  }
 
 
  /**
   * In the case of a value calls (e.g. as base64 data transmission) this method
   * extracts and decodes the data to a local file and provides a file reference
   * An output file type (e.g. doc) can be specified, which will be used as the result's file type
   * @return
   */
  @SuppressWarnings("unused")
  private Map<String,String> createFilesFromBase64Result(Map<String,String> migrationResults, String outputFileType){
    Map<String,String> ret = new HashMap<String,String>();
    if((migrationResults==null)||(migrationResults.size()<=0))
      return ret;
   
    Iterator<String> itKeys = migrationResults.keySet().iterator();
    while(itKeys.hasNext()){
      String key = itKeys.next();
      String sBase64value = migrationResults.get(key);
       
      //decode the base64 String
      byte[] b = DataHandlerImpl.decodeToByteArray(sBase64value);
      try {
        //get the file's new name (same as it's input file) - input and output should have the same key
        String sInputFileName = new File(this.hmInputFiles.get(key)).getName();
        String sOutputFileName ="";
        char delimP = '.';
        int p = sInputFileName.lastIndexOf(delimP);
        String origInputFileMathNr = sInputFileName.substring(0, p);
        sOutputFileName = origInputFileMathNr+"."+outputFileType;
       
        //now copy the byteArray into the file-location
        String ref = dh.storeBytearray(b, sOutputFileName).toString();
       
        //finally update the returned migration output reference
        ret.put(key, ref);
       
      } catch (FileNotFoundException e) {
        System.out.println(e.toString());
      } catch (IOException e) {
        System.out.println(e.toString());
      }
    }
   
    return ret;
  }

  /* (non-Javadoc)
   * @see eu.planets_project.tb.api.system.ServiceExecutionHandler#executeAutoEvalServices(eu.planets_project.tb.api.model.Experiment)
   * Executable only if the current experiment phase = evaluation
   */
  public void executeAutoEvalServices(Experiment exp) { 
    log.info("Attempting to execute the Auto Eval services.");
    //a Planets IF Java Workflow instance (mockup)
    WorkflowDroidXCDLExtractorComparator evalWorkflow = new WorkflowDroidXCDLExtractorComparator();
   
    //Get the experiment's data we want to add autoEval FileBMGoals for
    Collection<Entry<String,String>> data = exp.getExperimentExecutable().getMigrationDataEntries();

    //iterate over all experiemnt data entries
    for(Entry<String,String> dataEntry : data){
      DataHandler dh = new DataHandlerImpl();
      try {
        URI inputFileURI = dh.get(dataEntry.getKey()).getDownloadUri();
        //URI outputFileURI = dh.getHttpFileRef(new File(dataEntry.getValue()), false);
        File fInputFile = new File(dataEntry.getKey());
        File fOutputFile = new File(dataEntry.getValue());
       
        //the fileBMGoals for the file to evaluate
        Collection<BenchmarkGoal> fileBMGoals = exp.getExperimentEvaluation().getEvaluatedFileBenchmarkGoals(inputFileURI);
       
        //call the workflow and extract the data from the workflow's result for every fileBMGoal
        for(BenchmarkGoal fileBMGoal : fileBMGoals){
          //executes the workflow, extracts the data, writes results into the objects
          this.executeWorkflowAndExtractResults(fileBMGoal, fInputFile, fOutputFile, evalWorkflow);
        }
      } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
      }     
    }
  }
 

  /**
   * This method executes a fully functional mockup of the following workflow:
   * In-->Takes two files as input
   * a) identify using Droid: to analyze a given file and to extract it's pronom Id(s)
   * b) extract using XCDL Extractor: to extract it's XCDL representation (if it is supported)
   * c) compare using XCDL Comparator: compares the two XCDL descriptions.
   * Out<--returns the comparator's responds
   * This responds is then parsed given the XPath queries within AutoEvalServiceConfig and the BenchmarkGoal objects updated
   * TODO: Andrew: substitute with IF workflow
   * @param bmGoal - the BM goal to evaluate
   * @param f1 localFile ref input file
   * @param f2 localFile ref output file
   */
  private void executeWorkflowAndExtractResults(BenchmarkGoal bmGoal, File f1, File f2, Workflow evalWorkflow){
/*    FIXME ANJ Clear this up.
    //execute the Droid->XCDLExtractor->Comparator workflow
    EvaluationExecutable evalExecutable = evalWorkflow.execute(f1, f2);
   
    //persist the workflow's data
    bmGoal.setAutoEvaluationExecutable(evalExecutable);
   
    //in the case the evaluation workflow was successful
    if(evalExecutable.isExecutableInvoked()&&evalExecutable.isExecutionSuccess()){
     
      try {
        AutoEvaluationSettings autoEvalSettings = bmGoal.getAutoEvalSettings();
        EvaluationTestbedServiceTemplateImpl evalService = (EvaluationTestbedServiceTemplateImpl)autoEvalSettings.getEvaluationService();
 
        //fetch the XCDL comparison result
        String wfResult = evalExecutable.getXCDLsComparisonResult();
       
        //try to build a w3c Document structure
        Document document = this.buildDOM(wfResult);

      //AUSLAGERN IN EIGENE METHODE
        //Iterate over the results and extract metric and evaluation information according to the given XPath definitions
        NodeList nodes = evalService.getAllEvalResultsRootNodes(document);
        if((nodes!=null)&&(nodes.getLength()>0)){
          for(int i=0;i<nodes.getLength();i++){
            Node node = nodes.item(i);
           
            //e.g. imageHeight
            String sPropertyName = evalService.getEvalResultName(node);
           
            //mapping of TB BMGoalID to mappedPropertyName
            String mappedPropName = evalService.getMappedPropertyName(bmGoal.getID());
           
            //check if the values belong to this BMGoal
            if(sPropertyName.equals(mappedPropName)){
              //e.g. complete
              String sStatus = evalService.getEvalResultCompStatus(node);
              //check if the metric was evaluated properly
              if(sStatus.equals(evalService.getStringForCompStatusSuccess())){
                //e.g. 32
                String sSrcVal = evalService.getEvalResultSrcValue(node);
                //e.g. 32
                String sTarVal = evalService.getEvalResultTarValue(node);
                //e.g. <hammingDistance,0.000000>
                Map<String,String> metric = evalService.getEvalResultMetricNamesAndValues(node);
               
                TBEvaluationTypes type = autoEvalSettings.autoValidate(metric);
                if(type!=null){
                 
                  //now write the extracted auto Eval information back to the BMGoal
                  bmGoal.setSourceValue(sSrcVal);
                  bmGoal.setTargetValue(sTarVal);
                  bmGoal.setEvaluationValue(type.screenName());
                  bmGoal.setWasAutomaticallyEvaluated(true);
                }
              }
            }
          }
        }
        else{
          return;
        }
    //END AUSLAGERN IN EIGENE METHODE
      } catch (Exception e) {
        return;
      }
    }
    else{
      //in this case autoEval workflow failed (e.g. due to non supported file type) - the user must evaluate by hand
    }
    */
  }
 

   
 
  /* (non-Javadoc)
   * @see eu.planets_project.tb.api.system.ServiceExecutionHandler#executeExperimentAndAutoEvalServices(eu.planets_project.tb.api.model.Experiment)
   */
  public void executeExperimentAndAutoEvalServices(Experiment exp) {
    //execute the migration/characterisation service
    this.executeExperiment(exp);
    //execute the evaluation services
    this.executeAutoEvalServices(exp);
   
  }
 

}
TOP

Related Classes of eu.planets_project.tb.impl.system.ServiceExecutionHandlerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.