Beispiel #1
0
  @Override
  public String executeProcess(String sosEndpoint, RunMetadata metadata) {
    if (StringUtils.isBlank(sosEndpoint)) {
      throw new IllegalArgumentException("sosEndpoint parameter may not be null or blank");
    }

    WPSTask task = new WPSTask(sosEndpoint, metadata.toKeyValueMap());
    task.start();
    if (task.isAlive()) {
      return "ok";
    } else {
      return "not started";
    }
  }
Beispiel #2
0
  private void sendFailedEmail(Exception ex, String to) {
    String subject = "WaterSMART processing failed";
    StringBuilder content = new StringBuilder();
    content.append("Your request unfortunately failed, we are looking into it.");
    content.append("\n\tUpload: ").append((uploadSuccessful) ? "success" : "failure");
    content.append("\n\tParse: ").append((netcdfSuccessful) ? "success" : "failure");
    content.append("\n\tStatistics: ").append((rStatsSuccessful) ? "success" : "failure");
    content.append("\n\tMetadata: ").append((cswTransSuccessful) ? "success" : "failure");

    RunMetadata metaObj = RunMetadata.getInstance(metadata);
    content.append("\n\n\tFile: ").append(metaObj.getFileName());
    content.append("\n\tModeler: ").append(metaObj.getName());
    content.append("\n\tComments: ").append(metaObj.getComments());
    content.append("\n\tDate: ").append(metaObj.getCreationDate());

    content.append("\n\nthe application failed with message: ").append(ex.getMessage());

    content.append("\n\nhere is the stack trace for troubleshooting:\n\n");
    for (StackTraceElement el : ex.getStackTrace()) {
      content.append(el.toString()).append("\n");
    }
    List<String> bcc = new ArrayList<String>();
    String from = props.getProperty("watersmart.email.from");
    String bccAddr = props.getProperty("watersmart.email.tracker");
    if (!"".equals(bccAddr)) {
      bcc.add(bccAddr);
    }
    EmailMessage message = new EmailMessage(from, to, null, bcc, subject, content.toString());
    try {
      EmailHandler.sendMessage(message);
    } catch (AddressException ex1) {
      log.error(
          "Unable to send failed e-mail:\n"
              + message
              + "\n\nOriginal Exception:\n"
              + ex.getMessage(),
          ex1);
    } catch (MessagingException ex1) {
      log.error(
          "Unable to send failed e-mail:\n"
              + message
              + "\n\nOriginal Exception:\n"
              + ex.getMessage(),
          ex1);
    }
  }
Beispiel #3
0
  private void sendCompleteEmail(Map<String, String> outputs, String to) {
    String subject = "Processing Complete";
    StringBuilder content = new StringBuilder();
    content
        .append("Your upload has finished conversion and processing,")
        .append(" you may view the results of the processing by going to:\n");

    for (String alg : outputs.keySet()) {
      content.append("\t").append(alg).append(": ").append(outputs.get(alg)).append("\n");
    }

    content.append("\nor return to the application to view your upload.");

    content.append("\nJust to double check, here is what happened");
    content.append("\n\tUpload: ").append((uploadSuccessful) ? "success" : "failure");
    content.append("\n\tParse: ").append((netcdfSuccessful) ? "success" : "failure");
    content.append("\n\tStatistics: ").append((rStatsSuccessful) ? "success" : "failure");
    content.append("\n\tMetadata: ").append((cswTransSuccessful) ? "success" : "failure");

    RunMetadata metaObj = RunMetadata.getInstance(metadata);
    content.append("\n\n\tFile: ").append(metaObj.getFileName());
    content.append("\n\tModeler: ").append(metaObj.getName());
    content.append("\n\tComments: ").append(metaObj.getComments());
    content.append("\n\tDate: ").append(metaObj.getCreationDate());

    content.append("\n\nHave a nice day!");
    List<String> bcc = new ArrayList<String>();
    String from = props.getProperty("watersmart.email.from");
    String bccAddr = props.getProperty("watersmart.email.tracker");
    if (!"".equals(bccAddr)) {
      bcc.add(bccAddr);
    }

    EmailMessage message = new EmailMessage(from, to, null, bcc, subject, content.toString());
    try {
      EmailHandler.sendMessage(message);
    } catch (AddressException ex) {
      log.error("Unable to send completed e-mail:\n" + message, ex);
    } catch (MessagingException ex) {
      log.error("Unable to send completed e-mail:\n" + message, ex);
    }
  }
Beispiel #4
0
 @Override
 public String executeProcess(File zipLocation, RunMetadata metadata) {
   return executeProcess(zipLocation, metadata.toKeyValueMap());
 }
Beispiel #5
0
 private void sendFailedEmail(Exception ex) {
   sendFailedEmail(ex, RunMetadata.getInstance(metadata).getEmail());
 }
Beispiel #6
0
 private void sendCompleteEmail(Map<String, String> outputs) {
   sendCompleteEmail(outputs, RunMetadata.getInstance(metadata).getEmail());
 }
Beispiel #7
0
  /**
   * @param alg Algorithm to run
   * @param wpsRequest XML representing WPS request
   * @param uuid UUID for output
   * @param metaObj RunMetadata associated with user
   * @return Web Accessible File with process results
   * @throws IOException
   * @throws ParserConfigurationException
   * @throws SAXException
   * @throws XPathExpressionException
   * @throws InterruptedException
   */
  private String runNamedAlgorithm(String alg, String wpsRequest, UUID uuid, RunMetadata metaObj)
      throws IOException, ParserConfigurationException, SAXException, XPathExpressionException,
          InterruptedException {

    // String wpsRequest = WPSImpl.createNahatStatsRequest(sosEndpoint, info.stations,
    // info.properties);
    String wpsResponse = postToWPS(props.getProperty("watersmart.wps.url"), wpsRequest);
    log.debug(wpsResponse);
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    Document wpsResponseDoc =
        factory.newDocumentBuilder().parse(new ByteArrayInputStream(wpsResponse.getBytes()));
    ProcessStatus procStat = new ProcessStatus(wpsResponseDoc);
    String wpsCheckPoint = procStat.getStatusLocation();
    log.debug(wpsCheckPoint);
    String contextPath = props.getProperty("watersmart.external.mapping.url");

    InputStream is = null;
    InputStream resultIs = null;

    try {
      boolean completed = false;
      Document document = null;
      int checks = 0;
      while (!completed) {
        checks++;
        // TODO-
        // http://stackoverflow.com/questions/3535754/netbeans-java-new-hint-thread-sleep-called-in-loop
        Thread.sleep(CHECK_WAIT);
        log.debug("Checking: " + checks);
        is = HTTPUtils.sendPacket(new URL(wpsCheckPoint), "GET");
        document = CheckProcessCompletion.parseDocument(is);
        completed = checkWPSProcess(document);
        if (checks == CHECKS_UNTIL_NOTIFY) {
          sendMaybeEmail(metaObj.getEmail());
        }
        if (checks > CHECKS_UNTIL_FAIL) {
          throw new IOException("R Statistics never returned");
        }
      }

      ProcessStatus resultStatus = new ProcessStatus(document);
      String outputReference = resultStatus.getOutputReference();
      resultIs = HTTPUtils.sendPacket(new URL(outputReference), "GET");
      String resultStr = IOUtils.toString(resultIs, "UTF-8");
      // copy results to persistant location // switch to completed document above

      log.debug(resultStr);

      File destinationDir =
          new File(
              props.getProperty("watersmart.file.location")
                  + props.getProperty("watersmart.file.location.wps.repository")
                  + File.separatorChar
                  + uuid);
      if (!destinationDir.exists()) {
        FileUtils.forceMkdir(destinationDir);
      }
      String filename =
          metaObj.getTypeString()
              + "-"
              + metaObj.getScenario()
              + "-"
              + metaObj.getModelVersion()
              + "."
              + metaObj.getRunIdent()
              + "-"
              + alg
              + ".txt";
      File destinationFile =
          new File(destinationDir.getCanonicalPath() + File.separatorChar + filename);
      FileUtils.write(destinationFile, resultStr, "UTF-8");
      String destinationFileName = destinationFile.getName();
      String webAccessibleFile =
          contextPath
              + props.getProperty("watersmart.file.location.wps.repository")
              + "/"
              + uuid
              + "/"
              + destinationFileName;

      return webAccessibleFile;
    } finally {
      IOUtils.closeQuietly(is);
      IOUtils.closeQuietly(resultIs);
    }
  }
Beispiel #8
0
  @Override
  public void run() {
    CSWTransactionHelper helper;
    Map<String, String> wpsOutputMap = Maps.newHashMap();
    ReturnInfo info;
    RunMetadata metaObj = RunMetadata.getInstance(metadata);
    String compReq;
    String repo = props.getProperty("watersmart.sos.model.repo");
    String netCDFFailMessage = "NetCDF failed unexpectedly ";
    String cswResponse;
    UUID uuid = UUID.randomUUID();

    // -- Start here if we have a file and no SOS endpoint...
    // 1. Create NetCDF file
    // 2. Add results from NetCDF creation to CSW record
    // 3. Wait for THREDDS
    // -- Start here if we have an SOS endpoint
    // 4. Run the compare stats WPS process
    // 5. Add results from WPS process to CSW record

    if (StringUtils.isBlank(sosEndpoint)) {
      // SOS is blank which means we have to create it. Otherwise, the typical use
      // case is that the client is requesting a re-run

      // 1. Create NetCDF file
      try {
        log.debug("Creating NetCDF file");
        // CreateDSGFromZip.create() seems to cause a lot of grief. We keep getting:
        // java.lang.UnsatisfiedLinkError: Native Library
        // ${application_path}/loader/com/sun/jna/linux-amd64/libnetcdf.so already loaded in another
        // classloader
        // When developing and I see this, I have to restart the server and redeploy the project
        // The fault happens at
        // gov.usgs.cida.jna.NetCDFJNAInitializer.contextDestroyed(NetCDFJNAInitializer.java:21)
        info = CreateDSGFromZip.create(zipLocation, metaObj);
        if (info != null && info.properties != null) {
          netcdfSuccessful = true;
        } else {
          log.error(netCDFFailMessage);
          sendFailedEmail(new RuntimeException(netCDFFailMessage));
          throw new IOException("Output from NetCDF creation process was null");
        }
      } catch (IOException ex) {
        log.error(netCDFFailMessage, ex);
        sendFailedEmail(new RuntimeException(netCDFFailMessage));
        return;
      } catch (XMLStreamException ex) {
        log.error(netCDFFailMessage, ex);
        sendFailedEmail(new RuntimeException(netCDFFailMessage));
        return;
      } catch (RuntimeException ex) {
        log.error(netCDFFailMessage, ex);
        sendFailedEmail(new RuntimeException(netCDFFailMessage));
        return;
      }

      // The NetCDF process has passed so create a CSW record for the run and
      // insert what we have so far.
      // The WPS output will be updated once the process succeeds/fails.  The UI
      // will show "Process not yet completed" in the meantime.
      sosEndpoint = repo + metaObj.getTypeString() + "/" + info.filename;
      wpsOutputMap.put(WPSImpl.stats_compare, "");
      helper = new CSWTransactionHelper(metaObj, sosEndpoint, wpsOutputMap);
      // 2. Add results from NetCDF creation to CSW record
      try {
        log.debug("Adding results from NetCDF creation to CSW record");
        cswResponse = helper.addServiceIdentification();
        if (cswResponse != null) {
          cswTransSuccessful = true;
        } else {
          cswTransSuccessful = false;
          throw new IOException("Unable to update CSW Record");
        }
      } catch (Exception ex) {
        log.error("Failed to perform CSW insert", ex);
        sendFailedEmail(ex);
        return;
      }

      // 3. Wait for THREDDS
      try {
        log.debug("Beginning THREDDS wait period");
        Thread.sleep(SLEEP_FOR_THREDDS);
      } catch (InterruptedException ex) {
        // Typically we don't care about this, but we can log and move on.
        log.warn("THREDDS wait period was interrupted.");
        // If anything needs to be handled on an interruption, handle it here
      }
      log.trace("End of THREDDS wait period");
    }

    // 4. Run the compare stats using the R-WPS package
    try {
      log.debug("Sending request for compare stats");
      compReq = WPSImpl.createCompareStatsRequest(sosEndpoint);
      String algorithmOutput = runNamedAlgorithm("compare", compReq, uuid, metaObj);
      wpsOutputMap.put(WPSImpl.stats_compare, algorithmOutput);
    } catch (Exception ex) {
      log.error("Failed to run WPS algorithm", ex);
      sendFailedEmail(ex);
      return;
    }

    // 5. Add results from WPS process to CSW record
    if (wpsOutputMap.get(WPSImpl.stats_compare) != null) {
      log.debug("Stats compare completed successfully");
      rStatsSuccessful = true;
      helper = new CSWTransactionHelper(metaObj, sosEndpoint, wpsOutputMap);
      try {
        cswResponse = helper.updateRunMetadata(metaObj);
        cswTransSuccessful = cswResponse != null;
        sendCompleteEmail(wpsOutputMap);
      } catch (IOException ex) {
        log.error("Failed to perform CSW update", ex);
        sendFailedEmail(ex);
      } catch (URISyntaxException ex) {
        log.error("Failed to perform CSW update,", ex);
        sendFailedEmail(ex);
      }
    } else {
      log.error("Stats compare failed");
      sendFailedEmail(new Exception("Failed to run WPS algorithm"));
    }
  }