001/* 002 * Copyright (c) 2017 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2017-08-24 12:45:52 -0700 (Thu, 24 Aug 2017) $' 007 * '$Revision: 1388 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029package org.kepler.webview.server.handler; 030 031import java.util.HashMap; 032import java.util.Map; 033import java.util.Set; 034 035import org.kepler.util.WorkflowRun; 036import org.kepler.webview.server.WebViewServer; 037 038import io.vertx.core.MultiMap; 039import io.vertx.core.json.JsonArray; 040import io.vertx.core.json.JsonObject; 041import io.vertx.ext.web.RoutingContext; 042import ptolemy.data.BooleanToken; 043import ptolemy.data.DoubleToken; 044import ptolemy.data.StringToken; 045import ptolemy.data.Token; 046import ptolemy.data.expr.ASTPtRootNode; 047import ptolemy.data.expr.ParseTreeEvaluator; 048import ptolemy.data.expr.ParserScope; 049import ptolemy.data.expr.PtParser; 050import ptolemy.data.expr.UndefinedConstantOrIdentifierException; 051import ptolemy.data.type.Type; 052import ptolemy.graph.InequalityTerm; 053import ptolemy.kernel.util.IllegalActionException; 054 055/** Handler to get information about workflow runs. 056 * 057 * @author Daniel Crawl 058 * @version $Id: RunsHandler.java 1388 2017-08-24 19:45:52Z crawl $ 059 * 060 */ 061public class RunsHandler extends ProvenanceHandler { 062 063 public RunsHandler(WebViewServer server) { 064 super(server); 065 } 066 067 @Override 068 public void handle(RoutingContext context) { 069 070 /* 071 System.out.println("in runs handler"); 072 for(Entry<String, String> e : context.request().params()) { 073 System.out.println(e.getKey() + " -> " + e.getValue()); 074 } 075 */ 076 077 _server.getVertx().<JsonObject>executeBlocking(future -> { 078 try { 079 JsonArray jsonArray = new JsonArray(); 080 081 MultiMap params = context.request().params(); 082 083 String name = params.get("name"); 084 String parameters = params.get("parameters"); 085 086 PtParser parser; 087 ASTPtRootNode parseTree = null; 088 ParseTreeEvaluator parseTreeEvaluator = null; 089 ParametersScope scope = null; 090 091 // if evaluating parameters expression, create parser objects 092 if(parameters != null) { 093 parser = new PtParser(); 094 parseTree = parser.generateParseTree(parameters); 095 parseTreeEvaluator = new ParseTreeEvaluator(); 096 scope = new ParametersScope(); 097 } 098 099 for(WorkflowRun run : _queryable.getWorkflowRunsForUser(context.user().principal().getString("username"))) { 100 101 // if search for name, check if run name matches 102 // TODO perform this in queryable 103 if(name != null && !name.equals(run.getWorkflowName())) { 104 continue; 105 } 106 107 if(parameters != null) { 108 109 // add the run's parameter names and values to the parser's scope 110 Map<String,String> map = _queryable.getParameterNameValuesOfSpecificTypeForExecution(run.getExecId()); 111 scope.setParametersValues(map); 112 113 // attempt to evaluate the expression. 114 Token result = null; 115 try { 116 result = parseTreeEvaluator.evaluateParseTree(parseTree, scope); 117 } catch(UndefinedConstantOrIdentifierException e) { 118 // ignore undefined identifiers since the workflow may not 119 // have a parameter with that name. 120 continue; 121 } 122 123 // make sure result is a boolean 124 if(!(result instanceof BooleanToken)) { 125 throw new Exception("Parameter search expression must evaluate to true or false."); 126 } 127 128 // if expression evaluates to false, do not add this run to the results. 129 if(!((BooleanToken)result).booleanValue()) { 130 continue; 131 } 132 } 133 134 jsonArray.add(new JsonObject().put("id", run.getExecLSID().toString()) 135 .put("start", run.getStartTimeISO8601()) 136 .put("status", run.getType()) 137 .put("workflowName", run.getWorkflowName())); 138 } 139 future.complete(new JsonObject().put("runs", jsonArray)); 140 141 } catch(Exception e) { 142 future.fail(e); 143 } 144 }, false, result -> { 145 if(result.succeeded()) { 146 _sendResponseWithSuccessJson(context.request(), result.result()); 147 } else { 148 _sendResponseWithError(context.request(), "Could not get runs: " + result.cause().getMessage()); 149 } 150 }); 151 } 152 153 /** A scope for expressions that references parameters from a workflow run. */ 154 private static class ParametersScope implements ParserScope { 155 156 /** Get the value from an identifier in the expression. */ 157 @Override 158 public Token get(String name) throws IllegalActionException { 159 160 // see if the identifier was a parameter in the workflow run 161 String value = _map.get(name); 162 if(value != null) { 163 //System.out.println("found " + name + " = " + value); 164 // first try casting value as a double 165 try { 166 return new DoubleToken(value); 167 } catch(Throwable t) { 168 // default to a string 169 return new StringToken(value); 170 } 171 } 172 173 return null; 174 } 175 176 /** Set the parameters from the workflow run. */ 177 public void setParametersValues(Map<String, String> map) { 178 _map.clear(); 179 for(Map.Entry<String, String> entry : map.entrySet()) { 180 // add the parameter name and value. 181 // NOTE: remove the first character of the name since it begins with "." 182 _map.put(entry.getKey().substring(1), entry.getValue()); 183 } 184 } 185 186 @Override 187 public Type getType(String name) throws IllegalActionException { 188 // TODO Auto-generated method stub 189 return null; 190 } 191 192 @Override 193 public InequalityTerm getTypeTerm(String name) throws IllegalActionException { 194 // TODO Auto-generated method stub 195 return null; 196 } 197 198 @Override 199 public Set<?> identifierSet() throws IllegalActionException { 200 // TODO Auto-generated method stub 201 return null; 202 } 203 204 private Map<String, String> _map = new HashMap<>(); 205 } 206 207}