Skip to content

Commit

Permalink
Merge pull request #39 from johandahlberg/add_index_checking_to_workflow
Browse files Browse the repository at this point in the history
Add index checking to workflow
  • Loading branch information
Johan Hermansson authored Sep 1, 2016
2 parents 4729cf6 + 842a80d commit aacef1d
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 80 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Getting an authentication token

Get your auth token setup (substitute for correct user and password as necessary) :

export ST2_AUTH_TOKEN=$(st2 auth --only-token testu -p testp)
export ST2_AUTH_TOKEN=$(st2 auth --only-token arteriaadmin -p arteriarulz)

Example of starting a workflow
------------------------------
Expand Down
103 changes: 43 additions & 60 deletions actions/poll_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import requests
from requests.exceptions import RequestException
import click
import logging
import os
# Needs to be run in a Stackstorm virtualenv
from st2actions.runners.pythonrunner import Action
Expand All @@ -21,33 +20,17 @@ class PollStatus(Action):
error is generated and the polling stops.
"""

LOG_FILENAME = None

def log(self, output):
""" Quick way of putting output to a log file and stdout
"""
logging.basicConfig(filename = self.LOG_FILENAME, level = logging.DEBUG)
logging.debug(output)
print output

def shutdown(self, returncode):
""" Shuts down the logging framework properly by flushing all buffers
and closing handlers; then returns with a return code.
"""
logging.shutdown()
sys.exit(returncode)

def query(self, url, verify_ssl_cert):
try:
resp = requests.get(url, verify=verify_ssl_cert)
state = resp.json()["state"]
return state, resp
return resp
except RequestException as err:
current_time = datetime.datetime.now()
self.log("{0} -- {1} - an error was encountered: {2}".format(current_time, url, err))
self.logger.warning(
"{0} -- {1} - an error was encountered: {2}".format(current_time, url, err))
return None, None

def run(self, url, sleep, log, ignore_result, verify_ssl_cert, max_retries = 3):
def run(self, url, sleep, ignore_result, verify_ssl_cert, max_retries=3):
"""
Query the url end-point. Can be called directly from StackStorm, or via the script cli
:param url: to call
Expand All @@ -60,70 +43,70 @@ def run(self, url, sleep, log, ignore_result, verify_ssl_cert, max_retries = 3):
"""
retry_attempts = 0
state = "started"
self.LOG_FILENAME = log

while state == "started" or state == "pending" or not state:
current_time = datetime.datetime.now()

state, resp = self.query(url, verify_ssl_cert)
resp = self.query(url, verify_ssl_cert)
json_resp = resp.json()
state = json_resp["state"]

if state == "started" or state == "pending":
self.log("{0} -- {1} returned state {2}. Sleeping {3}m until retrying again...".format(current_time,
url,
state,
sleep))
self.logger.info("{0} -- {1} returned state {2}. Sleeping {3}m until retrying again...".format(current_time,
url,
state,
sleep))
time.sleep(sleep * 60)
elif state == "done":
self.log("{0} -- {1} returned state {2}. Will now stop polling the status.".format(current_time,
url,
state))
self.shutdown(0)
self.logger.info("{0} -- {1} returned state {2}. Will now stop polling the status.".format(current_time,
url,
state))

return (0, json_resp)
elif state in ["error", "none", "cancelled"]:
self.log("{0} -- {1} returned state {2}. Will now stop polling the status.".format(current_time,
url,
state))
self.log(resp.json())
self.logger.warning("{0} -- {1} returned state {2}. Will now stop polling the status.".format(current_time,
url,
state))

if ignore_result:
self.shutdown(0)
return (0, json_resp)
else:
self.shutdown(1)
return (1, json_resp)

elif not state and retry_attempts < max_retries:
retry_attempts += 1
self.log("{0} -- {1} did not report state. "
"Probably due to a connection error, will retry. Attempt {2} of {3}.".format(current_time,
url,
retry_attempts,
max_retries))
self.logger.warning("{0} -- {1} did not report state. "
"Probably due to a connection error, "
"will retry. Attempt {2} of {3}.".format(current_time,
url,
retry_attempts,
max_retries))
time.sleep(sleep * 60)
else:
self.log("{0} -- {1} returned state unknown state {2}. "
"Will now stop polling the status.".format(current_time, url, state))
self.log(resp.json())
self.shutdown(1)
self.logger.error("{0} -- {1} returned state unknown state {2}. "
"Will now stop polling the status.".format(current_time, url, state))
return (1, json_resp)


@click.command()
@click.option("--url", required = True, help = "URL to poll")
@click.option("--sleep", default = 1, required = False,
help = "Number of minutes to sleep between poll (default 1)")
@click.option("--log", required = False,
default = "/var/log/arteria/poll_status.log",
help = "Path to log file (default /var/log/arteria/poll_status.log)")
@click.option("--ignore_result", required = False,
default = False,
help = "Return 0 exit status even if polling failed.")
@click.option("--verify_ssl_cert/--skip_ssl_cert", required = False,
default = True,
help = "Verify SSL cert. Default is true.")
def start(url, sleep, log, ignore_result, verify_ssl_cert):
@click.option("--url", required=True, help="URL to poll")
@click.option("--sleep", default=1, required=False,
help="Number of minutes to sleep between poll (default 1)")
@click.option("--ignore_result", required=False,
default=False,
help="Return 0 exit status even if polling failed.")
@click.option("--verify_ssl_cert/--skip_ssl_cert", required=False,
default=True,
help="Verify SSL cert. Default is true.")
def start(url, sleep, ignore_result, verify_ssl_cert):
""" Accepts an URL to poll (e.g. http://testarteria1:10900/api/1.0/qc/status/4224)
and sleeps a number of minutes between every poll (default 1 minute).
Will continue to poll as long as a returned JSON field called state contains 'started'.
Exits with an error if 'error' or 'none' is received, and with success if 'done'
is received.
"""
PollStatus().run(url, sleep, log, ignore_result, verify_ssl_cert)
PollStatus().run(url, sleep, ignore_result, verify_ssl_cert)

if __name__ == "__main__":
start()
6 changes: 0 additions & 6 deletions actions/poll_status.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,3 @@ parameters:
required: false
position: 3
default: true
log:
type: string
description: Path to log file (default /var/log/arteria/poll_status.log)
required: false
position: 3
default: /var/log/arteria/poll_status.log
32 changes: 27 additions & 5 deletions actions/workflows/ngi_uu_workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ workflows:
runfolder_service_port: <% task(get_config).result.result.runfolder_service_port %>
send_mail_to: <% task(get_config).result.result.send_mail_to %>
remote_sisyphus_location: <% task(get_config).result.result.remote_sisyphus_location %>
nestor_remote_path: <% task(get_config).result.result.nestor_remote_path %>
irma_remote_path: <% task(get_config).result.result.irma_remote_path %>
irma_api_key: <% task(get_config).result.result.irma_api_key %>
irma_checksum_base_url: <% task(get_config).result.result.irma_checksum_base_url %>
Expand All @@ -60,7 +59,7 @@ workflows:

mark_as_started:
action: core.http
input:
input:
url: http://<% $.host %>:<% $.runfolder_service_port %>/api/1.0/runfolders/path<% $.runfolder %>
body: '{"state": "started"}'
method: "POST"
Expand Down Expand Up @@ -91,7 +90,7 @@ workflows:
action: core.http
input:
url: <% $.hermes_base_url %>/<% $.flowcell_name %>/samplesheetfile
headers:
headers:
USER: <% $.hermes_user %>
X-XSRF-TOKEN: <% $.hermes_token %>
publish:
Expand Down Expand Up @@ -178,9 +177,32 @@ workflows:
input:
url: "<% $.report_status_url %>"
on-success:
- download_qc_config
- run_sisyphus_check_indices
### QUICK REPORT END ###

### CHECK INDICES START###
run_sisyphus_check_indices:
action: core.http
input:
url: "http://<% $.host %>:<% $.siswrap_service_port %>/api/1.0/checkindices/run/<% $.runfolder_name %>"
method: "POST"
headers:
Content-Type: application/json
body: '{"runfolder": "<% $.runfolder_name %>"}'
publish:
sisyphus_check_indices_status_url: <% task(run_sisyphus_check_indices).result.body.link %>
on-success:
- poll_check_indices_status

poll_check_indices_status:
action: arteria-packs.poll_status
input:
url: "<% $.sisyphus_check_indices_status_url %>"
ignore_result: <% $.ignore_sisyphus_qc_result %>
on-success:
- download_qc_config
### CHECK INDICES END###

### QUALITY CONTROL START ###
download_qc_config:
action: core.http
Expand Down Expand Up @@ -253,7 +275,7 @@ workflows:
action: core.http
input:
url: <% $.hermes_base_url %>/<% $.flowcell_name %>/flowcell/analysishostinfo
headers:
headers:
USER: <% $.hermes_user %>
X-XSRF-TOKEN: <% $.hermes_token %>
on-success:
Expand Down
14 changes: 6 additions & 8 deletions tests/test_poll_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ def run_with_state(self, state, expected_exit_status, ignore_results=False):
with mock.patch.object(requests, 'get', return_value=self.MockResponse(state)):
action = self.get_action_instance()

with self.assertRaises(SystemExit) as cm:
result = action.run(url='http://www.google.com',
sleep=0.02,
log="/dev/null",
ignore_result=ignore_results,
verify_ssl_cert=False,
max_retries=1)
self.assertTrue(cm.exception.code == expected_exit_status)
(exit_code, result) = action.run(url='http://www.google.com',
sleep=0.02,
ignore_result=ignore_results,
verify_ssl_cert=False,
max_retries=1)
self.assertTrue(exit_code == expected_exit_status)

def test_done(self):
self.run_with_state(state=["done"], expected_exit_status=0, ignore_results=False)
Expand Down

0 comments on commit aacef1d

Please sign in to comment.