Beispiel #1
0
    def hpcprepWaiter(sessionToken, extraParameters, seconds_to_wait):
        """Creates all parameters required as input by the HPC launcher.

        Most parameters are hard-coded here, but in other scenarios (for example
        with user-defined input), some more string handling will happen here.
        """
        # Validate session token
        ep = ExtraParameters(extraParameters)
        auth = AuthClient(ep.get_auth_WSDL_URL())
        if not auth.validate_session_token(sessionToken):
            logging.error("Token validation failed")
            error_msg = "Session-token validation failed"
            raise TokenValidationFailedFault(faultstring=error_msg)

        # Prepare parameters the HPC launcher needs
        image_name = "waiter_abortable.simg"
        commandline = "python"
        parameters = "/app/startup.py {} /app".format(seconds_to_wait)
        queue = "qexp"
        numNodes = os.environ["N_NODES"]
        numCores = os.environ["N_CORES"]
        maxDurationInMinutes = 5
        SingularityVersion = "2.4.2"

        return (image_name, commandline, parameters, queue, numNodes, numCores,
                maxDurationInMinutes, SingularityVersion)
Beispiel #2
0
    def showDialog(serviceID, sessionToken, extraParameters):
        """
        Starts the dialog application.
        """
        logging.info(
            "startDialog() called with service ID {}".format(serviceID))

        # Check that the session token is valid and abort with a SOAP fault if
        # it's not. To that end, we use the clfpy library both to extract the
        # authentication endpoint from the extraParameters input argument and
        # to communicate with that endpoint.
        ep = ExtraParameters(extraParameters)
        auth = AuthClient(ep.get_auth_WSDL_URL())
        if not auth.validate_session_token(sessionToken):
            logging.error("Token validation failed")
            error_msg = "Session-token validation failed"
            raise TokenValidationFailedFault(faultstring=error_msg)

        # The entire application, which will be visible to the user running the
        # workflow, is packed in the status report created in this method.
        # Here, we create a simple HTML page with a button to continue the
        # workflow.
        status = base64.b64encode(
            create_html_dialog(serviceID, sessionToken,
                               ep.get_WFM_endpoint()).encode()).decode()
        result = "UNSET"

        return (status, result)
Beispiel #3
0
    def abortService(ctx, serviceID, sessionToken):
        """Aborts the currently running service (not implemented, returns false)
        """
        logging.info(
            "abortService() called with service ID {}".format(serviceID))

        # We obtain the authentication-manager endpoint from a class property
        # and check that the session token is valid
        # Read wsdl URL from a file
        waiterdir = os.path.join(WAITER_LOG_FOLDER, serviceID)
        wsdlfile = os.path.join(waiterdir, 'wsdl.txt')
        with open(wsdlfile) as f:
            auth_wsdl = f.read().strip()

        auth = AuthClient(auth_wsdl)
        if not auth.validate_session_token(sessionToken):
            error_msg = "Session-token validation failed"
            raise TokenValidationFailedFault(faultstring=error_msg)

        # This method offers the option to abort long-running asynchronous
        # services. In this example, we do not implement this functionality
        # and thus always return False.
        # In a more realistic scenario, this method would terminate the
        # background computation process gracefully.

        return False
def main():
    port = 80

    try:
        context_root = os.environ["CONTEXT_ROOT"]
    except KeyError:
        print("Error: environment variable CONTEXT_ROOT not set.")
        exit(1)

    url = "http://localhost:{}{}/Dialog?wsdl".format(port, context_root)
    print("wsdl URL is {}".format(url))

    print("Obtaining session token")
    user = input("Enter username: "******"Enter project: ")
    password = getpass.getpass(prompt="Enter password: "******"Calling startDialog()")
    response = soap_call(url, "showDialog", ["serviceID1", token, extra_pars])
    html = base64.b64decode(response["status_base64"]).decode()
    with open("test.html", 'w') as fout:
        fout.write(html)
    print("Result written to test.html")
Beispiel #5
0
def main():
    """Makes a series of test calls and prints their outputs."""

    port = 80

    try:
        context_root = os.environ["CONTEXT_ROOT"]
    except KeyError:
        print("Error: environment variable CONTEXT_ROOT not set.")
        exit(1)

    print("Obtaining session token")
    user = input("Enter username: "******"Enter project: ")
    password = getpass.getpass(prompt="Enter password: "******"http://localhost:{}{}/WaiterPrep?wsdl".format(port, context_root)
    print("wsdl URL is {}".format(url))

    print("Calling preprocessor with 45 seconds waiting time:")
    response = soap_call(url, "hpcprepWaiter", [token, extra_pars, 45])
    print(response)
Beispiel #6
0
def main():
    port = 80

    try:
        context_root = os.environ["CONTEXT_ROOT"]
    except KeyError:
        print("Error: environment variable CONTEXT_ROOT not set.")
        exit(1)

    url = "http://localhost:{}{}/Waiter?wsdl".format(port, context_root)
    print("wsdl URL is {}".format(url))

    if len(sys.argv) != 2:
        print("Expected [start|status] as argument.")
        exit(1)

    print("Obtaining session token")
    user = input("Enter username: "******"Enter project: ")
    password = getpass.getpass(prompt="Enter password: ")
    auth = AuthClient(auth_endpoint)
    token = auth.get_session_token(user, project, password)

    if sys.argv[1] == 'start':
        start(url, token)
    elif sys.argv[1] == 'status':
        status(url, token)
    else:
        print('Unknown argument.')
    def abortService(ctx, serviceID, sessionToken):
        """Aborts the currently running service (not implemented, returns false)
        """
        logging.info(f"abortService() called with service ID {serviceID}")

        # We obtain the authentication-manager endpoint from a class property
        # and check that the session token is valid
        # Read wsdl URL from a file
        logdir = os.path.join(LOG_FOLDER, serviceID)
        wsdlfile = os.path.join(logdir, 'wsdl.txt')
        with open(wsdlfile) as f:
            auth_wsdl = f.read().strip()

        auth = AuthClient(auth_wsdl)
        if not auth.validate_session_token(sessionToken):
            error_msg = "Session-token validation failed"
            raise TokenValidationFailedFault(faultstring=error_msg)

        pidfile = os.path.join(logdir, 'pid.txt')
        with open(pidfile) as f:
            pid = f.read().strip()

        try:
            os.kill(int(pid), signal.SIGKILL)
        except Exception as ex:
            print('Exception while aborting consumer')
            print(str(ex))
            return False
        return True
Beispiel #8
0
    def getServiceStatus(ctx, serviceID, sessionToken):
        """Status-query method which is called regularly by WFM.

        Here, a more realistic service would query the status of a calculation
        etc. and process its log files to create a status page. Here, the log
        contains only a single number, which we convert to an html progress
        bar.
        """
        logging.info(
            "getServiceStatus() called with service ID {}".format(serviceID))

        # We obtain the authentication-manager endpoint from a class property
        # and check that the session token is valid
        auth = AuthClient(ctx.descriptor.service_class.auth_wsdl)
        if not auth.validate_session_token(sessionToken):
            logging.error("Token validation failed")
            error_msg = "Session-token validation failed"
            raise TokenValidationFailedFault(faultstring=error_msg)

        # Create correct file paths from service ID. By using the unique
        # service ID, we can address the right waiter process in case this
        # service is called several times in parallel.
        waiterdir = os.path.join(WAITER_LOG_FOLDER, serviceID)
        statusfile = os.path.join(waiterdir, 'status.txt')
        resultfile = os.path.join(waiterdir, 'result.txt')

        # Read the current status from the waiter logs. Here, that is only a
        # single number between 0 and 100.
        with open(statusfile) as f:
            current_status = f.read().strip()

        if current_status == "100":
            logging.info("Waiting completed")
            status = "COMPLETED"
            # Read result page from waiter
            with open(resultfile) as f:
                result = f.read()
            return (status, result)

        # Note that the interface definition of getServiceStatus() specifies
        # "UNCHANGED" as another option for the return value of
        # 'status_base64'. In this case, the workflow manager will simply
        # continue to display the last status page transmitted. This can be
        # used when the status-page generation in itself is costly.

        # If not finished, create a status page from the current status
        # This could include more post-processing etc. in a more realistic
        # service
        result = "UNSET"
        status = base64.b64encode(
            create_html_progressbar(int(current_status)).encode()).decode()
        return (status, result)
Beispiel #9
0
    def parameterDebugger(serviceID,
                          sessionToken,
                          extraParameters,
                          in1="",
                          label1="in1",
                          in2="",
                          label2="in2",
                          in3="",
                          label3="in3",
                          in4="",
                          label4="in4",
                          in5="",
                          label5="in5"):
        """
        Starts the debugger application.
        """
        logging.info(
            "parameterDebugger() called with service ID {}".format(serviceID))

        # Validate token
        ep = ExtraParameters(extraParameters)
        auth = AuthClient(ep.get_auth_WSDL_URL())
        if not auth.validate_session_token(sessionToken):
            logging.error("Token validation failed")
            error_msg = "Session-token validation failed"
            raise TokenValidationFailedFault(faultstring=error_msg)

        # Create application HTML
        html = HTML.format(
            sid=serviceID,
            stk=sessionToken,
            wfm_endpoint=ep.get_WFM_endpoint(),
            eP=extraParameters,
            in1=in1,
            in2=in2,
            in3=in3,
            in4=in4,
            in5=in5,
            label1=label1,
            label2=label2,
            label3=label3,
            label4=label4,
            label5=label5,
            result=RES_B64,
        )

        status = base64.b64encode(html.encode()).decode()

        return status
    def hpcPrepWithFile(sessionToken, extraParameters, filepath, textinput):
        """Creates parameters required as input by the HPC launcher.
        """
        # Validate session token
        ep = ExtraParameters(extraParameters)
        auth = AuthClient(ep.get_auth_WSDL_URL())
        if not auth.validate_session_token(sessionToken):
            logging.error("Token validation failed")
            error_msg = "Session-token validation failed"
            raise TokenValidationFailedFault(faultstring=error_msg)

        # Prepare parameters the HPC launcher needs
        commandline = "python"
        parameters = "/app/startup.py {} {}".format(filepath, textinput)
        queue = "qexp"
        numNodes = os.environ["N_NODES"]
        numCores = os.environ["N_CORES"]

        return (commandline, parameters, queue, numNodes, numCores)
Beispiel #11
0
    def abortService(ctx, serviceID, sessionToken):
        """Aborts the currently running service (not implemented, returns false)
        """
        logging.info(
            "abortService() called with service ID {}".format(serviceID))

        # We obtain the authentication-manager endpoint from a class property
        # and check that the session token is valid
        auth = AuthClient(ctx.descriptor.service_class.auth_wsdl)
        if not auth.validate_session_token(sessionToken):
            error_msg = "Session-token validation failed"
            raise TokenValidationFailedFault(faultstring=error_msg)

        # This method offers the option to abort long-running asynchronous
        # services. In this example, we do not implement this functionality
        # and thus always return False.
        # In a more realistic scenario, this method would terminate the
        # background computation process gracefully.

        return False
Beispiel #12
0
def main():
    try:
        port = int(sys.argv[1])
        print(f"Using port {port}")
    except:
        port = 821
        print(f"Couldn't get port from commandline argument, using {port}.")

    try:
        context_root = os.environ["CONTEXT_ROOT"]
    except KeyError:
        print("Error: environment variable CONTEXT_ROOT not set.")
        exit(1)

    # host_adress = 'kafka_consumer'
    host_adress = '193.175.65.88'
    url = f"http://{host_adress}:{port}{context_root}/KafkaConsumerService?wsdl"
    print(f"wsdl URL is {url}")

    if len(sys.argv) != 2:
        print("Expected [start|status] as argument.")
        exit(1)

    print("Obtaining session token")
    user = input("Enter username: "******"Enter project: ")
    password = getpass.getpass(prompt="Enter password: ")
    auth = AuthClient(auth_endpoint)
    token = auth.get_session_token(user, project, password)

    if sys.argv[1] == 'start':
        start(url, token)
    elif sys.argv[1] == 'status':
        status(url, token)
    else:
        print('Unknown argument.')
Beispiel #13
0
from clfpy import HpcImagesClient
from clfpy import GssClient
from clfpy import AuthClient

auth = AuthClient("https://api.hetcomp.org/authManager/AuthManager?wsdl")
user = "******"
project = "???"
password = "******"

print("Authenticating ...")
tk = auth.get_session_token(user, project, password)

print("Uploading image ...")
gss = GssClient("https://api.hetcomp.org/gss-0.1/FileUtilities?wsdl")
gss_ID = "it4i_anselm://home/abortable_waiter.simg"
# Change to gss.upload for the first upload
gss.update(gss_ID, tk, "abortable_waiter.simg")

print("Registering image ...")
images = HpcImagesClient("https://api.hetcomp.org/hpc-4-anselm/Images?wsdl")
# Change to images.upload_image for the first upload
images.update_image(tk, "waiter_abortable.simg", gss_ID)

print("Querying image information ...")
print(images.get_image_info(tk, "waiter_abortable.simg"))
Beispiel #14
0
    def startWaiter(ctx, serviceID, sessionToken, extraParameters,
                    secondsToWait):
        """Starts a waiter script as a separate process and returns immediately.

        In a more realistic scenario, this is where a longer computation etc.
        would be started as a separate process. Here, we simply start a process
        which waits for a while while regularly updating a status file.
        """
        logging.info(
            "startWaiter() called with service ID {}".format(serviceID))

        # Check that the session token is valid and abort with a SOAP fault if
        # it's not. To that end, we use the clfpy library both to extract the
        # authentication endpoint from the extraParameters input argument and
        # to communicate with that endpoint. We also save the authentication-
        # manager endpoint in a class property which we can re-use in methods
        # that don't have the extraParameters as an argument.
        ep = ExtraParameters(extraParameters)
        auth = AuthClient(ep.get_auth_WSDL_URL())
        if not auth.validate_session_token(sessionToken):
            logging.error("Token validation failed")
            error_msg = "Session-token validation failed"
            raise TokenValidationFailedFault(faultstring=error_msg)

        # Add default value for waiting time
        if secondsToWait is None:
            logging.info("Setting default value for waiting time")
            secondsToWait = 60

        # Create a temporary folder to store the status files in.
        # Note that we use the service ID as a unique identifier. Since this
        # service is stateless, subsequent calls to getServiceStatus() need to
        # be able to read the correct status files. (The service can be started
        # several times in parallel.)
        # In a more realistic setting, one would set up log directories for a
        # computation here.
        waiterdir = os.path.join(WAITER_LOG_FOLDER, serviceID)
        if not os.path.exists(waiterdir):
            os.mkdir(waiterdir)
        statusfile = os.path.join(waiterdir, 'status.txt')
        resultfile = os.path.join(waiterdir, 'result.txt')

        # Store the auth-manager WSDL URL in a file for later use in
        # getServiceStatus()
        wsdlfile = os.path.join(waiterdir, 'wsdl.txt')
        with open(wsdlfile, 'w') as f:
            f.write(ep.get_auth_WSDL_URL())
        logging.info("Stored auth-manager WSDL URL: {}".format(
            ep.get_auth_WSDL_URL()))

        # Spawn new process running the waiter script.
        # We pass the status and result file to the script to ensure that the
        # waiter logs to the correct place.
        logging.info("Starting waiter script")
        command = [
            'python', 'wait_a_while.py',
            str(secondsToWait), statusfile, resultfile
        ]
        subprocess.Popen(command)

        # We now create a first status page to be displayed while the
        # workflow is executed. Since the waiter process was only just started,
        # we don't have a proper status yet. So we simply start with an empty
        # progress bar.
        # The status page needs to be base64 encoded.
        status = base64.b64encode(create_html_progressbar(0).encode()).decode()
        result = "UNSET"

        return (status, result)
Beispiel #15
0
def main():
    """Makes a series of test calls and prints their outputs."""

    try:
        host_address_service = int(sys.argv[1])
        print(f"Using host address {host_address_service}")
    except:
        host_address_service = "localhost"
        print(
            "Couldn't get host address of the consumer service from commandline argument, using localhost."
        )

    try:
        port_service = int(sys.argv[2])
        print(f"Using port {port_service}")
    except:
        port_service = 821
        print(
            f"Couldn't get port of the consumer service from commandline argument, using {port_service}."
        )

    try:
        serviceid = int(sys.argv[3])
        print(f"Using serviceid {serviceid}")
    except:
        serviceid = "testid_" + str(int(time.time())) + "-" + str(
            random.randint(0, 10000))
        print(
            f"Couldn't get serviceid from commandline argument, using {serviceid}."
        )

    try:
        host_address = int(sys.argv[4])
        print(f"Using host address {host_address}")
    except:
        host_address = "92.78.102.187"
        print(
            f"Couldn't get kafka broker host address from commandline argument, using default: {host_address}"
        )

    try:
        port = int(sys.argv[5])
        print(f"Using port {port}")
    except:
        port = 59092
        print(
            f"Couldn't get port from commandline argument, using default: {port}."
        )

    try:
        timeout = int(sys.argv[6])
        print(f"Using timeout {timeout}")
    except:
        timeout = 5
        print(
            f"Couldn't get timeout from commandline argument, using {timeout}s."
        )

    try:
        topic = int(sys.argv[7])
        print(f"Using topic {topic}")
    except:
        topic = "testtopic_" + str(random.randint(0, 10000))
        print(f"Couldn't get topic from commandline argument, using {topic}.")

    try:
        context_root = os.environ["CONTEXT_ROOT"]
    except KeyError:
        context_root = '/demo-kafka-consumer'
        print(
            f"Error: environment variable CONTEXT_ROOT not set, using default: {context_root}."
        )

    print("Obtaining session token")
    user = input("Enter username: "******"Enter project: ")
    password = getpass.getpass(prompt="Enter password: "******"http://{host_address_service}:{port_service}{context_root}/KafkaConsumerService?wsdl"
    print(f"Service URL is {url}")

    print("Testing start of consumer:")
    response = soap_call(
        url, "startConsumer",
        [id, token, extra_pars, host_address, port, topic,
         int(timeout + 5)])
    print(f"Start result = {response}")

    print(
        f"Waiting {timeout} seconds until update is retrieved and consumer is stopped"
    )
    time.sleep(timeout)
    response2 = soap_call(url, "getServiceStatus", [id, token])
    print(f"status = {response2}")

    response3 = soap_call(url, "abortService", [id, token])
    print(f"Consumer stop successful: {response3}")

    print(f"Test finished")