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 { Injectable } from "@angular/core";
import {HttpClient} from "@angular/common/http"; import { HttpClient } from "@angular/common/http";
import {environment} from "../../../environments/environment"; import { environment } from "../../../environments/environment";
import {Observable} from "rxjs"; import { Observable } from "rxjs";
import {CapabilityRequest} from "../model/capability-request"; import { CapabilityRequest } from "../model/capability-request";
import {CapabilityExecution} from "../model/capability-execution"; import { CapabilityExecution } from "../model/capability-execution";
@Injectable({ @Injectable({
providedIn: "root", providedIn: "root",
...@@ -16,15 +16,18 @@ export class CapabilityLauncherService { ...@@ -16,15 +16,18 @@ export class CapabilityLauncherService {
/** /**
* Create capability request and send it to capability service * Create capability request and send it to capability service
* @param: capabilityName Name of capability to create request for * @param: capabilityName Name of capability to create request for
* @param: args Arguments for capability execution * @param: parameters Parameters for capability request
*/ */
createRequest( createRequest(
capabilityName: string, capabilityName: string,
args: string parameters: string
): Observable<CapabilityRequest> { ): Observable<CapabilityRequest> {
const url = environment.workspacesUrl + this.endpoint; const url = environment.workspacesUrl + this.endpoint;
const params = JSON.stringify({ capability: capabilityName, args: args }); const requestParams = JSON.stringify({
return this.httpClient.post<CapabilityRequest>(url, params); capability: capabilityName,
args: parameters,
});
return this.httpClient.post<CapabilityRequest>(url, requestParams);
} }
/** /**
......
<div class="container-fluid"> <div class="container-fluid">
<div class="row py-2"> <div class="row py-2">
<div class="col"> <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> </div>
</div> </div>
......
...@@ -19,33 +19,47 @@ export class WorkspacesComponent implements OnInit { ...@@ -19,33 +19,47 @@ export class WorkspacesComponent implements OnInit {
/** /**
* OnClick method that creates a capability request for the null capability and submits it * 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 { 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 // Create capability request
this.capabilityLauncher this.capabilityLauncher.createRequest(capabilityName, parameters).subscribe(
.createRequest( (requestResponse) => {
"test_download", this.capabilityRequests.push(requestResponse);
"shared/workspaces/test/test_data/spool/724126739/17A-109.sb33151331.eb33786546.57892.65940042824" if (requestResponse.id) {
) // Capability request created; ID found
.subscribe( const requestId = requestResponse.id;
(requestResponse) => { // Submit capability request
this.capabilityRequests.push(requestResponse); this.capabilityLauncher.submit(requestId).subscribe(
if (requestResponse.id) { (submitResponse) => {
// Capability request created; ID found this.capabilityExecutions.push(submitResponse);
const requestId = requestResponse.id; },
// Submit capability request (error) => {
this.capabilityLauncher.submit(requestId).subscribe( console.log(error);
(submitResponse) => { }
this.capabilityExecutions.push(submitResponse); );
},
(error) => {
console.log(error);
}
);
}
},
(error) => {
console.log(error);
} }
); },
(error) => {
console.log(error);
}
);
} }
} }
...@@ -114,9 +114,7 @@ class WorkflowRequestRestService: ...@@ -114,9 +114,7 @@ class WorkflowRequestRestService:
""" """
print(f"Submitting workflow {self.request.context}") print(f"Submitting workflow {self.request.context}")
return self.request.workflows.execute( return self.request.workflows.execute(self.request.context, self.request.json_body["files"])
self.request.context, self.request.json_body["files"]
)
@view_defaults(route_name="workflow_request_files", renderer="json") @view_defaults(route_name="workflow_request_files", renderer="json")
...@@ -135,9 +133,7 @@ class WorkflowFilesRestService: ...@@ -135,9 +133,7 @@ class WorkflowFilesRestService:
Audience: front-end and CLI Audience: front-end and CLI
""" """
print( print(f"Adding file {self.request.matchdict['filename']} to {self.request.context}")
f"Adding file {self.request.matchdict['filename']} to {self.request.context}"
)
file = self.request.info.save_file( file = self.request.info.save_file(
request=self.request.context, request=self.request.context,
filename=self.request.matchdict["filename"], filename=self.request.matchdict["filename"],
...@@ -237,9 +233,7 @@ def main(global_config, **settings): ...@@ -237,9 +233,7 @@ def main(global_config, **settings):
reify=True, reify=True,
) )
# make workflow_service available for use in Pyramid # make workflow_service available for use in Pyramid
config.add_request_method( config.add_request_method(lambda r: WorkflowService(r.info), "workflows", reify=True)
lambda r: WorkflowService(r.info), "workflows", reify=True
)
# GET /workflows <- list of workflows # GET /workflows <- list of workflows
# GET /workflows/null <- info about the null workflow # GET /workflows/null <- info about the null workflow
......
...@@ -4,7 +4,7 @@ import subprocess ...@@ -4,7 +4,7 @@ import subprocess
import threading import threading
from pathlib import Path from pathlib import Path
from tempfile import mkdtemp from tempfile import mkdtemp
from typing import List, Union, Dict from typing import Dict, List, Union
import requests import requests
from channels.amqp_helpers import Channel, WorkflowEventChannel from channels.amqp_helpers import Channel, WorkflowEventChannel
...@@ -17,36 +17,36 @@ from workspaces.workflow.schema import ( ...@@ -17,36 +17,36 @@ from workspaces.workflow.schema import (
WorkflowRequest, WorkflowRequest,
WorkflowRequestFile, 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 from workspaces.workflow.services.interfaces import WorkflowInfoIF, WorkflowServiceIF
class WorkflowServiceRESTClient(WorkflowServiceIF): class WorkflowServiceRESTClient(WorkflowServiceIF):
def __init__(self): def __init__(self):
self.url = ( self.url = CapoConfig().settings("edu.nrao.archive.workspaces.WorkflowSettings").serviceUrl
CapoConfig()
.settings("edu.nrao.archive.workspaces.WorkflowSettings")
.serviceUrl
)
def execute(self, request: WorkflowRequestIF, files: List[AbstractFile]): def execute(self, request: WorkflowRequestIF, files: List[AbstractFile]):
# step 1: if necessary, pass the files up for this request # step 1: if necessary, pass the files up for this request
for file in files: for file in files:
requests.post( requests.post(
f"{self.url}/workflows/requests/{request['workflow_request_id']}/files/{file.filename}", f"{self.url}/workflows/requests/{request['workflow_request_id']}/files/{file.filename}",
body=file.content, {"files": file.content},
) )
# step 2: execute the request # step 2: execute the request
requests.post( 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: def create_workflow_request(
return requests.post( self, workflow: Union[str, WorkflowIF], argument: Dict
f"{self.url}/workflows/{workflow}/requests/create?args={argument}" ) -> WorkflowRequestIF:
return requests.post(
f"{self.url}/workflows/requests/create", json={"workflow": workflow, "args": argument}
).json() ).json()
class WorkflowService(WorkflowServiceIF): class WorkflowService(WorkflowServiceIF):
""" """
Executes workflows; should be a freestanding service. Executes workflows; should be a freestanding service.
...@@ -81,16 +81,12 @@ class WorkflowService(WorkflowServiceIF): ...@@ -81,16 +81,12 @@ class WorkflowService(WorkflowServiceIF):
# 2. render templates to files, returns list of rendered files # 2. render templates to files, returns list of rendered files
workflow_files = definition.render_templates(request.argument, files) workflow_files = definition.render_templates(request.argument, files)
for file in workflow_files: for file in workflow_files:
self.info.save_file( self.info.save_file(request=request, filename=file.filename, content=file.content)
request=request, filename=file.filename, content=file.content
)
# 4. prepare files for condor execution # 4. prepare files for condor execution
if not request.results_dir: if not request.results_dir:
# Create temp results directory if the request doesn't already have one (from a previous execution attempt) # Create temp results directory if the request doesn't already have one (from a previous execution attempt)
request.results_dir = str( request.results_dir = str(self._prepare_files_for_condor(workflow_files).absolute())
self._prepare_files_for_condor(workflow_files).absolute()
)
self.info.save_request(request) self.info.save_request(request)
# 5. execute condor and retrieve log file # 5. execute condor and retrieve log file
...@@ -157,9 +153,7 @@ class WorkflowService(WorkflowServiceIF): ...@@ -157,9 +153,7 @@ class WorkflowService(WorkflowServiceIF):
# vulture is a workaround for testing locally without submitting to condor # vulture is a workaround for testing locally without submitting to condor
print("submitting to vulture...") print("submitting to vulture...")
subprocess.run( subprocess.run(["vulture", "job", "execute", str(condor)], cwd=str(folder.absolute()))
["vulture", "job", "execute", str(condor)], cwd=str(folder.absolute())
)
# return the logfile # return the logfile
return logfile return logfile
...@@ -179,7 +173,5 @@ class WorkflowService(WorkflowServiceIF): ...@@ -179,7 +173,5 @@ class WorkflowService(WorkflowServiceIF):
else: else:
status = WorkflowRequestState.Running.name status = WorkflowRequestState.Running.name
print( print(f"Updating state on workflow request {request.workflow_request_id} to {status}...")
f"Updating state on workflow request {request.workflow_request_id} to {status}..."
)
request.update_status(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