Skip to content
Snippets Groups Projects
Commit fa7e5b6e authored by Nathan Hertz's avatar Nathan Hertz
Browse files

Created two buttons; one that launches the null capability, one that

launches the download capability; moved the capability launching
functionality from the on-click methods to a new method that gets called
by the on click methods
parent 411ff473
No related branches found
No related tags found
1 merge request!70Turned T H E B U T T O N into two buttons
Pipeline #482 passed
import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {environment} from "../../../environments/environment";
import {Observable} from "rxjs";
import {CapabilityRequest} from "../model/capability-request";
import {CapabilityExecution} from "../model/capability-execution";
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { environment } from "../../../environments/environment";
import { Observable } from "rxjs";
import { CapabilityRequest } from "../model/capability-request";
import { CapabilityExecution } from "../model/capability-execution";
@Injectable({
providedIn: "root",
......@@ -16,15 +16,18 @@ export class CapabilityLauncherService {
/**
* Create capability request and send it to capability service
* @param: capabilityName Name of capability to create request for
* @param: args Arguments for capability execution
* @param: parameters Parameters for capability request
*/
createRequest(
capabilityName: string,
args: string
parameters: string
): Observable<CapabilityRequest> {
const url = environment.workspacesUrl + this.endpoint;
const params = JSON.stringify({ capability: capabilityName, args: args });
return this.httpClient.post<CapabilityRequest>(url, params);
const requestParams = JSON.stringify({
capability: capabilityName,
args: parameters,
});
return this.httpClient.post<CapabilityRequest>(url, requestParams);
}
/**
......
<div class="container-fluid">
<div class="row py-2">
<div class="col">
<button type="button" class="btn btn-primary" (click)="downloadButtonOnClick()">Launch null capability [null -g]</button>
<button type="button" class="btn btn-secondary" (click)="nullButtonOnClick()">Launch null capability</button>
</div>
</div>
<div class="row py-2">
<div class="col">
<button type="button" class="btn btn-warning" (click)="downloadButtonOnClick()">Launch download capability</button>
</div>
</div>
</div>
......
......@@ -19,33 +19,47 @@ export class WorkspacesComponent implements OnInit {
/**
* OnClick method that creates a capability request for the null capability and submits it
*/
nullButtonOnClick(): void {
this.launchCapability("null", "-g");
}
/**
* OnClick method that creates a capability request for the test_download capability and submits it
*/
downloadButtonOnClick(): void {
this.launchCapability(
"test_download",
"shared/workspaces/test/test_data/spool/724126739/17A-109.sb33151331.eb33786546.57892.65940042824"
);
}
/**
* Method that uses the capabilityLauncher service to launch a capability
* @param capabilityName Name of capability
* @param parameters Parameters of capability request
*/
launchCapability(capabilityName: string, parameters: string): void {
// Create capability request
this.capabilityLauncher
.createRequest(
"test_download",
"shared/workspaces/test/test_data/spool/724126739/17A-109.sb33151331.eb33786546.57892.65940042824"
)
.subscribe(
(requestResponse) => {
this.capabilityRequests.push(requestResponse);
if (requestResponse.id) {
// Capability request created; ID found
const requestId = requestResponse.id;
// Submit capability request
this.capabilityLauncher.submit(requestId).subscribe(
(submitResponse) => {
this.capabilityExecutions.push(submitResponse);
},
(error) => {
console.log(error);
}
);
}
},
(error) => {
console.log(error);
this.capabilityLauncher.createRequest(capabilityName, parameters).subscribe(
(requestResponse) => {
this.capabilityRequests.push(requestResponse);
if (requestResponse.id) {
// Capability request created; ID found
const requestId = requestResponse.id;
// Submit capability request
this.capabilityLauncher.submit(requestId).subscribe(
(submitResponse) => {
this.capabilityExecutions.push(submitResponse);
},
(error) => {
console.log(error);
}
);
}
);
},
(error) => {
console.log(error);
}
);
}
}
......@@ -114,9 +114,7 @@ class WorkflowRequestRestService:
"""
print(f"Submitting workflow {self.request.context}")
return self.request.workflows.execute(
self.request.context, self.request.json_body["files"]
)
return self.request.workflows.execute(self.request.context, self.request.json_body["files"])
@view_defaults(route_name="workflow_request_files", renderer="json")
......@@ -135,9 +133,7 @@ class WorkflowFilesRestService:
Audience: front-end and CLI
"""
print(
f"Adding file {self.request.matchdict['filename']} to {self.request.context}"
)
print(f"Adding file {self.request.matchdict['filename']} to {self.request.context}")
file = self.request.info.save_file(
request=self.request.context,
filename=self.request.matchdict["filename"],
......@@ -237,9 +233,7 @@ def main(global_config, **settings):
reify=True,
)
# make workflow_service available for use in Pyramid
config.add_request_method(
lambda r: WorkflowService(r.info), "workflows", reify=True
)
config.add_request_method(lambda r: WorkflowService(r.info), "workflows", reify=True)
# GET /workflows <- list of workflows
# GET /workflows/null <- info about the null workflow
......
......@@ -4,7 +4,7 @@ import subprocess
import threading
from pathlib import Path
from tempfile import mkdtemp
from typing import List, Union, Dict
from typing import Dict, List, Union
import requests
from channels.amqp_helpers import Channel, WorkflowEventChannel
......@@ -17,36 +17,36 @@ from workspaces.workflow.schema import (
WorkflowRequest,
WorkflowRequestFile,
)
from workspaces.workflow.schema_interfaces import WorkflowRequestIF, WorkflowIF
from workspaces.workflow.schema_interfaces import WorkflowIF, WorkflowRequestIF
from workspaces.workflow.services.interfaces import WorkflowInfoIF, WorkflowServiceIF
class WorkflowServiceRESTClient(WorkflowServiceIF):
def __init__(self):
self.url = (
CapoConfig()
.settings("edu.nrao.archive.workspaces.WorkflowSettings")
.serviceUrl
)
self.url = CapoConfig().settings("edu.nrao.archive.workspaces.WorkflowSettings").serviceUrl
def execute(self, request: WorkflowRequestIF, files: List[AbstractFile]):
# step 1: if necessary, pass the files up for this request
for file in files:
requests.post(
f"{self.url}/workflows/requests/{request['workflow_request_id']}/files/{file.filename}",
body=file.content,
{"files": file.content},
)
# step 2: execute the request
requests.post(
f"{self.url}/workflows/requests/{request['workflow_request_id']}/submit"
)
f"{self.url}/workflows/requests/{request['workflow_request_id']}/submit",
json={"files": files},
).json()
def create_workflow_request(self, workflow: Union[str, WorkflowIF], argument: Dict) -> WorkflowRequestIF:
return requests.post(
f"{self.url}/workflows/{workflow}/requests/create?args={argument}"
def create_workflow_request(
self, workflow: Union[str, WorkflowIF], argument: Dict
) -> WorkflowRequestIF:
return requests.post(
f"{self.url}/workflows/requests/create", json={"workflow": workflow, "args": argument}
).json()
class WorkflowService(WorkflowServiceIF):
"""
Executes workflows; should be a freestanding service.
......@@ -81,16 +81,12 @@ class WorkflowService(WorkflowServiceIF):
# 2. render templates to files, returns list of rendered files
workflow_files = definition.render_templates(request.argument, files)
for file in workflow_files:
self.info.save_file(
request=request, filename=file.filename, content=file.content
)
self.info.save_file(request=request, filename=file.filename, content=file.content)
# 4. prepare files for condor execution
if not request.results_dir:
# Create temp results directory if the request doesn't already have one (from a previous execution attempt)
request.results_dir = str(
self._prepare_files_for_condor(workflow_files).absolute()
)
request.results_dir = str(self._prepare_files_for_condor(workflow_files).absolute())
self.info.save_request(request)
# 5. execute condor and retrieve log file
......@@ -157,9 +153,7 @@ class WorkflowService(WorkflowServiceIF):
# vulture is a workaround for testing locally without submitting to condor
print("submitting to vulture...")
subprocess.run(
["vulture", "job", "execute", str(condor)], cwd=str(folder.absolute())
)
subprocess.run(["vulture", "job", "execute", str(condor)], cwd=str(folder.absolute()))
# return the logfile
return logfile
......@@ -179,7 +173,5 @@ class WorkflowService(WorkflowServiceIF):
else:
status = WorkflowRequestState.Running.name
print(
f"Updating state on workflow request {request.workflow_request_id} to {status}..."
)
print(f"Updating state on workflow request {request.workflow_request_id} to {status}...")
request.update_status(status)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment