Skip to content

Commit

Permalink
Merge pull request #6 from SBI-/master
Browse files Browse the repository at this point in the history
Add support for path parameters in rest urls
  • Loading branch information
SBI- committed Jun 29, 2018
2 parents 41b654b + 67feae0 commit 542ac44
Show file tree
Hide file tree
Showing 33 changed files with 493 additions and 186 deletions.
2 changes: 1 addition & 1 deletion feature/feature.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<feature
id="org.jazzcommunity.GitConnectorService.feature"
label="REST Service"
version="1.4.0.qualifier"
version="1.5.0.qualifier"
provider-name="PROVIDER">

<description url="http://www.example.com/description">
Expand Down
2 changes: 1 addition & 1 deletion feature/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.jazzcommunity.GitConnectorService</groupId>
<artifactId>org.jazzcommunity.GitConnectorService.parent</artifactId>
<version>1.4.0-SNAPSHOT</version>
<version>1.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion plugin/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: org.jazzcommunity.GitConnectorService
Bundle-SymbolicName: org.jazzcommunity.GitConnectorService;singleton:=true
Bundle-Version: 1.4.0.qualifier
Bundle-Version: 1.5.0.qualifier
Bundle-Vendor: VENDOR
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle:
Expand Down
2 changes: 1 addition & 1 deletion plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.jazzcommunity.GitConnectorService</groupId>
<artifactId>org.jazzcommunity.GitConnectorService.parent</artifactId>
<version>1.4.0-SNAPSHOT</version>
<version>1.5.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@
import com.ibm.team.jfs.app.http.util.HttpConstants.HttpMethod;
import com.ibm.team.repository.service.TeamRawService;
import com.siemens.bt.jazz.services.base.rest.RestAction;
import com.siemens.bt.jazz.services.base.rest.RestActionBuilder;
import com.siemens.bt.jazz.services.base.rest.RestRequest;
import com.siemens.bt.jazz.services.base.router.factory.RestFactory;
import org.eclipse.core.runtime.Platform;
import org.jazzcommunity.GitConnectorService.base.rest.RestActionBuilder;
import org.jazzcommunity.GitConnectorService.base.router.factory.RestFactory;
import org.jazzcommunity.GitConnectorService.builder.VersionService;
import org.jazzcommunity.GitConnectorService.builder.gitlab.IssueLinkService;
import org.jazzcommunity.GitConnectorService.builder.gitlab.IssuePreviewService;
import org.jazzcommunity.GitConnectorService.builder.gitlab.RequestLinkService;
import org.jazzcommunity.GitConnectorService.builder.gitlab.RequestPreviewService;
import org.jazzcommunity.GitConnectorService.router.CustomRouter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.Version;
import org.jazzcommunity.GitConnectorService.base.router.CustomRouter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
Expand All @@ -36,28 +33,23 @@ public class GitConnectorService extends TeamRawService implements IGitConnector
*/
public GitConnectorService() {
super();
router.addService(
HttpMethod.GET,
"gitlab/[a-zA-Z.]+/project/[0-9]+/issue/[0-9]+/link.*",
new RestFactory(IssueLinkService.class));
router.addService(
HttpMethod.GET,
"gitlab/[a-zA-Z.]+/project/[0-9]+/issue/[0-9]+/preview.*",
new RestFactory(IssuePreviewService.class));
router.get(new RestFactory(
"gitlab/{host}/project/{projectId}/issue/{issueId}/link.*",
IssueLinkService.class));
router.get(new RestFactory(
"gitlab/{host}/project/{projectId}/issue/{issueId}/preview.*",
IssuePreviewService.class));

router.addService(
HttpMethod.GET,
"gitlab/[a-zA-Z.]+/project/[0-9]+/merge-request/[0-9]+/link.*",
new RestFactory(RequestLinkService.class));
router.addService(
HttpMethod.GET,
"gitlab/[a-zA-Z.]+/project/[0-9]+/merge-request/[0-9]+/preview.*",
new RestFactory(RequestPreviewService.class));
router.get(new RestFactory(
"gitlab/{host}/project/{projectId}/merge-request/{mergeRequestId}/link.*",
RequestLinkService.class));
router.get(new RestFactory(
"gitlab/{host}/project/{projectId}/merge-request/{mergeRequestId}/preview.*",
RequestPreviewService.class));

router.addService(
HttpMethod.GET,
router.get(new RestFactory(
"info/version",
new RestFactory(VersionService.class));
VersionService.class));

/**
* This code is purposely commented out and not deleted!
Expand Down Expand Up @@ -99,12 +91,19 @@ protected void performAction(String uri, HttpServletRequest request, HttpServlet
}
}

protected final RestActionBuilder prepareRequest(String uri,
HttpServletRequest request,
HttpServletResponse response) {
protected final RestActionBuilder prepareRequest(
String uri,
HttpServletRequest request,
HttpServletResponse response) {

HttpMethod method = HttpMethod.fromString(request.getMethod());
@SuppressWarnings("unchecked")
RestRequest restRequest = new RestRequest(method, uri, request.getParameterMap());
return router.prepareAction(this, this.getLog(), request, response, restRequest);
return router.prepareAction(
this,
this.getLog(),
request,
response,
restRequest);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.jazzcommunity.GitConnectorService.base.rest;

import com.ibm.team.repository.service.TeamRawService;
import com.siemens.bt.jazz.services.base.rest.RestAction;
import com.siemens.bt.jazz.services.base.rest.RestRequest;
import org.apache.commons.logging.Log;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class AbstractRestService implements RestAction {
protected Log log;
protected HttpServletRequest request;
protected HttpServletResponse response;
protected RestRequest restRequest;
protected TeamRawService parentService;
protected PathParameters pathParameters;

public AbstractRestService(
Log log,
HttpServletRequest request,
HttpServletResponse response,
RestRequest restRequest,
TeamRawService parentService,
PathParameters pathParameters) {
this.log = log;
this.request = request;
this.response = response;
this.restRequest = restRequest;
this.parentService = parentService;
this.pathParameters = pathParameters;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.jazzcommunity.GitConnectorService.base.rest;

import com.ibm.team.repository.service.TeamRawService;
import com.siemens.bt.jazz.services.base.rest.RestRequest;
import org.apache.commons.logging.Log;
import org.apache.http.HttpStatus;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

public class DefaultRestService extends AbstractRestService {
public DefaultRestService(Log log, HttpServletRequest request, HttpServletResponse response, RestRequest restRequest, TeamRawService parentService, PathParameters pathParameters) {
super(log, request, response, restRequest, parentService, pathParameters);
}

@Override
public void execute() throws Exception {
this.response.setStatus(HttpStatus.SC_NOT_IMPLEMENTED);
this.response.setContentType("text");
PrintWriter writer = this.response.getWriter();
String answer = String.format("The requested service \"%s\" doesn't exist for method \"%s\".",
this.restRequest,
this.request.getMethod());
writer.write(answer);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.jazzcommunity.GitConnectorService.base.rest;

import com.google.common.base.Joiner;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PathParameters {
private final Map<String, String> parameters;

public PathParameters(String path, String url) {
// first, I want the names...
// This I can probably do just once..., maybe when
// creating the service. But I'm not going to optimize
// this until later.
ArrayList<String> names = getNames(path);
ArrayList<String> values = getValues(path, url);

if (names.size() != values.size()) {
throw new RuntimeException("Unable to match url parameters to values");
}

this.parameters = makeMap(names, values);
}

// getters should do checking if stuff exists etc.
public String get(String key) {
return parameters.get(key);
}

public Integer getAsInteger(String key) {
return Integer.parseInt(get(key));
}

private Map<String, String> makeMap(ArrayList<String> names, ArrayList<String> values) {
// zip operation
HashMap<String, String> parameters = new HashMap<>();

for (int i = 0; i < names.size(); i += 1) {
parameters.put(names.get(i), values.get(i));
}

return parameters;
}

// It's probably possible to consolidate these two functions, maybe even into a single
// regex call.
// Idea: Match the all-match regex to both path and url, which should give the name
// in one match and the value in the other. Then the zip could be done right away as well.
// this is what the matching regex should look like: \{{0,1}([^\/}]+)\}{0,1} for everything
// in {} and not. The rest of the path should then match accordingly.
// Regex 101: example
// gitlab\/\{{0,1}([^\/}]+)\}{0,1}\/project\/\{{0,1}([^\/}]+)\}{0,1}\/issue\/\{{0,1}([^\/}]+)\}{0,1}\/link.*
// will match the path and the actual url as well.
// test data:
// gitlab/{host}/project/{projectId}/issue/{issueId}/link.*
// gitlab/code.siemens.com/project/1234/issue/12/link.*
private static ArrayList<String> getValues(String path, String url) {
String regex = path.replaceAll("\\{[^\\/]+\\}", "([^\\\\/]+)");
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(url);

ArrayList<String> values = new ArrayList<>();
matcher.find();

for (int i = 1; i <= matcher.groupCount(); i += 1) {
values.add(matcher.group(i));
}

return values;
}

private static ArrayList<String> getNames(String path) {
String regex = "\\{([^\\/]+)\\}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(path);

ArrayList<String> names = new ArrayList<>();
while (matcher.find()) {
names.add(matcher.group(1));
}

return names;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.jazzcommunity.GitConnectorService.base.rest;

import com.ibm.team.repository.service.TeamRawService;
import com.siemens.bt.jazz.services.base.rest.RestAction;
import com.siemens.bt.jazz.services.base.rest.RestRequest;
import org.apache.commons.logging.Log;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class RestActionBuilder {
protected final Class<? extends AbstractRestService> serviceClass;
protected final String path;
protected HttpServletRequest request;
protected HttpServletResponse response;
// not sure about which log to use here...
protected Log log;
protected RestRequest restRequest;
protected TeamRawService parentService;

public RestActionBuilder(Class<? extends AbstractRestService> serviceClass, String path) {
this.serviceClass = serviceClass;
this.path = path;
}

public RestActionBuilder setLog(Log log) {
this.log = log;
return this;
}

public RestActionBuilder setRequest(HttpServletRequest request) {
this.request = request;
return this;
}

public RestActionBuilder setResponse(HttpServletResponse response) {
this.response = response;
return this;
}

public RestActionBuilder setRestRequest(RestRequest restRequest) {
this.restRequest = restRequest;
return this;
}

public RestActionBuilder setParentService(TeamRawService parentService) {
this.parentService = parentService;
return this;
}

public RestAction create() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Constructor<? extends AbstractRestService> constructor = this.serviceClass.getConstructor(
Log.class,
HttpServletRequest.class,
HttpServletResponse.class,
RestRequest.class,
TeamRawService.class,
PathParameters.class);

return (RestAction)constructor.newInstance(
this.log,
this.request,
this.response,
this.restRequest,
this.parentService,
// not sure yet if this belongs here, or in the actual
// constructor of the abstract service...
new PathParameters(path, restRequest.toString()));
}

}
Loading

0 comments on commit 542ac44

Please sign in to comment.