/*
   * (non-Javadoc)
   *
   * @see org.apache.oodt.cas.workflow.engine.WorkflowEngine#getWorkflowInstanceMetadata(java.lang.String)
   */
  public Metadata getWorkflowInstanceMetadata(String workflowInstId) {
    // okay, try and look up that worker thread in our hash map
    IterativeWorkflowProcessorThread worker =
        (IterativeWorkflowProcessorThread) workerMap.get(workflowInstId);
    if (worker == null) {
      // try and get the metadata
      // from the workflow instance repository (as it was persisted)
      try {
        WorkflowInstance inst = instRep.getWorkflowInstanceById(workflowInstId);
        return inst.getSharedContext();
      } catch (InstanceRepositoryException e) {
        LOG.log(
            Level.FINEST,
            "WorkflowEngine: Attempt to get metadata "
                + "for workflow instance id: "
                + workflowInstId
                + ", however, this engine is "
                + "not tracking its execution and the id: ["
                + workflowInstId
                + "] "
                + "was never persisted to "
                + "the instance repository");
        e.printStackTrace();
        return new Metadata();
      }
    }

    return worker.getWorkflowInstance().getSharedContext();
  }
  @Test
  public void testGetWorkflowInstanceMetadata2() throws Exception {
    WorkflowInstance wf = (WorkflowInstance) fmc.getFirstPage().getPageWorkflows().get(0);

    assertThat(wf, is(not(Matchers.nullValue())));

    Metadata meta = fmc.getWorkflowInstanceMetadata(wf.getId());

    assertNotNull(meta);
  }
 public void testPctCompleteWengineStages() {
   ParentChildWorkflow workflow = new ParentChildWorkflow(new Graph());
   WorkflowState successState =
       lifecycle.getDefaultLifecycle().createState("Success", "done", "All done.");
   WorkflowInstance instance = new WorkflowInstance();
   instance.setState(successState);
   instance.setParentChildWorkflow(workflow);
   double pct = lifecycle.getPercentageComplete(instance);
   assertNotNull(pct);
   assertEquals(1.0, pct);
 }
  @BeforeClass
  public static void setup() throws MalformedURLException {

    testWrkInst = new WorkflowInstance();
    testWrkFlw = new Workflow();
    testTask = new WorkflowTask();
    testCond = new WorkflowCondition();
    Metadata sharedContext = new Metadata();

    // to check if the path already exists and to delete if it does exist
    if (new File(catalogPath).exists()) {
      try {
        FileUtils.deleteDirectory(new File(catalogPath));
      } catch (IOException e) {
        fail(e.getMessage());
      }
    }
    repo = new LuceneWorkflowInstanceRepository(catalogPath, stdPgSz);

    testWrkFlw.setName("test.getMetadataWorkflow");
    testWrkFlw.setId("test.id");
    List tasks = new Vector();
    List conds = new Vector();

    testCond.setConditionId("test.cond.id");
    testCond.setConditionInstanceClassName("test.class");
    testCond.setConditionName("test.cond.name");
    testCond.setOrder(1);
    conds.add(testCond);

    testTask.setTaskConfig(new WorkflowTaskConfiguration());
    testTask.setTaskId("test.task.id");
    testTask.setConditions(conds);
    testTask.setOrder(1);
    testTask.setTaskInstanceClassName("test.class");
    testTask.setTaskName("test.task.name");
    tasks.add(testTask);
    testWrkFlw.setTasks(tasks);

    testWrkInst.setCurrentTaskId("test.task");
    testWrkInst.setStatus("STARTED");
    testWrkInst.setWorkflow(testWrkFlw);

    sharedContext.addMetadata("key1", "val1");
    sharedContext.addMetadata("key1", "val2");
    sharedContext.addMetadata("key1", "val3");
    sharedContext.addMetadata("key2", "val4");
    sharedContext.addMetadata("key2", "val5");
    testWrkInst.setSharedContext(sharedContext);
    startXmlRpcWorkflowManager();
    startWorkflow();
    fmc = new XmlRpcWorkflowManagerClient(new URL("http://localhost:" + WM_PORT));
  }
  protected static double getWallClockMinutes(WorkflowInstance inst) {
    if (inst == null) {
      return 0.0;
    }

    Date currentDateOrStopTime =
        (inst.getEndDateTimeIsoStr() != null
                && !inst.getEndDateTimeIsoStr().equals("")
                && !inst.getEndDateTimeIsoStr().equals("null"))
            ? safeDateConvert(inst.getEndDateTimeIsoStr())
            : new Date();

    Date workflowStartDateTime = null;

    if (inst.getStartDateTimeIsoStr() == null
        || (inst.getStartDateTimeIsoStr() != null
            && (inst.getStartDateTimeIsoStr().equals("")
                || inst.getStartDateTimeIsoStr().equals("null")))) {
      return 0.0;
    }

    try {
      workflowStartDateTime = DateConvert.isoParse(inst.getStartDateTimeIsoStr());
    } catch (ParseException e) {
      return 0.0;
    }

    long diffMs = currentDateOrStopTime.getTime() - workflowStartDateTime.getTime();
    double diffSecs = (diffMs * 1.0 / 1000.0);
    double diffMins = diffSecs / 60.0;
    return diffMins;
  }
 public void testPctCompleteWorkflow1Stages() throws InstantiationException {
   this.lifecycle =
       new WorkflowLifecycleManager("./src/main/resources" + "/examples/workflow-lifecycle.xml");
   assertNotNull(this.lifecycle);
   assertNotNull(this.lifecycle.getDefaultLifecycle());
   assertNotNull(this.lifecycle.getDefaultLifecycle().getStages());
   ParentChildWorkflow workflow = new ParentChildWorkflow(new Graph());
   WorkflowState successState =
       lifecycle.getDefaultLifecycle().createState("FINISHED", "done", "All done.");
   WorkflowInstance instance = new WorkflowInstance();
   instance.setState(successState);
   instance.setParentChildWorkflow(workflow);
   double pct = lifecycle.getPercentageComplete(instance);
   assertNotNull(pct);
   assertEquals(1.0, pct);
 }
  @Test
  public void testGetWorkflowWallClockMinutes()
      throws RepositoryException, XmlRpcException, IOException {
    List<WorkflowInstance> workflowlist = fmc.getWorkflowInstances();

    assertThat(workflowlist, is(not(nullValue())));

    assertThat(workflowlist.size(), is(not(0)));

    WorkflowInstance instance = fmc.getWorkflowInstanceById(workflowlist.get(0).getId());

    assertThat(instance, is(not(nullValue())));

    double clock = fmc.getWorkflowWallClockMinutes(instance.getId());

    assertThat(clock, is(not(nullValue())));
  }
  private synchronized void persistWorkflowInstance(WorkflowInstance wInst) throws EngineException {

    try {
      if (wInst.getId() == null || (wInst.getId() != null && wInst.getId().equals(""))) {
        // we have to persist it by adding it
        // rather than updating it
        instRep.addWorkflowInstance(wInst);

      } else {
        // persist by update
        instRep.updateWorkflowInstance(wInst);
      }
    } catch (InstanceRepositoryException e) {
      e.printStackTrace();
      throw new EngineException(e.getMessage());
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see org.apache.oodt.cas.workflow.engine.WorkflowEngine#startWorkflow(org.apache.oodt.cas.workflow.structs.Workflow,
   *      org.apache.oodt.cas.metadata.Metadata)
   */
  public synchronized WorkflowInstance startWorkflow(Workflow workflow, Metadata metadata)
      throws EngineException {
    // to start the workflow, we create a default workflow instance
    // populate it
    // persist it
    // add it to the worker map
    // start it

    WorkflowInstance wInst = new WorkflowInstance();
    wInst.setWorkflow(workflow);
    wInst.setCurrentTaskId(((WorkflowTask) workflow.getTasks().get(0)).getTaskId());
    wInst.setSharedContext(metadata);
    wInst.setStatus(CREATED);
    persistWorkflowInstance(wInst);

    IterativeWorkflowProcessorThread worker =
        new IterativeWorkflowProcessorThread(wInst, instRep, this.wmgrUrl);
    worker.setRClient(rClient);
    workerMap.put(wInst.getId(), worker);

    wInst.setStatus(QUEUED);
    persistWorkflowInstance(wInst);

    try {
      pool.execute(worker);
    } catch (InterruptedException e) {
      throw new EngineException(e);
    }

    return wInst;
  }
  @Test
  public void testUpdateWorkflowInstanceStatus()
      throws XmlRpcException, IOException, RepositoryException {

    List<WorkflowInstance> workflowlist = fmc.getWorkflowInstances();

    assertThat(workflowlist, is(not(nullValue())));

    assertThat(workflowlist.size(), is(not(0)));

    WorkflowInstance instance = fmc.getWorkflowInstanceById(workflowlist.get(0).getId());

    assertThat(instance, is(not(nullValue())));

    boolean upd = fmc.updateWorkflowInstanceStatus(instance.getId(), "RUNNING");

    assertThat(upd, equalTo(true));
  }
  protected static double getCurrentTaskWallClockMinutes(WorkflowInstance inst) {
    if (inst == null) {
      return 0.0;
    }

    Date currentDateOrStopTime =
        (inst.getCurrentTaskEndDateTimeIsoStr() != null
                && !inst.getCurrentTaskEndDateTimeIsoStr().equals("")
                && !inst.getCurrentTaskEndDateTimeIsoStr().equals("null"))
            ? safeDateConvert(inst.getCurrentTaskEndDateTimeIsoStr())
            : new Date();

    Date workflowTaskStartDateTime = null;

    if (inst.getCurrentTaskStartDateTimeIsoStr() == null
        || (inst.getCurrentTaskStartDateTimeIsoStr() != null
            && (inst.getCurrentTaskStartDateTimeIsoStr().equals("")
                || inst.getCurrentTaskStartDateTimeIsoStr().equals("null")))) {
      return 0.0;
    }

    try {
      workflowTaskStartDateTime = DateConvert.isoParse(inst.getCurrentTaskStartDateTimeIsoStr());
    } catch (ParseException e) {
      return 0.0;
    }

    // should never be in this state, so return 0
    if (workflowTaskStartDateTime.after(currentDateOrStopTime)) {
      LOG.log(
          Level.WARNING,
          "Start date time: ["
              + DateConvert.isoFormat(workflowTaskStartDateTime)
              + " of workflow inst ["
              + inst.getId()
              + "] is AFTER "
              + "End date time: ["
              + DateConvert.isoFormat(currentDateOrStopTime)
              + "] of workflow inst.");
      return 0.0;
    }

    long diffMs = currentDateOrStopTime.getTime() - workflowTaskStartDateTime.getTime();
    double diffSecs = (diffMs * 1.0 / 1000.0);
    double diffMins = diffSecs / 60.0;
    return diffMins;
  }
  @Test
  public void testGetWorkflowInstanceMetadata() {

    try {
      repo.addWorkflowInstance(testWrkInst);
    } catch (InstanceRepositoryException e) {
      fail(e.getMessage());
    }
    String testWrkInstId = testWrkInst.getId();
    assertNotNull(testWrkInstId);

    // get workflow instance from instance id
    WorkflowInstance WInst = null;
    try {
      WInst = repo.getWorkflowInstanceById(testWrkInstId);
    } catch (InstanceRepositoryException e) {
      fail(e.getMessage());
    }

    assertNotNull(WInst);

    // get Metadata for the workflow instance
    Metadata met;
    met = WInst.getSharedContext();
    assertNotNull(met);

    assertNotNull(met.getMap());
    assertEquals(2, met.getMap().keySet().size());
    assertNotNull(met.getAllMetadata("key1"));
    assertEquals(3, met.getAllMetadata("key1").size());
    assertNotNull(met.getAllMetadata("key2"));
    assertEquals(2, met.getAllMetadata("key2").size());

    // check key-values for key1
    boolean checkVal1 = false, checkVal2 = false, checkVal3 = false;

    for (String val : met.getAllMetadata("key1")) {
      if (val.equals("val1")) {
        checkVal1 = true;
      } else if (val.equals("val2")) {
        checkVal2 = true;
      } else if (val.equals("val3")) {
        checkVal3 = true;
      }
    }

    assert (checkVal1 && checkVal2 && checkVal3);

    // check key-values for key2
    boolean checkVal4 = false, checkVal5 = false;

    for (String val : met.getAllMetadata("key2")) {
      if (val.equals("val4")) {
        checkVal4 = true;
      } else if (val.equals("val5")) {
        checkVal5 = true;
      }
    }

    assertTrue(checkVal4 && checkVal5);
  }