Skip to content

Commit

Permalink
Working draft, minimal styling
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobsonMT committed Sep 25, 2018
1 parent a44c127 commit 4c6f923
Show file tree
Hide file tree
Showing 26 changed files with 1,327 additions and 9 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/.nb-gradle/

/application.properties

5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

<build>
Expand Down
123 changes: 123 additions & 0 deletions src/main/java/com/jacobsonmt/idrbind/controllers/JobController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.jacobsonmt.idrbind.controllers;

import com.jacobsonmt.idrbind.model.IDRBindJob;
import com.jacobsonmt.idrbind.model.IDRBindJobResult;
import com.jacobsonmt.idrbind.services.JobManager;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Log4j2
@Controller
public class JobController {

@Autowired
private JobManager jobManager;



@PostMapping("/")
public String handleFileUpload(@RequestParam("pdbFile") MultipartFile pdbFile,
@RequestParam("sequence") MultipartFile sequence,
@RequestParam("label") String label,
@RequestParam(value = "email", required = false, defaultValue = "") String email,
@RequestParam(value = "hidden", required = false, defaultValue = "false") boolean hidden,
HttpServletRequest request,
RedirectAttributes redirectAttributes) throws IOException {

String ipAddress = request.getHeader( "X-FORWARDED-FOR" );
if ( ipAddress == null ) {
ipAddress = request.getRemoteAddr();
}

IDRBindJob job = jobManager.createJob( ipAddress,
label,
IDRBindJob.inputStreamToString( pdbFile.getInputStream() ),
IDRBindJob.inputStreamToString( sequence.getInputStream() ),
email,
hidden );
jobManager.submit( job );

redirectAttributes.addFlashAttribute("message",
"Job Submitted! View job <a href='job/" + job.getJobId() + "' target='_blank'>here</a>.");

return "redirect:/";
}

@GetMapping("/job/{jobId}")
public String job( @PathVariable("jobId") String jobId,
Model model) throws IOException {

IDRBindJob job = jobManager.getSavedJob( jobId );

if (job==null) {
return "/";
}

model.addAttribute("job", jobManager.getSavedJob( jobId ).toValueObject( true ) );

return "job";
}

@GetMapping("/job/{jobId}/resultPDB")
public ResponseEntity<String> jobResultPDB( @PathVariable("jobId") String jobId) {
IDRBindJob job = jobManager.getSavedJob( jobId );

// test for not null and complete
if ( job != null && job.isComplete() && !job.isFailed() ) {
try {
IDRBindJobResult result = job.getFuture().get( 1, TimeUnit.SECONDS );

return ResponseEntity.ok()
.contentType( MediaType.parseMediaType("application/octet-stream"))
.header( HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + job.getLabel() + "-result.pdb\"")
.body(result.getResultPDB());

} catch ( InterruptedException | ExecutionException | TimeoutException e ) {
log.warn( e );
ResponseEntity.status( 500 ).body( "" );
}
}
return ResponseEntity.badRequest().body( "" );
}

@GetMapping("/job/{jobId}/resultCSV")
public ResponseEntity<String> jobResultCSV( @PathVariable("jobId") String jobId) {
IDRBindJob job = jobManager.getSavedJob( jobId );

// test for not null and complete
if ( job != null && job.isComplete() && !job.isFailed() ) {
try {
IDRBindJobResult result = job.getFuture().get( 1, TimeUnit.SECONDS );

return ResponseEntity.ok()
.contentType( MediaType.parseMediaType("application/octet-stream"))
.header( HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + job.getLabel() + "-result.csv\"")
.body(result.getResultCSV());

} catch ( InterruptedException | ExecutionException | TimeoutException e ) {
log.warn( e );
ResponseEntity.status( 500 ).body( "" );
}
}
return ResponseEntity.badRequest().body( "" );
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.jacobsonmt.idrbind.controllers;

import com.jacobsonmt.idrbind.services.JobManager;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.io.IOException;

@Log4j2
@Controller
public class MainController {

@Autowired
private JobManager jobManager;

@GetMapping("/")
public String index( Model model) throws IOException {

return "index";
}

@GetMapping("/queue")
public String queue( Model model) throws IOException {

model.addAttribute("jobs", jobManager.listPublicJobs() );

return "queue";
}

@GetMapping("/documentation")
public String documentation( Model model) throws IOException {
return "documentation";
}

@GetMapping("/faq")
public String faq( Model model) throws IOException {
return "faq";
}

@GetMapping("/contact")
public String contact( Model model) throws IOException {
return "contact";
}
}
194 changes: 194 additions & 0 deletions src/main/java/com/jacobsonmt/idrbind/model/IDRBindJob.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
package com.jacobsonmt.idrbind.model;

import com.jacobsonmt.idrbind.services.JobManager;
import lombok.*;
import lombok.extern.log4j.Log4j2;
import org.springframework.util.StopWatch;

import javax.ws.rs.core.StreamingOutput;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.concurrent.*;

@Log4j2
@Getter
@Setter
@Builder
@ToString(of = {"jobId", "userId", "label", "hidden"})
@EqualsAndHashCode(of = {"jobId"})
public class IDRBindJob implements Callable<IDRBindJobResult> {

// Path to resources
private String command;
private String commandWorkingDirectory;
private String inputPDBFullPath;
private String inputProteinChainFullPath;
private String outputScoredPDBFullPath;
private String outputCSVFullPath;


// Information on creation of job
private String userId;
private String jobId;
private String label;
private String inputPDBContent;
private String inputProteinChainIds;
@Builder.Default private boolean hidden = true;
private Date submittedDate;
private String email;

// Information on running / completion
@Builder.Default private boolean running = false;
@Builder.Default private boolean failed = false;
@Builder.Default private boolean complete = false;
private Integer position;
private String status;

// Results
private Future<IDRBindJobResult> future;
private StreamingOutput resultFile;
private long executionTime;

// Saving Job information / results for later
@Builder.Default private boolean saved = false;
private Long saveExpiredDate;

// Back-reference to owning JobManager
private JobManager jobManager;

@Override
public IDRBindJobResult call() throws Exception {

try {

log.info( "Starting job (" + label + ") for user: (" + userId + ")" );

this.running = true;
this.status = "Processing";

jobManager.onJobStart( this );

// Write content to input
File pdbFile = new File( inputPDBFullPath );
writeToFile( pdbFile, inputPDBContent );

File chainFile = new File( inputProteinChainFullPath );
writeToFile( chainFile, inputProteinChainIds );

// Execute script
StopWatch sw = new StopWatch();
sw.start();
executeCommand( "./" + command, commandWorkingDirectory );
sw.stop();
this.executionTime = sw.getTotalTimeMillis() / 1000;

// Get output
String resultPDB = inputStreamToString( new FileInputStream( outputScoredPDBFullPath ) );
String resultCSV = inputStreamToString( new FileInputStream( outputCSVFullPath ) );

log.info( "Finished job (" + label + ") for user: (" + userId + ")" );
this.running = false;
this.complete = true;

jobManager.onJobComplete( this );
jobManager = null;

return new IDRBindJobResult( resultPDB, resultCSV );
} catch ( Exception e ) {
log.error( e );
this.complete = true;
this.running = false;
this.failed = true;
jobManager = null;
this.status = "Failed";
return new IDRBindJobResult( "", "" );
}

}

private static void writeToFile(File file, String fileContents) throws IOException {

try (FileOutputStream fop = new FileOutputStream( file )) {

// if file doesn't exists, then create it
if (!file.exists()) {
file.createNewFile();
}

BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fop));
writer.write(fileContents);
writer.newLine();
writer.flush();
writer.close();

}

}

private static String executeCommand( String command, String path ) {

StringBuffer output = new StringBuffer();

Process p;
try {
p = Runtime.getRuntime().exec( command, null, new File( path ) );
p.waitFor();
BufferedReader reader = new BufferedReader( new InputStreamReader( p.getInputStream() ) );

String line = "";
while ( ( line = reader.readLine() ) != null ) {
output.append( line + "\r\n" );
}

} catch ( Exception e ) {
e.printStackTrace();
}

return output.toString();
}

public static String inputStreamToString(InputStream inputStream) throws IOException {
StringBuilder textBuilder = new StringBuilder();
try (Reader reader = new BufferedReader(new InputStreamReader
(inputStream, Charset.forName(StandardCharsets.UTF_8.name())))) {
int c = 0;
while ((c = reader.read()) != -1) {
textBuilder.append((char) c);
}
}
return textBuilder.toString();
}

@Getter
@AllArgsConstructor
public static final class IDRBindJobVO {
private final String jobId;
private final String label;
private final String status;
private final boolean running;
private final boolean failed;
private final boolean complete;
private Integer position;
private final String email;
private final boolean hidden;
private final Date submitted;
private final IDRBindJobResult result;
}

public IDRBindJobVO toValueObject(boolean obfuscateEmail) {

IDRBindJobResult result = null;
if ( this.isComplete() ) {
try {
result = this.getFuture().get( 1, TimeUnit.SECONDS );
} catch ( InterruptedException | ExecutionException | TimeoutException e ) {
log.error( e );
}
}

return new IDRBindJobVO( jobId, label, status, running, failed, complete, position, obfuscateEmail ? email.replaceAll("(\\w{0,3})(\\w+.*)(@.*)", "$1****$3") : email, hidden, submittedDate, result );
}

}
Loading

0 comments on commit 4c6f923

Please sign in to comment.