Created
March 4, 2016 09:02
-
-
Save unixunion/0d1599f6eeb83319c44a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.deblox.greatsnipe.git.impl; | |
import com.deblox.greatsnipe.git.GitServerProvider; | |
import io.netty.handler.codec.http.HttpHeaders; | |
import io.vertx.core.Handler; | |
import io.vertx.core.Vertx; | |
import io.vertx.core.http.HttpClient; | |
import io.vertx.core.http.HttpClientRequest; | |
import io.vertx.core.json.JsonObject; | |
import io.vertx.core.logging.Logger; | |
import io.vertx.core.logging.LoggerFactory; | |
import java.io.IOException; | |
import java.net.MalformedURLException; | |
import java.net.URL; | |
import java.util.Base64; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
/** | |
* Created by keghol on 02/12/15. | |
*/ | |
public class BitBucket implements GitServerProvider { | |
private static final Logger logging = LoggerFactory.getLogger(BitBucket.class); | |
HttpClient client; | |
public URL apiUrl; // e.g. https://bitbucket.mydomain.com:80/stash/rest/api/1.0 | |
public String token; // username:password goes here | |
private String repoUrl; // set this from result of createProjectAndRepo | |
private Vertx vertx; | |
@Override | |
public GitServerProvider setVertx(Vertx vertx) { | |
this.vertx = vertx; | |
return this; | |
} | |
/** | |
* Set the url to the BitBucket API, e.g.: https://bitbucket.mydomain.com:80/stash/rest/api/1.0 | |
* <p> | |
* Important to specify the PORT in the URL! | |
* @param url | |
* @return | |
* @throws MalformedURLException | |
*/ | |
@Override | |
public GitServerProvider setApiUrl(String url) throws MalformedURLException { | |
apiUrl = new URL(url); | |
client = vertx.createHttpClient(); | |
return this; | |
} | |
/** | |
* sets the token we will use for authentication, for BitBucket, this is "username:password". | |
* | |
* @param token | |
* @return | |
*/ | |
@Override | |
public GitServerProvider setToken(String token) { | |
this.token = token; | |
return this; | |
} | |
/** | |
* Create a project within BitBucket, create a repo within project, return URL to repo. | |
* | |
* Ignores failures to create duplicate projects, returning the URL to the REPO is the only goal. | |
* | |
* @param name JsonObject which contains the keys `projectKey` and `projectName` and `repoName` | |
* @param handler the handler to call with the body | |
* @throws IOException | |
*/ | |
@Override | |
public void createProjectAndRepo(Object name, Handler<Object> handler) throws IOException { | |
JsonObject document = (JsonObject)name; | |
// copy relevant keys to the new request on the correct key name per BitBucket API specification | |
JsonObject request = new JsonObject(); | |
request.put("key", document.getValue("projectKey")); | |
request.put("name", document.getValue("projectName")); | |
HttpClientRequest req = client.post(apiUrl.getPort(), apiUrl.getHost(), apiUrl.getPath() + "/projects", res -> { | |
res.bodyHandler(body -> { | |
logging.info("Response: " + body.toString()); | |
// created {"key":"MGP","id":62,"name":"My Group","public":false,"type":"NORMAL","link":{"url":"/projects/MGP","rel":"self"},"links":{"self":[{"href":"https://stashpoc.unibet.com/stash/projects/MGP"}]}} | |
// exists {"errors":[{"context":"key","message":"The project key is already in use","exceptionName":null},{"context":"name","message":"The project name is already in use","exceptionName":null}]} | |
logging.info("Creating Repo"); | |
HttpClientRequest createRepo = client.post(apiUrl.getPort(), apiUrl.getHost(), apiUrl.getPath() + "/projects/" + document.getValue("projectKey") + "/repos", createResult -> { | |
createResult.bodyHandler( c -> { | |
logging.info(c.toString()); | |
logging.info("Getting Project URL URL"); | |
HttpClientRequest req2 = client.get(apiUrl.getPort(), apiUrl.getHost(), apiUrl.getPath() + "/projects/" + document.getValue("projectKey") + "/repos/" + document.getValue("repoName"), res2 -> { | |
res2.bodyHandler(f -> { | |
logging.info(f.toString()); | |
try { | |
handler.handle(new JsonObject(f.toString()).getString("cloneUrl")); | |
} catch (Exception e) { | |
handler.handle(new JsonObject().put("error", "unable to get repo url")); | |
} | |
}); | |
}); | |
req2 = appendHeaders(req2); | |
req2.end(); | |
}); | |
}); | |
JsonObject newRepoJson = new JsonObject(); | |
newRepoJson.put("name", document.getValue("repoName")); | |
newRepoJson.put("scmId", "git"); | |
newRepoJson.put("forkable", true); | |
createRepo = appendHeaders(createRepo); | |
createRepo.end(); | |
}); | |
}); | |
req = appendHeaders(req); | |
logging.info("Created Request: " + request.toString()); | |
try { | |
req.end(request.toString()); | |
} catch (Exception e) { | |
logging.error("talking to gitApiUrl error, example: https://stash.mydomain.com:80/stash/rest/api/1.0"); | |
req.end("talking to gitApiUrl error, example: https://stash.mydomain.com:80/stash/rest/api/1.0"); | |
} | |
} | |
/** | |
* Encodes "token" and puts it into a Basic Auth header. Token should be "username:password" | |
* | |
* @param req | |
* @return | |
*/ | |
public HttpClientRequest appendHeaders(HttpClientRequest req) { | |
logging.info("Appending credentials"); | |
req.putHeader(HttpHeaders.Names.AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString(token.getBytes())); | |
req.putHeader(HttpHeaders.Names.CONTENT_TYPE, "application/json"); | |
return req; | |
} | |
@Override | |
public String getRepoUrl() { | |
return repoUrl; | |
} | |
/** | |
* Return the url with username:password in it. | |
* <p> | |
* depends on that the repoUrl is already set, and will strip away any username and password | |
* already within the URL. | |
* | |
* @return | |
*/ | |
@Override | |
public String getAuhRepoUrl(String username, String password) { | |
logging.info("Getting auth repo url for " + | |
"username: " + username + " " + | |
"password: " + password + " " + | |
"repoUrl: " + repoUrl); | |
if (!username.equals("")) { | |
Pattern pattern1 = Pattern.compile("http://.*@"); | |
Pattern pattern2 = Pattern.compile("https://.*@"); | |
Matcher m1 = pattern1.matcher(repoUrl); | |
String m1S = m1.replaceAll("http://" + username + ":" + password + "@"); | |
Matcher m2 = pattern2.matcher(m1S); | |
String m2S = m2.replaceAll("https://" + username + ":" + password + "@"); | |
logging.info("Adding credential to url: " + m2S); | |
return m2S; | |
} else { | |
logging.warn("username not set, returning original url"); | |
return repoUrl; | |
} | |
} | |
public void setRepoUrl(String repoUrl) { | |
logging.info("Setting repoUrl: " + repoUrl); | |
this.repoUrl = repoUrl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment