From fd74b669c0e9475d18b09c3eab6a53a0dc47e0e1 Mon Sep 17 00:00:00 2001 From: Pan Li Date: Tue, 11 Sep 2018 14:42:59 +0800 Subject: [PATCH] Integration front end code (#142) * Integration code with front end, #130. * Apply OAuth2 token for push to github. Signed-off-by: Pan Li --- .../controller/MainController.java | 34 +++++++++++++-- .../exception/GithubFileException.java | 12 ++++++ .../exception/GithubProcessException.java | 2 +- .../github/GithubApiWrapper.java | 29 ++++++++----- .../github/GithubOperator.java | 43 ++++++++++--------- src/main/resources/static/js/start.js | 4 +- 6 files changed, 86 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/microsoft/azure/springcloudplayground/exception/GithubFileException.java diff --git a/src/main/java/com/microsoft/azure/springcloudplayground/controller/MainController.java b/src/main/java/com/microsoft/azure/springcloudplayground/controller/MainController.java index 63d9e36..3223cb2 100644 --- a/src/main/java/com/microsoft/azure/springcloudplayground/controller/MainController.java +++ b/src/main/java/com/microsoft/azure/springcloudplayground/controller/MainController.java @@ -1,8 +1,10 @@ package com.microsoft.azure.springcloudplayground.controller; +import com.microsoft.azure.springcloudplayground.exception.GithubProcessException; import com.microsoft.azure.springcloudplayground.generator.MicroService; import com.microsoft.azure.springcloudplayground.generator.ProjectGenerator; import com.microsoft.azure.springcloudplayground.generator.ProjectRequest; +import com.microsoft.azure.springcloudplayground.github.GithubOperator; import com.microsoft.azure.springcloudplayground.metadata.GeneratorMetadataProvider; import com.microsoft.azure.springcloudplayground.util.PropertyLoader; import com.microsoft.azure.springcloudplayground.util.TelemetryProxy; @@ -11,6 +13,7 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Zip; import org.apache.tools.ant.types.ZipFileSet; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.lang.NonNull; import org.springframework.security.core.Authentication; @@ -117,9 +120,19 @@ private void triggerLoginEvent(@NonNull String accountType) { this.telemetryProxy.trackEvent(TELEMETRY_EVENT_LOGIN, properties); } + private boolean isValidOAuth2Token(OAuth2AuthenticationToken token) { + if (token == null) { + return false; + } else if (StringUtils.isEmpty(token.getName())) { + return false; + } else { + return true; + } + } + @RequestMapping(path = "/", produces = "text/html") public String home(Map model, OAuth2AuthenticationToken token) { - if (token != null && !StringUtils.isEmpty(token.getName())) { + if (isValidOAuth2Token(token)) { model.put("loggedInUser", token.getPrincipal().getAttributes().get("login")); } @@ -130,11 +143,24 @@ public String home(Map model, OAuth2AuthenticationToken token) { return "home"; } - @PostMapping("/push-to-github") - public String pushToGithub(@RequestBody @Nonnull ProjectRequest request) { + public ResponseEntity pushToGithub(@RequestBody @Nonnull ProjectRequest request, OAuth2AuthenticationToken token) { log.info("Project request received: " + request); - return "push to github not implemented"; + + if (isValidOAuth2Token(token)) { + String username = token.getPrincipal().getAttributes().get("login").toString(); + GithubOperator operator = new GithubOperator(username, getAccessToken().getTokenValue()); + File dir = this.projectGenerator.generate(request); + + try { + operator.createRepository(dir, request.getRepoName()); + return new ResponseEntity(HttpStatus.CREATED); + } catch (GithubProcessException e) { + return new ResponseEntity(HttpStatus.NOT_ACCEPTABLE); + } + } + + return new ResponseEntity(HttpStatus.UNAUTHORIZED); } @ResponseBody diff --git a/src/main/java/com/microsoft/azure/springcloudplayground/exception/GithubFileException.java b/src/main/java/com/microsoft/azure/springcloudplayground/exception/GithubFileException.java new file mode 100644 index 0000000..c860eab --- /dev/null +++ b/src/main/java/com/microsoft/azure/springcloudplayground/exception/GithubFileException.java @@ -0,0 +1,12 @@ +package com.microsoft.azure.springcloudplayground.exception; + +public class GithubFileException extends RuntimeException { + + public GithubFileException(String message, Throwable cause) { + super(message, cause); + } + + public GithubFileException(String message) { + super(message); + } +} diff --git a/src/main/java/com/microsoft/azure/springcloudplayground/exception/GithubProcessException.java b/src/main/java/com/microsoft/azure/springcloudplayground/exception/GithubProcessException.java index 6506990..89199fd 100644 --- a/src/main/java/com/microsoft/azure/springcloudplayground/exception/GithubProcessException.java +++ b/src/main/java/com/microsoft/azure/springcloudplayground/exception/GithubProcessException.java @@ -1,7 +1,7 @@ package com.microsoft.azure.springcloudplayground.exception; -public class GithubProcessException extends RuntimeException { +public class GithubProcessException extends Exception { public GithubProcessException(String message, Throwable cause) { super(message, cause); diff --git a/src/main/java/com/microsoft/azure/springcloudplayground/github/GithubApiWrapper.java b/src/main/java/com/microsoft/azure/springcloudplayground/github/GithubApiWrapper.java index 3962f2b..dbdac00 100644 --- a/src/main/java/com/microsoft/azure/springcloudplayground/github/GithubApiWrapper.java +++ b/src/main/java/com/microsoft/azure/springcloudplayground/github/GithubApiWrapper.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.azure.springcloudplayground.exception.GithubFileException; import com.microsoft.azure.springcloudplayground.exception.GithubProcessException; import com.microsoft.azure.springcloudplayground.github.gitdata.GitDataRequestBlob; import com.microsoft.azure.springcloudplayground.github.gitdata.GitDataRequestCommit; @@ -46,7 +47,7 @@ protected GithubApiWrapper(@NonNull String username, @NonNull String token) { this.token = token; } - private HttpResponse executeRequest(@NonNull HttpUriRequest request) { + private HttpResponse executeRequest(@NonNull HttpUriRequest request) throws GithubProcessException { try { request.setHeader(ACCEPT_HEADER, ACCEPT_VALUE); HttpClient client = HttpClientBuilder.create().build(); @@ -61,14 +62,14 @@ private void appendAuthorizationHeader(@NonNull HttpUriRequest request) { request.setHeader(AUTH_HEADER, String.format("token %s", this.token)); } - protected HttpResponse createRepository(@NonNull GithubRepository repository) { + protected HttpResponse createRepository(@NonNull GithubRepository repository) throws GithubProcessException { HttpPost request = new HttpPost(CREATE_REPOSITORY_URL); try { StringEntity body = new StringEntity(MAPPER.writeValueAsString(repository), ContentType.APPLICATION_JSON); request.setEntity(body); } catch (JsonProcessingException e) { - throw new GithubProcessException("Failed to process GithubRepository to Json", e); + throw new GithubFileException("Failed to process GithubRepository to Json", e); } appendAuthorizationHeader(request); @@ -76,7 +77,7 @@ protected HttpResponse createRepository(@NonNull GithubRepository repository) { return executeRequest(request); } - protected HttpResponse deleteRepository(@NonNull String repositoryName) { + protected HttpResponse deleteRepository(@NonNull String repositoryName) throws GithubProcessException { String url = "https://api.github.com/repos/%s/%s"; HttpDelete request = new HttpDelete(String.format(url, username, repositoryName)); @@ -85,28 +86,31 @@ protected HttpResponse deleteRepository(@NonNull String repositoryName) { return executeRequest(request); } - protected HttpResponse getAllCommits(@NonNull String repositoryName) { + protected HttpResponse getAllCommits(@NonNull String repositoryName) throws GithubProcessException { String url = "https://api.github.com/repos/%s/%s/commits"; HttpGet request = new HttpGet(String.format(url, username, repositoryName)); return executeRequest(request); } - protected HttpResponse getGitDataCommit(@NonNull String repositoryName, @NonNull String commitSha) { + protected HttpResponse getGitDataCommit(@NonNull String repositoryName, @NonNull String commitSha) + throws GithubProcessException { String url = "https://api.github.com/repos/%s/%s/git/commits/%s"; HttpGet request = new HttpGet(String.format(url, username, repositoryName, commitSha)); return executeRequest(request); } - protected HttpResponse getGitDataTree(@NonNull String repositoryName, @NonNull String treeSha) { + protected HttpResponse getGitDataTree(@NonNull String repositoryName, @NonNull String treeSha) + throws GithubProcessException { String url = "https://api.github.com/repos/%s/%s/git/trees/%s"; HttpGet request = new HttpGet(String.format(url, username, repositoryName, treeSha)); return executeRequest(request); } - protected HttpResponse createGitDataTree(@NonNull String repositoryName, @NonNull GitDataRequestTree tree) { + protected HttpResponse createGitDataTree(@NonNull String repositoryName, @NonNull GitDataRequestTree tree) + throws GithubProcessException { String url = "https://api.github.com/repos/%s/%s/git/trees"; HttpPost request = new HttpPost(String.format(url, username, repositoryName)); @@ -122,7 +126,8 @@ protected HttpResponse createGitDataTree(@NonNull String repositoryName, @NonNul return executeRequest(request); } - protected HttpResponse createGitDataBlob(@NonNull String repositoryName, @NonNull GitDataRequestBlob blob) { + protected HttpResponse createGitDataBlob(@NonNull String repositoryName, @NonNull GitDataRequestBlob blob) + throws GithubProcessException { String url = "https://api.github.com/repos/%s/%s/git/blobs"; HttpPost request = new HttpPost(String.format(url, username, repositoryName)); @@ -138,7 +143,8 @@ protected HttpResponse createGitDataBlob(@NonNull String repositoryName, @NonNul return executeRequest(request); } - protected HttpResponse createGitDataCommit(@NonNull String repositoryName, @NonNull GitDataRequestCommit commit) { + protected HttpResponse createGitDataCommit(@NonNull String repositoryName, @NonNull GitDataRequestCommit commit) + throws GithubProcessException { String url = "https://api.github.com/repos/%s/%s/git/commits"; HttpPost request = new HttpPost(String.format(url, username, repositoryName)); @@ -155,7 +161,8 @@ protected HttpResponse createGitDataCommit(@NonNull String repositoryName, @NonN } protected HttpResponse updateGitDataReference(@NonNull String repositoryName, - @NonNull GitDataRequestReference reference) { + @NonNull GitDataRequestReference reference) + throws GithubProcessException { String url = "https://api.github.com/repos/%s/%s/git/refs/heads/master"; HttpPatch request = new HttpPatch(String.format(url, username, repositoryName)); diff --git a/src/main/java/com/microsoft/azure/springcloudplayground/github/GithubOperator.java b/src/main/java/com/microsoft/azure/springcloudplayground/github/GithubOperator.java index a567a16..20b1636 100644 --- a/src/main/java/com/microsoft/azure/springcloudplayground/github/GithubOperator.java +++ b/src/main/java/com/microsoft/azure/springcloudplayground/github/GithubOperator.java @@ -1,6 +1,7 @@ package com.microsoft.azure.springcloudplayground.github; import com.google.common.io.Files; +import com.microsoft.azure.springcloudplayground.exception.GithubFileException; import com.microsoft.azure.springcloudplayground.exception.GithubProcessException; import com.microsoft.azure.springcloudplayground.github.gitdata.*; import com.microsoft.azure.springcloudplayground.github.metadata.Author; @@ -22,7 +23,7 @@ public GithubOperator(@NonNull String username, @NonNull String token) { super(username, token); } - private String getContent(@NonNull HttpResponse response) { + private String getContent(@NonNull HttpResponse response) throws GithubProcessException { try { String line; BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); @@ -38,7 +39,7 @@ private String getContent(@NonNull HttpResponse response) { } } - private T readValue(@NonNull String json, Class clazz) { + private T readValue(@NonNull String json, Class clazz) throws GithubProcessException { try { return MAPPER.readValue(json, clazz); } catch (IOException e) { @@ -46,7 +47,7 @@ private T readValue(@NonNull String json, Class clazz) { } } - private GithubRepository createRepository(@NonNull String name) { + private GithubRepository createRepository(@NonNull String name) throws GithubProcessException { GithubRepository repository = GithubRepository.builder(name).build(); HttpResponse response = super.createRepository(repository); @@ -57,7 +58,7 @@ private GithubRepository createRepository(@NonNull String name) { return repository; } - public void deleteRepository(@NonNull GithubRepository repository) { + public void deleteRepository(@NonNull GithubRepository repository) throws GithubProcessException { HttpResponse response = super.deleteRepository(repository.getName()); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_NO_CONTENT) { @@ -65,7 +66,7 @@ public void deleteRepository(@NonNull GithubRepository repository) { } } - private List getRepositoryCommits(@NonNull GithubRepository repository) { + private List getRepositoryCommits(@NonNull GithubRepository repository) throws GithubProcessException { HttpResponse response = super.getAllCommits(repository.getName()); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { @@ -79,7 +80,8 @@ private List getRepositoryCommits(@NonNull GithubRepository reposi return Arrays.asList(commit); } - private GitDataCommit getGitDataCommit(@NonNull GithubRepository repository, @NonNull GithubCommit commit) { + private GitDataCommit getGitDataCommit(@NonNull GithubRepository repository, @NonNull GithubCommit commit) + throws GithubProcessException { HttpResponse response = super.getGitDataCommit(repository.getName(), commit.getSha()); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { @@ -89,7 +91,8 @@ private GitDataCommit getGitDataCommit(@NonNull GithubRepository repository, @No return readValue(getContent(response), GitDataCommit.class); } - private GitDataTree getGitDataTree(@NonNull GithubRepository repository, @NonNull GitDataCommit commit) { + private GitDataTree getGitDataTree(@NonNull GithubRepository repository, @NonNull GitDataCommit commit) + throws GithubProcessException { HttpResponse response = super.getGitDataTree(repository.getName(), commit.getTree().getSha()); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { @@ -108,7 +111,8 @@ private GitDataRequestTree getGitDataRequestTree(@NonNull GitDataTree baseTree) return requestTree; } - private GitDataBlob createGitDataBlob(@NonNull GithubRepository repository, @NonNull GitDataRequestBlob requestBlob) { + private GitDataBlob createGitDataBlob(@NonNull GithubRepository repository, @NonNull GitDataRequestBlob requestBlob) + throws GithubProcessException { HttpResponse response = super.createGitDataBlob(repository.getName(), requestBlob); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { @@ -124,7 +128,7 @@ private GitDataRequestBlob getGitDataRequestBlob(@NonNull String filename) { return new GitDataRequestBlob(content, "utf-8"); } catch (IOException e) { - throw new GithubProcessException("Failed to read file: " + filename, e); + throw new GithubFileException("Failed to read file: " + filename, e); } } @@ -149,7 +153,8 @@ private GitDataRequestCommit getGitDateRequestCommit(@NonNull GitDataCommit pare .build(); } - private GitDataCommit createGitDateCommit(@NonNull GithubRepository repository, @NonNull GitDataRequestCommit commit) { + private GitDataCommit createGitDateCommit(@NonNull GithubRepository repository, @NonNull GitDataRequestCommit commit) + throws GithubProcessException { HttpResponse response = super.createGitDataCommit(repository.getName(), commit); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { @@ -159,7 +164,8 @@ private GitDataCommit createGitDateCommit(@NonNull GithubRepository repository, return readValue(getContent(response), GitDataCommit.class); } - private GithubTree createGitDataTree(@NonNull GithubRepository repository, @NonNull GitDataRequestTree tree) { + private GithubTree createGitDataTree(@NonNull GithubRepository repository, @NonNull GitDataRequestTree tree) + throws GithubProcessException { HttpResponse response = super.createGitDataTree(repository.getName(), tree); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { @@ -174,7 +180,7 @@ private GitDataRequestReference getGitDataRequestReference(@NonNull GitDataCommi } private void updateGithubRepository(@NonNull GithubRepository repository, - @NonNull GitDataRequestReference reference) { + @NonNull GitDataRequestReference reference) throws GithubProcessException { HttpResponse response = super.updateGitDataReference(repository.getName(), reference); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { @@ -219,25 +225,24 @@ private String truncateFileNamePrefix(@NonNull String fileName) { } private GithubTree createGithubTree(@NonNull GithubRepository repository, @NonNull GitDataCommit parentCommit, - @NonNull File dir) { + @NonNull File dir) throws GithubProcessException { List files = getAllFiles(dir); GitDataTree tree = getGitDataTree(repository, parentCommit); GitDataRequestTree requestTree = getGitDataRequestTree(tree); List requestBlobs = files.stream().map(this::getGitDataRequestBlob).collect(Collectors.toList()); - List blobs = requestBlobs.stream().map(b -> createGitDataBlob(repository, b)).collect(Collectors.toList()); for (int i = 0; i < files.size(); i++) { String filename = files.get(i); - String sha = blobs.get(i).getSha(); + GitDataBlob blob = createGitDataBlob(repository, requestBlobs.get(i)); - requestTree.getTree().add(getRequestTreeNode(truncateFileNamePrefix(filename), sha)); + requestTree.getTree().add(getRequestTreeNode(truncateFileNamePrefix(filename), blob.getSha())); } return createGitDataTree(repository, requestTree); } - public void createRepository(@NonNull File dir) { - GithubRepository repository = createRepository("spring-cloud-azure-demo"); + public void createRepository(@NonNull File dir, @NonNull String repositoryName) throws GithubProcessException { + GithubRepository repository = createRepository(repositoryName); GitDataCommit parentCommit = getGitDataCommit(repository, getRepositoryCommits(repository).get(0)); GithubTree githubTree = createGithubTree(repository, parentCommit, dir); GitDataRequestCommit requestCommit = getGitDateRequestCommit(parentCommit, githubTree); @@ -245,7 +250,5 @@ public void createRepository(@NonNull File dir) { GitDataRequestReference reference = getGitDataRequestReference(commit); updateGithubRepository(repository, reference); - - deleteRepository(repository); } } diff --git a/src/main/resources/static/js/start.js b/src/main/resources/static/js/start.js index a30d8a7..5249313 100644 --- a/src/main/resources/static/js/start.js +++ b/src/main/resources/static/js/start.js @@ -212,9 +212,9 @@ $(function () { generateInProgress(); var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { - if (xhttp.readyState === 4 && xhttp.status === 200) { + if (xhttp.readyState === 4 && xhttp.status === 201) { generateSucceed(); - } else { + } else if (xhttp.readyState === 4) { generateFailed(); } closeModal(githubConfigModal);