001/* A default implementation of Queryable. 002 * 003 * Copyright (c) 2015 The Regents of the University of California. 004 * All rights reserved. 005 * 006 * '$Author: crawl $' 007 * '$Date: 2017-08-23 20:27:50 +0000 (Wed, 23 Aug 2017) $' 008 * '$Revision: 34619 $' 009 * 010 * Permission is hereby granted, without written agreement and without 011 * license or royalty fees, to use, copy, modify, and distribute this 012 * software and its documentation for any purpose, provided that the above 013 * copyright notice and the following two paragraphs appear in all copies 014 * of this software. 015 * 016 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 017 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 018 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 019 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 020 * SUCH DAMAGE. 021 * 022 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 023 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 024 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 025 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 026 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 027 * ENHANCEMENTS, OR MODIFICATIONS. 028 * 029 */ 030package org.kepler.provenance; 031 032import java.io.IOException; 033import java.lang.ref.WeakReference; 034import java.util.Date; 035import java.util.HashMap; 036import java.util.LinkedList; 037import java.util.List; 038import java.util.Map; 039 040import org.kepler.objectmanager.lsid.KeplerLSID; 041import org.kepler.sms.NamedOntClass; 042import org.kepler.util.WorkflowRun; 043import org.kepler.util.WorkflowRun.type; 044 045import ptolemy.data.StringToken; 046import ptolemy.data.Token; 047import ptolemy.data.expr.ASTPtRootNode; 048import ptolemy.data.expr.ParseTreeEvaluator; 049import ptolemy.data.expr.PtParser; 050import ptolemy.kernel.util.NamedObj; 051import ptolemy.moml.MoMLParser; 052 053/** A default implementation of Queryable. Most methods do nothing 054 * and return null. 055 * 056 * @author Daniel Crawl 057 * @version $Id: DefaultQuery.java 34619 2017-08-23 20:27:50Z crawl $ 058 */ 059public abstract class DefaultQuery implements Queryable { 060 061 @Override 062 public void close() throws IOException { 063 try { 064 disconnect(); 065 } catch (QueryException e) { 066 throw new IOException("Error closing query interface.", e); 067 } 068 } 069 070 @Override 071 public void disconnect() throws QueryException { 072 // TODO Auto-generated method stub 073 074 } 075 076 @Override 077 public List<String> getWorkflows() throws QueryException { 078 // TODO Auto-generated method stub 079 return null; 080 } 081 082 @Override 083 public String getWorkflowName(KeplerLSID lsid) throws QueryException { 084 // TODO Auto-generated method stub 085 return null; 086 } 087 088 @Override 089 public String getWorkflowNameForExecution(KeplerLSID lsid) throws QueryException { 090 // TODO 091 return null; 092 } 093 094 @Override 095 public List<Integer> getExecutions() throws QueryException { 096 // TODO Auto-generated method stub 097 return null; 098 } 099 100 @Override 101 public List<KeplerLSID> getExecutionLSIDs() throws QueryException { 102 // TODO Auto-generated method stub 103 return null; 104 } 105 106 @Override 107 public List<Integer> getExecutionsForWorkflow(String workflow) 108 throws QueryException { 109 // TODO Auto-generated method stub 110 return null; 111 } 112 113 @Override 114 public Integer getExecutionForExecutionLSID(KeplerLSID runLSID) 115 throws QueryException { 116 // TODO Auto-generated method stub 117 return null; 118 } 119 120 @Override 121 public KeplerLSID getExecutionLSIDForExecution(Integer execId) 122 throws QueryException { 123 // TODO Auto-generated method stub 124 return null; 125 } 126 127 @Override 128 public List<Integer> getExecutionsForAnnotation(String annotation) 129 throws QueryException { 130 // TODO Auto-generated method stub 131 return null; 132 } 133 134 @Override 135 public Date[] getTimestampsForExecution(int execId) throws QueryException { 136 // TODO Auto-generated method stub 137 return null; 138 } 139 140 @Override 141 public String getMoMLForExecution(int execId) throws QueryException { 142 // TODO Auto-generated method stub 143 return null; 144 } 145 146 @Override 147 public String getMoMLForExecution(KeplerLSID lsid) throws QueryException { 148 // TODO Auto-generated method stub 149 return null; 150 } 151 152 @Override 153 public List<String> getMoMLForExecutionLSIDs(List<KeplerLSID> lsids) 154 throws QueryException { 155 // TODO Auto-generated method stub 156 return null; 157 } 158 159 /** Get the workflow object for a execution id. */ 160 @Override 161 public NamedObj getWorkflowForExecution(Integer execId) 162 throws QueryException { 163 164 // sychronizing on the static _executionToWorkflowMap map prevents 165 // MoMLParsing from being performed concurrently. MoMLParser is not 166 // thread-safe, even using different instances. 167 synchronized(_executionToWorkflowMap) { 168 NamedObj workflow = null; 169 WeakReference<NamedObj> weakWorkflow = _executionToWorkflowMap.get(execId); 170 if(weakWorkflow != null) { 171 workflow = weakWorkflow.get(); 172 } 173 174 if(workflow == null) { 175 //System.out.println("parsing for " + execId); 176 MoMLParser parser = new MoMLParser(); 177 String momlStr = getMoMLForExecution(execId); 178 try { 179 workflow = parser.parse(momlStr); 180 } catch (Exception e) { 181 throw new QueryException("Error parsing workflow MoML.", e); 182 } 183 _executionToWorkflowMap.put(execId, new WeakReference<NamedObj>(workflow)); 184 } 185 186 // return a copy of the workflow since the caller may modify 187 // the workflow. 188 try { 189 return (NamedObj) workflow.clone(); 190 } catch (CloneNotSupportedException e) { 191 throw new QueryException("Error cloning workflow.", e); 192 } 193 } 194 } 195 196 @Override 197 public List<Integer> getExecutionsForTimespan(Date start, Date end) 198 throws QueryException { 199 // TODO Auto-generated method stub 200 return null; 201 } 202 203 @Override 204 public List<Integer> getExecutionsForWorkflowRuns(String workflowName, 205 String userName) throws QueryException { 206 // TODO Auto-generated method stub 207 return null; 208 } 209 210 @Override 211 public List<Integer> getExecutionsForWorkflowRunsAfter(String workflowName, 212 String userName, Date after) throws QueryException { 213 // TODO Auto-generated method stub 214 return null; 215 } 216 217 @Override 218 public List<Integer> getExecutionsForWorkflowRuns(String workflowName, 219 String userName, Date after, Date before, int execIdAfter, 220 int execIdBefore) throws QueryException { 221 // TODO Auto-generated method stub 222 return null; 223 } 224 225 @Override 226 public List<KeplerLSID> getExecutionLSIDsForWorkflowRuns( 227 String workflowName, String userName, Date after, Date before, 228 int execIdAfter, int execIdBefore) throws QueryException { 229 // TODO Auto-generated method stub 230 return null; 231 } 232 233 @Override 234 public List<Integer> getExecutionsForWorkflowRunsBefore( 235 String workflowName, String userName, Date before) 236 throws QueryException { 237 // TODO Auto-generated method stub 238 return null; 239 } 240 241 @Override 242 public Integer getLastExecutionForWorkflow(KeplerLSID lsid) 243 throws QueryException { 244 // TODO Auto-generated method stub 245 return null; 246 } 247 248 @Override 249 public Integer getLastExecutionForWorkflow(String workflow) 250 throws QueryException { 251 // TODO Auto-generated method stub 252 return null; 253 } 254 255 @Override 256 public KeplerLSID getLastExecutionLSIDForWorkflow(String workflow) 257 throws QueryException { 258 // TODO Auto-generated method stub 259 return null; 260 } 261 262 @Override 263 public KeplerLSID getLastExecutionLSIDForWorkflow(KeplerLSID lsid) 264 throws QueryException { 265 // TODO Auto-generated method stub 266 return null; 267 } 268 269 @Override 270 public String getErrorForExecution(KeplerLSID lsid) throws QueryException { 271 // TODO Auto-generated method stub 272 return null; 273 } 274 275 @Override 276 public boolean isErrorForExecution(KeplerLSID executionLSID) 277 throws QueryException { 278 // TODO Auto-generated method stub 279 return false; 280 } 281 282 /** Get an sequence of tokens for an execution. 283 * @param execId the execution id 284 * @param last if true, the sequence starts at the last token created 285 * and goes backwards to the first; otherwise the sequence starts at 286 * the first. 287 */ 288 @Override 289 public List<Integer> getTokensForExecution(int execId, boolean last) 290 throws QueryException 291 { 292 return getTokensForExecution(execId, null, last); 293 } 294 295 /** Get an sequence of tokens for an execution. 296 * @param execId the execution id 297 * @param portId the port id. If null, returns the ids of 298 * tokens read in entire execution. 299 * @param last if true, the sequence starts at the last token created 300 * and goes backwards to the first; otherwise the sequence starts at 301 * the first. 302 */ 303 @Override 304 public List<Integer> getTokensForExecution(int execId, Integer portId, 305 boolean last) throws QueryException { 306 // TODO Auto-generated method stub 307 return null; 308 } 309 310 /** Get the firing id(s) of the actor(s) that read or wrote a token. 311 * @param tokenId the token id 312 * @param read If true, return the actor(s) firing id(s) that read 313 * the token. Otherwise, return the actor firing that wrote the token. 314 */ 315 @Override 316 public List<Integer> getActorFiringForToken(int tokenId, boolean read) 317 throws QueryException { 318 // TODO Auto-generated method stub 319 return null; 320 } 321 322 @Override 323 public List<Integer> getTokensForFiring(int fireId, boolean read) 324 throws QueryException { 325 // TODO Auto-generated method stub 326 return null; 327 } 328 329 /** Get the Token. */ 330 @Override 331 public Token getToken(int tokenId) throws QueryException 332 { 333 Token token = null; 334 //get the type 335 String type = getTokenType(tokenId); 336 //get the value 337 String value = getTokenValue(tokenId); 338 339 if(_stringTokenValuesHaveSurroundingQuotes()) { 340 // if the token is a StringToken, then the value is surrounded 341 // by double-quotes. the quotes should be removed from the value 342 // otherwise they are in the contents of the new StringToken, which 343 // is not identical to the one recorded to provenance. 344 if(type.equals(StringToken.class.getName()) && value.length() >= 2) { 345 value = value.substring(1, value.length() - 1); 346 } 347 } 348 349 if(type.equals(_stringTokenClassName)) { 350 351 //put it together - requires token to have a string constructor 352 try 353 { 354 Class<?> clazz = Class.forName(type); 355 token = (Token) clazz.getConstructor(String.class).newInstance(value); 356 } 357 catch (Exception e) 358 { 359 System.err.println("WARNING: Token could not be constructed for type: " + 360 type + ": " + e.getMessage()); 361 e.printStackTrace(); 362 } 363 364 365 } else { 366 try { 367 synchronized(_parserLock) { 368 if (_parser == null) { 369 _parser = new PtParser(); 370 } 371 372 if (_parseTreeEvaluator == null) { 373 _parseTreeEvaluator = new ParseTreeEvaluator(); 374 } 375 376 ASTPtRootNode parseTree = _parser.generateParseTree(value); 377 token = _parseTreeEvaluator.evaluateParseTree(parseTree); 378 } 379 } catch (Throwable e) { 380 System.err.println("Warning: Token value invalid: " + e.getMessage()); 381 } 382 } 383 384 return token; 385 } 386 387 388 @Override 389 public String getTokenValue(int tokenId) throws QueryException { 390 // TODO Auto-generated method stub 391 return null; 392 } 393 394 @Override 395 public String getTokenType(int tokenId) throws QueryException { 396 // TODO Auto-generated method stub 397 return null; 398 } 399 400 /** Get the channel that a token was read or written on. 401 * @param tokenId the token id 402 * @param read if true, return the channel the token was read on. 403 * otherwise, return the channel the token was written on. 404 * @param fireId the actor firing id. can be null for writes, but 405 * must be specified for reads. 406 * @return the channel the token was read or written on. 407 */ 408 @Override 409 public Integer getChannelForToken(int tokenId, boolean read, Integer fireId) 410 throws QueryException { 411 // TODO 412 return null; 413 } 414 415 @Override 416 public String getActorName(int fireId) throws QueryException { 417 // TODO Auto-generated method stub 418 return null; 419 } 420 421 @Override 422 public String getActorType(int fireId) throws QueryException { 423 // TODO Auto-generated method stub 424 return null; 425 } 426 427 @Override 428 public Integer getEntityId(String entityName, KeplerLSID lsid) 429 throws QueryException { 430 // TODO Auto-generated method stub 431 return null; 432 } 433 434 @Override 435 public Integer getEntityId(String entityName, String workflowName) 436 throws QueryException { 437 // TODO Auto-generated method stub 438 return null; 439 } 440 441 @Override 442 public String getEntityType(Integer entityId) throws QueryException { 443 // TODO Auto-generated method stub 444 return null; 445 } 446 447 @Override 448 public Integer getEntityWorkflowId(Integer entityId) throws QueryException { 449 // TODO Auto-generated method stub 450 return null; 451 } 452 453 @Override 454 public Map<String, String> getParameterNameValuesForFiring(int fireId) 455 throws QueryException { 456 // TODO Auto-generated method stub 457 return null; 458 } 459 460 @Override 461 public Map<String, String> getParameterNameValuesForExecution(int execId) 462 throws QueryException { 463 // TODO Auto-generated method stub 464 return null; 465 } 466 467 @Override 468 public String getParameterValueLatest(String parameter, KeplerLSID lsid) 469 throws QueryException { 470 // TODO Auto-generated method stub 471 return null; 472 } 473 474 @Override 475 public String getParameterValueAtTime(Date timestamp, String parameter, 476 KeplerLSID lsid) throws QueryException { 477 // TODO Auto-generated method stub 478 return null; 479 } 480 481 @Override 482 public List<Integer> getImmediateDependencies(int tokenId) 483 throws QueryException { 484 // TODO Auto-generated method stub 485 return null; 486 } 487 488 @Override 489 public List<byte[]> getAssociatedDataForExecution(int execId, 490 Map<String, String> metadataMap, boolean matchAny) 491 throws QueryException { 492 // TODO Auto-generated method stub 493 return null; 494 } 495 496 /** Get any associated keys-values for an execution. */ 497 @Override 498 public Map<String,String> getAssociatedKeysValuesForExecution(int execId) 499 throws QueryException { 500 // TODO 501 return null; 502 } 503 504 @Override 505 public Map<KeplerLSID, WorkflowRun> getWorkflowRunsForExecutionLSIDs( 506 List<KeplerLSID> executions) throws QueryException { 507 // TODO Auto-generated method stub 508 return null; 509 } 510 511 /** Get workflow runs for a user. */ 512 @Override 513 public List<WorkflowRun> getWorkflowRunsForUser(String user) throws QueryException { 514 return new LinkedList<WorkflowRun>(); 515 } 516 517 @Override 518 public List<Integer> getExecutionIdsForTags(String tagsSearchString) 519 throws QueryException { 520 // TODO Auto-generated method stub 521 return null; 522 } 523 524 @Override 525 public List<String> getTagsForExecutionId(int execId) throws QueryException { 526 // TODO Auto-generated method stub 527 return null; 528 } 529 530 @Override 531 public String getTypeForTag(String conceptId) { 532 // TODO Auto-generated method stub 533 return null; 534 } 535 536 @Override 537 public Map<NamedOntClass, String> getTagClassesForExecutionId(int execId) 538 throws QueryException { 539 // TODO Auto-generated method stub 540 return null; 541 } 542 543 @Override 544 public Integer getExecutionForExecutionLSIDWithoutRevision( 545 String execLSIDWithoutRevision) throws QueryException { 546 // TODO Auto-generated method stub 547 return null; 548 } 549 550 @Override 551 public Integer getExecutionForOldestReferralExecutionLSIDWithoutRevision( 552 String stringWithoutRevision) throws QueryException { 553 // TODO Auto-generated method stub 554 return null; 555 } 556 557 @Override 558 public List<KeplerLSID> getExecutionsForType(type type) 559 throws QueryException { 560 // TODO Auto-generated method stub 561 return null; 562 } 563 564 @Override 565 public boolean isImportedExecution(KeplerLSID executionLSID) 566 throws QueryException { 567 // TODO Auto-generated method stub 568 return false; 569 } 570 571 @Override 572 public List<String> getPortsForActor(KeplerLSID workflow, String actor) 573 throws QueryException { 574 // TODO Auto-generated method stub 575 return null; 576 } 577 578 @Override 579 public String getUserForExecution(Integer execId) throws QueryException { 580 // TODO Auto-generated method stub 581 return null; 582 } 583 584 @Override 585 public String getUserForExecution(KeplerLSID execLSID) throws QueryException { 586 // TODO Auto-generated method stub 587 return null; 588 } 589 590 @Override 591 public String getHostIdForExecution(Integer execId) throws QueryException { 592 // TODO Auto-generated method stub 593 return null; 594 } 595 596 @Override 597 public String getOutputRoleToken(int tokenId) throws QueryException { 598 // TODO Auto-generated method stub 599 return null; 600 } 601 602 @Override 603 public String getInputRoleForTokenAndFireId(int tokenId, int fireId) 604 throws QueryException { 605 // TODO Auto-generated method stub 606 return null; 607 } 608 609 @Override 610 public Map<String, String> getParameterNameValuesOfSpecificTypeForExecution( 611 int execId) throws QueryException { 612 // TODO Auto-generated method stub 613 return null; 614 } 615 616 @Override 617 public Date[] getTimestampsForActorFiring(int fireId) throws QueryException { 618 // TODO Auto-generated method stub 619 return null; 620 } 621 622 @Override 623 public List<Integer> getActorFiringIds(String actorName, Integer wfExecId) 624 throws QueryException { 625 // TODO Auto-generated method stub 626 return null; 627 } 628 629 @Override 630 public Map<String, String> getParameterAndPortParameterNameValuesForFiring( 631 int fireId) throws QueryException { 632 // TODO Auto-generated method stub 633 return null; 634 } 635 636 @Override 637 public List<Integer> getActorFirings(int wfExecId) throws QueryException { 638 // TODO Auto-generated method stub 639 return null; 640 } 641 642 /** Get the total execution time for an actor. 643 * 644 * @param workflow the workflow LSID. If null, must specify execution id. 645 * @param execLSID the execution id. If null, use the last execution of the workflow. 646 * @param actor the full actor name. 647 * @return the total time execution time of the actor, in milliseconds. 648 */ 649 @Override 650 public long getTotalExecutionTimeForActor(KeplerLSID workflow, KeplerLSID execLSID, 651 String actor) throws QueryException 652 { 653 Map<String,Long> map = getExecutionTimesForActor(workflow, execLSID, actor); 654 long sum = 0; 655 for(Long time : map.values()) 656 { 657 sum += time; 658 } 659 return sum; 660 } 661 662 /** Get the execution times for an actor. 663 * 664 * @param workflow the workflow LSID. If null, must specify execution id. 665 * @param execLSID the execution LSID. If null, the last execution of the workflow 666 * is used. 667 * @param actor the full actor name. 668 * @return a map of actor fire id to execution time pairs. if a firing does not 669 * have a valid start or stop time, the firing is not included in the result. 670 */ 671 @Override 672 public Map<String,Long> getExecutionTimesForActor(KeplerLSID workflow, 673 KeplerLSID execLSID, String actor) throws QueryException { 674 // TODO Auto-generated method stub 675 return null; 676 } 677 678 /** Get the number of bytes read or written by a port. 679 * 680 * @param workflow the workflow LSID. If null, must specify execution id. 681 * @param execId the execution id. If null, the last execution of the workflow 682 * is used. 683 * @param port the full port name. 684 * @param read If true, get the bytes read. Otherwise, get the bytes written. 685 * @return a map of port event id to bytes read/written. 686 */ 687 @Override 688 public Map<Integer,Integer> getIOBytesForPort(KeplerLSID workflow, Integer execId, 689 String port, boolean read) throws QueryException { 690 // TODO Auto-generated method stub 691 return null; 692 } 693 694 /** Get the total number of bytes read or or written by an actor over all its ports. 695 * @param workflow the workflow LSID. If null, specify the execution id. 696 * @param execId the execution id. If null, the last execution of the workflow 697 * is used. 698 * @param actor the full actor name. 699 * @param read If true, get the bytes read. Otherwise, get the bytes written. 700 */ 701 @Override 702 public Integer getTotalIOBytesForActor(KeplerLSID workflow, Integer execId, String actor, 703 boolean read) throws QueryException 704 { 705 Integer retval = 0; 706 707 if(execId == null) 708 { 709 execId = _getLastExecutionId(workflow); 710 } 711 712 List<String> portsList = getPortsForActor(workflow, actor); 713 714 for(String port : portsList) 715 { 716 Map<Integer,Integer> map = getIOBytesForPort(workflow, execId, port, read); 717 for(Integer size : map.values()) 718 { 719 retval += size; 720 } 721 } 722 723 return retval; 724 } 725 726 /* 727 @Override 728 public List<LinkIO> getLinksIO(KeplerLSID workflow, Integer execId) throws QueryException { 729 // TODO Auto-generated method stub 730 return null; 731 } 732 */ 733 734 /** Get the timestamp(s) when a token was read. If a token was 735 * never read, this can return null or an empty array. 736 */ 737 @Override 738 public Date[] getTimestampsForTokenRead(Integer tokenId) throws QueryException { 739 return null; 740 } 741 742 /** Get the timestamp when a token was written. */ 743 @Override 744 public Date getTimestampForTokenWrite(Integer tokenId) throws QueryException { 745 return null; 746 } 747 748 /** Get the last execution id for a workflow. If no execution id found, 749 * throws exception. 750 */ 751 protected Integer _getLastExecutionId(KeplerLSID workflow) 752 throws QueryException 753 { 754 if(workflow == null) 755 { 756 throw new QueryException("Must specify either workflow LSID or execution id."); 757 } 758 759 // get the last execution id for the workflow 760 Integer execId = getLastExecutionForWorkflow(workflow); 761 762 if(execId == null) 763 { 764 throw new QueryException("Could not find last execution for workflow."); 765 } 766 return execId; 767 } 768 769 /** Returns true if getTokenValue() for StringTokens has 770 * surrounding double-quotes. i.e., the value was saved 771 * using StringToken.toString() (which adds double-quotes) 772 * instead of StringToken.stringValue(). 773 */ 774 abstract protected boolean _stringTokenValuesHaveSurroundingQuotes(); 775 776 /** A mapping of execution id to workflow objects. We use weak 777 * references for the workflow objects so that they can be garbage 778 * collected. 779 */ 780 private static Map<Integer,WeakReference<NamedObj>> _executionToWorkflowMap = 781 new HashMap<Integer,WeakReference<NamedObj>>(); 782 783 private static final Object _parserLock = new Object(); 784 private ParseTreeEvaluator _parseTreeEvaluator = null; 785 private PtParser _parser = null; 786 private static final String _stringTokenClassName = StringToken.class.getName(); 787 788}