diff --git a/.gitignore b/.gitignore index 5df7221..4aff0ac 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,8 @@ hs_err_pid* .classpath .project .settings +.gradle +build/ +.idea/ +*.swp +*.iml diff --git a/Application.groovy b/Application.groovy deleted file mode 100644 index bc7d5b4..0000000 --- a/Application.groovy +++ /dev/null @@ -1,7 +0,0 @@ -@Grab("edu.wisc.my.restproxy:json-proxy-service:1.0") - -@ComponentScan("edu.wisc.my.restproxy") -@RestController -@RequestMapping("/") -class ProxyService extends edu.wisc.my.restproxy.api.GenericRestLookupController {} - diff --git a/README.md b/README.md index 8475785..0e5c248 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ -# json-proxy-service -A Simple server side JSON proxy service written in Java +# rest-proxy +A Simple server side REST proxy service written in Groovy -[![Build Status](https://travis-ci.org/UW-Madison-DoIT/json-proxy-service.svg)](https://travis-ci.org/UW-Madison-DoIT/json-proxy-service) +[![Build Status](https://travis-ci.org/UW-Madison-DoIT/rest-proxy.svg)](https://travis-ci.org/UW-Madison-DoIT/rest-proxy) ### Purpose This is an important component with a couple of use cases. - * Picture an app in the portal providing a preview of a fuller external application. Without this component, we would need to write REST controllers in the app that are a façade to the external-to-portal REST web services (that might even be provided out of the WSO2 ESB). With this component, we can drop `json-proxy-service` in the portal app, configure it with the ESB endpoint address for the application's REST API and credentials, and then NOT have to write any controllers! The AngularJS controllers can talk to the (same domain) URIs presented by the `json-proxy-service` controllers, which in turn relay to the ESB and the external application. + * Picture an app in the portal providing a preview of a fuller external application. Without this component, we would need to write REST controllers in the app that are a façade to the external-to-portal REST web services (that might even be provided out of the WSO2 ESB). With this component, we can drop `rest-proxy-core` in the portal app, configure it with the ESB endpoint address for the application's REST API and credentials, and then NOT have to write any controllers! The AngularJS controllers can talk to the (same domain) URIs presented by the `rest-proxy-core` controllers, which in turn relay to the ESB and the external application. * Picture this module deployed as a façade for ESB endpoints. `my.wisc.edu/esb/someservice/api/foo` . You could theoretically write 100% javascript apps against the proxy proxying ESB-provided JSON. ### Add Proxy Servlet to Existing Service @@ -19,12 +19,12 @@ This is an important component with a couple of use cases. + Setup a servlet: ```xml - json-proxy-api + rest-proxy-api org.springframework.web.servlet.DispatcherServlet 1 - json-proxy-api + rest-proxy-api /api/* @@ -33,15 +33,20 @@ This is an important component with a couple of use cases. ### Run Standalone Microservice -#### Prerequisites - * [Grails 3.0.x](https://grails.org/) - #### Running -* Run `grails run-app` to start the server -* [Verify it works](localhost:8080/todos.json) +* Supply endpoint configuration - you can copy application.properties.example to get started, or add a command-line flag, e.g. `--todos.uri=http://jsonplaceholder.typicode.com/todos` +* Run `gradle bootRun` to start the server +* [Verify in your browser](localhost:8080/todos) __OR__ -* Run `grails package` to build a jar artifact -* Start the server by running `java -jar build/proxy-service-0.1.jar` +* Run `gradle build` to build a standalone jar +* Start the server by running `java -jar rest-proxy-boot/build/rest-proxy-boot-.jar` + +### Releasing to Artifact Repository + +#### Manually +Only authorized users can perform the release. Contact one of the core contributors if you think you should have access. + +* Run `gradle uploadArchives` and provide Sonatype credentials when prompted (if they are not already supplied in ~/.gradle/gradle.properties). This will build both projects and generate pomfiles, javadoc, test, and sources artifacts, and then upload them to the Sonatype Nexus repository. diff --git a/application.yml b/application.yml deleted file mode 100644 index e3a3018..0000000 --- a/application.yml +++ /dev/null @@ -1,53 +0,0 @@ -grails: - profile: web-micro - codegen: - defaultPackage: proxy.service -info: - app: - name: proxy-service - version: 0.1 - grailsVersion: 3.0.2 -spring: - groovy: - template: - check-template-location: false ---- -grails: - mime: - disable: - accept: - header: - userAgents: - - Gecko - - WebKit - - Presto - - Trident - types: - all: '*/*' - atom: application/atom+xml - css: text/css - csv: text/csv - form: application/x-www-form-urlencoded - html: - - text/html - - application/xhtml+xml - js: text/javascript - json: - - application/json - - text/json - multipartForm: multipart/form-data - rss: application/rss+xml - text: text/plain - hal: - - application/hal+json - - application/hal+xml - xml: - - text/xml - - application/xml - urlmapping: - cache: - maxsize: 1000 - controllers: - defaultScope: singleton - converters: - encoding: UTF-8 diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..804479c --- /dev/null +++ b/build.gradle @@ -0,0 +1,88 @@ +buildscript { + repositories { jcenter() } + dependencies { classpath 'com.bmuschko:gradle-nexus-plugin:2.3.1' } +} + +subprojects { + + group = 'edu.wisc.my.restproxy' + version = '2.1.0-SNAPSHOT' + + repositories { + maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } + maven { url "https://code.doit.wisc.edu/maven/content/repositories/public-releases/" } + maven { url "https://code.doit.wisc.edu/maven/content/repositories/uw-releases/" } + maven { url "http://repo.maven.apache.org/maven2" } + } + + apply plugin: 'groovy' + apply plugin: 'com.bmuschko.nexus' + + // Nexus deploy configuration + nexus { + sign = true + repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' + snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots/' + } + + extraArchive { + javadoc = true + sources = true + tests = true + } + + modifyPom { + project { + url 'https://github.com/UW-Madison-DoIT/rest-proxy' + inceptionYear '2015' + scm { + url 'https://github.com/UW-Madison-DoIT/rest-proxy' + connection 'scm:https://github.com/UW-Madison-DoIT/rest-proxy.git' + developerConnection 'scm:git://github.com/UW-Madison-DoIT/rest-proxy.git' + } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + developers { + developer { + name 'My UW Dev Team' + email 'my-admin@lists.wisc.edu' + url 'https://github.com/UW-Madison-DoIT' + organization 'UW-Madison-DoIT' + } + } + // The nexus plugin overlooks provided dependencies + // so we override this bit to make sure they get in + def generatedDeps = dependencies + dependencies { + generatedDeps.each { dep -> + dependency { + groupId dep.groupId + artifactId dep.artifactId + version dep.version + scope dep.scope + } + } + project.configurations.provided.allDependencies.each { dep -> + dependency { + groupId dep.group + artifactId dep.name + version dep.version + scope 'provided' + } + } + } + } + } + + // Define provided scope + configurations { + provided + compile.extendsFrom provided + } + +} diff --git a/pom.xml b/pom.xml deleted file mode 100644 index f0a5c01..0000000 --- a/pom.xml +++ /dev/null @@ -1,236 +0,0 @@ - - 4.0.0 - edu.wisc.my.restproxy - json-proxy-service - jar - 2.0.0-SNAPSHOT - json-proxy-service - https://github.com/UW-Madison-DoIT/json-proxy-service - A simple JSON REST Proxy service - - - - my-admin@lists.wisc.edu - UW-Madison - https://github.com/UW-Madison-DoIT/angularjs-portal - My UW Dev Team - - - - - 4.1.5.RELEASE - 1.7.5 - - - - - Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - scm:git:git@github.com:UW-Madison-DoIT/json-proxy-service.git - scm:git:git@github.com:UW-Madison-DoIT/json-proxy-service.git - https://github.com/UW-Madison-DoIT/json-proxy-service - HEAD - - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - - - - org.apache.commons - commons-lang3 - 3.3.2 - - - commons-codec - commons-codec - 1.1 - - - com.fasterxml.jackson.core - jackson-databind - 2.2.0 - - - com.google.guava - guava - 18.0 - - - - - org.springframework - spring-core - ${spring.version} - - - - org.springframework - spring-web - ${spring.version} - - - - org.springframework - spring-webmvc - ${spring.version} - - - - - org.slf4j - jcl-over-slf4j - ${slf4j.version} - - - org.slf4j - slf4j-api - ${slf4j.version} - - - - ch.qos.logback - logback-classic - 1.0.12 - runtime - - - org.slf4j - jul-to-slf4j - ${slf4j.version} - runtime - - - org.slf4j - log4j-over-slf4j - ${slf4j.version} - runtime - - - - - - javax.servlet - javax.servlet-api - 3.0.1 - provided - - - - - junit - junit - 4.11 - test - - - org.mockito - mockito-core - 1.9.5 - test - - - org.springframework - spring-test - ${spring.version} - test - - - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.1 - - true - false - release - deploy - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.5 - false - - ossrh - https://oss.sonatype.org/ - true - - - - maven-compiler-plugin - 3.3 - - 1.7 - 1.7 - - - - - - - release - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.5 - - - sign-artifacts - verify - - sign - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - - attach-javadocs - - jar - - - - - - - - - diff --git a/rest-proxy-boot/build.gradle b/rest-proxy-boot/build.gradle new file mode 100644 index 0000000..f33cadb --- /dev/null +++ b/rest-proxy-boot/build.gradle @@ -0,0 +1,19 @@ +description = "A simple standalone REST proxy server" + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE") + } +} +apply plugin: 'spring-boot' +mainClassName = "edu.wisc.my.restproxy.Server" + +dependencies { + compile 'org.codehaus.groovy:groovy-all:2.4.4' + compile 'org.springframework.boot:spring-boot-starter-web:1.2.5.RELEASE' + compile project(':rest-proxy-core') +} + diff --git a/rest-proxy-boot/src/main/groovy/edu/wisc/my/restproxy/Server.groovy b/rest-proxy-boot/src/main/groovy/edu/wisc/my/restproxy/Server.groovy new file mode 100644 index 0000000..eb83af4 --- /dev/null +++ b/rest-proxy-boot/src/main/groovy/edu/wisc/my/restproxy/Server.groovy @@ -0,0 +1,12 @@ +package edu.wisc.my.restproxy + +import org.springframework.boot.SpringApplication +import org.springframework.boot.autoconfigure.SpringBootApplication + +@SpringBootApplication +class Server { + public static void main(String[] args) { + SpringApplication.run(Server.class, args); + } +} + diff --git a/rest-proxy-boot/src/main/resources/.gitignore b/rest-proxy-boot/src/main/resources/.gitignore new file mode 100644 index 0000000..bbd5731 --- /dev/null +++ b/rest-proxy-boot/src/main/resources/.gitignore @@ -0,0 +1,2 @@ +application.properties + diff --git a/endpoint.properties b/rest-proxy-boot/src/main/resources/application.properties.example similarity index 74% rename from endpoint.properties rename to rest-proxy-boot/src/main/resources/application.properties.example index 8d6a588..72a5263 100644 --- a/endpoint.properties +++ b/rest-proxy-boot/src/main/resources/application.properties.example @@ -2,6 +2,7 @@ #key.username : the username to login to service (basic auth) * #key.password : the password for the service (basic auth) * #key.attributes : the csv of attributes +#key.proxyHeaders : a comma separated list of headers to add output. Can put placeholders for values to get local request attributes. #key.cache : how long to cache the information for that URI (with variables replaced) - not implemented yet # # * : not required @@ -24,5 +25,12 @@ uwmadisonreddit.username= uwmadisonreddit.password= uwmadisonreddit.attributes= +# proxyHeaders example +someservice.uri=http://somewhere.wisc.edu/foo +someservice.username=user +someservice.password=pass +someservice.proxyHeaders=On-Behalf-Of: {wiscedupvi},Some-Other-Header: staticvalue + #todos placeholder example todos.uri=http://jsonplaceholder.typicode.com/todos + diff --git a/rest-proxy-core/build.gradle b/rest-proxy-core/build.gradle new file mode 100644 index 0000000..7028f89 --- /dev/null +++ b/rest-proxy-core/build.gradle @@ -0,0 +1,25 @@ +description = "A simple server-side REST proxy library" + +sourceCompatibility = 1.7 +targetCompatibility = 1.7 + +dependencies { + compile 'org.codehaus.groovy:groovy-all:2.4.4' + compile 'org.apache.commons:commons-lang3:3.3.2' + compile 'commons-codec:commons-codec:1.1' + compile 'com.fasterxml.jackson.core:jackson-databind:2.2.0' + compile 'com.google.guava:guava:18.0' + compile 'org.springframework:spring-core:4.1.5.RELEASE' + compile 'org.springframework:spring-web:4.1.5.RELEASE' + compile 'org.springframework:spring-webmvc:4.1.5.RELEASE' + compile 'org.slf4j:jcl-over-slf4j:1.7.5' + compile 'org.slf4j:slf4j-api:1.7.5' + runtime 'ch.qos.logback:logback-classic:1.0.12' + runtime 'org.slf4j:jul-to-slf4j:1.7.5' + runtime 'org.slf4j:log4j-over-slf4j:1.7.5' + testCompile 'junit:junit:4.11' + testCompile 'org.mockito:mockito-core:1.9.5' + testCompile 'org.springframework:spring-test:4.1.5.RELEASE' + provided 'javax.servlet:javax.servlet-api:3.1.0' +} + diff --git a/src/main/java/edu/wisc/my/restproxy/KeyUtils.java b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/KeyUtils.groovy similarity index 94% rename from src/main/java/edu/wisc/my/restproxy/KeyUtils.java rename to rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/KeyUtils.groovy index c15d1bf..dbd661e 100644 --- a/src/main/java/edu/wisc/my/restproxy/KeyUtils.java +++ b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/KeyUtils.groovy @@ -1,7 +1,6 @@ -package edu.wisc.my.restproxy; +package edu.wisc.my.restproxy -import java.util.HashMap; -import java.util.Map; +import groovy.transform.CompileStatic; import javax.servlet.http.HttpServletRequest; @@ -14,6 +13,7 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; +@CompileStatic public final class KeyUtils { private static final String END_PLACEHOLDER = "}"; @@ -21,9 +21,9 @@ public final class KeyUtils { private KeyUtils() { } - + private static final Logger logger = LoggerFactory.getLogger(KeyUtils.class); - + public static Map getHeaders(Environment env, HttpServletRequest request, String key) { HashMap map = new HashMap(); String attributes = env.getProperty(key + ".attributes"); @@ -37,18 +37,18 @@ public static Map getHeaders(Environment env, HttpServletRequest /** * Utility method for extracting the Proxy Headers for a request. - * + * * The configuration option '{key}.proxyHeaders' is used to specify a multi-valued list of HTTP headers to add to the - * outbound request to '{key}.uri'. - * + * outbound request to '{key}.uri'. + * * Example: *
    someservice.proxyHeaders=On-Behalf-Of: {wiscedupvi},Some-Other-Header: staticvalue
    
- * - * Implementers can specify either static values ('Some-Other-Header: staticvalue') or use placeholders to relay + * + * Implementers can specify either static values ('Some-Other-Header: staticvalue') or use placeholders to relay * {@link HttpServletRequest#getAttribute(String)} values ('On-Behalf-Of: {wiscedupvi}') - * + * * @param env * @param resourceKey * @param request diff --git a/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/ProxyRequestContext.groovy b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/ProxyRequestContext.groovy new file mode 100644 index 0000000..dc13b5e --- /dev/null +++ b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/ProxyRequestContext.groovy @@ -0,0 +1,46 @@ +package edu.wisc.my.restproxy + +import groovy.transform.Canonical; +import groovy.transform.CompileStatic +import groovy.transform.builder.Builder +import groovy.transform.builder.SimpleStrategy; +import org.springframework.http.HttpMethod; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; + +/** + * Java Bean representing all of the context about a REST Request this library is proxying. + * + * @author Nicholas Blair + */ +@Builder(builderStrategy = SimpleStrategy) +@Canonical +@CompileStatic +public class ProxyRequestContext { + + final String resourceKey; + HttpMethod httpMethod = HttpMethod.GET; + String uri; + String username; + String password; + Map attributes = new HashMap<>(); + Multimap headers = ArrayListMultimap.create(); + RequestBody requestBody; + + /** + * + * @param resourceKey required + */ + public ProxyRequestContext(String resourceKey) { + this.resourceKey = resourceKey; + } + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "ProxyRequestContext [resourceKey=${resourceKey}, httpMethod=${httpMethod}, uri=${uri}, username=${username}, password=${password != null ? '' : 'empty'}, attributes=${attributes}, headers=${headers}]" + } + +} diff --git a/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/RequestBody.groovy b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/RequestBody.groovy new file mode 100644 index 0000000..5b1c09d --- /dev/null +++ b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/RequestBody.groovy @@ -0,0 +1,16 @@ +package edu.wisc.my.restproxy + +import groovy.transform.Canonical +import groovy.transform.CompileStatic +import groovy.transform.builder.Builder +import groovy.transform.builder.SimpleStrategy; + +@Builder(builderStrategy = SimpleStrategy) +@Canonical +@CompileStatic +public class RequestBody { + + byte[] body; + String contentType; + +} diff --git a/src/main/java/edu/wisc/my/restproxy/config/RestProxyConfiguration.java b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/config/RestProxyConfiguration.groovy similarity index 72% rename from src/main/java/edu/wisc/my/restproxy/config/RestProxyConfiguration.java rename to rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/config/RestProxyConfiguration.groovy index 11b5576..a4fcf7f 100644 --- a/src/main/java/edu/wisc/my/restproxy/config/RestProxyConfiguration.java +++ b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/config/RestProxyConfiguration.groovy @@ -1,22 +1,21 @@ -/** - * - */ -package edu.wisc.my.restproxy.config; +package edu.wisc.my.restproxy.config +import groovy.transform.CompileStatic; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; /** * {@link Configuration} activating necessary REST proxy services. - * + * * To use this class, simply {@link Import} it with the rest of your configuration. * It's strongly suggested that your configuration provide a {@link org.springframework.web.client.RestTemplate} bean, but not required. - * + * * @author Nicholas Blair */ +@CompileStatic +@ComponentScan(value = ["edu.wisc.my.restproxy.dao", "edu.wisc.my.restproxy.service", "edu.wisc.my.restproxy.web"]) @Configuration -@ComponentScan(value = {"edu.wisc.my.restproxy.dao", "edu.wisc.my.restproxy.service", "edu.wisc.my.restproxy.web" }) public class RestProxyConfiguration { } diff --git a/src/main/java/edu/wisc/my/restproxy/dao/RestProxyDao.java b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/dao/RestProxyDao.groovy similarity index 82% rename from src/main/java/edu/wisc/my/restproxy/dao/RestProxyDao.java rename to rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/dao/RestProxyDao.groovy index 7d56ff2..ead6971 100644 --- a/src/main/java/edu/wisc/my/restproxy/dao/RestProxyDao.java +++ b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/dao/RestProxyDao.groovy @@ -1,17 +1,16 @@ -/** - * - */ -package edu.wisc.my.restproxy.dao; +package edu.wisc.my.restproxy.dao +import groovy.transform.CompileStatic; import org.springframework.http.ResponseEntity; import edu.wisc.my.restproxy.ProxyRequestContext; /** * Data access interface for talking with a REST API. - * + * * @author Nicholas Blair */ +@CompileStatic public interface RestProxyDao { /** diff --git a/src/main/java/edu/wisc/my/restproxy/dao/RestProxyDaoImpl.java b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/dao/RestProxyDaoImpl.groovy similarity index 98% rename from src/main/java/edu/wisc/my/restproxy/dao/RestProxyDaoImpl.java rename to rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/dao/RestProxyDaoImpl.groovy index 5c87575..a0d80ee 100644 --- a/src/main/java/edu/wisc/my/restproxy/dao/RestProxyDaoImpl.java +++ b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/dao/RestProxyDaoImpl.groovy @@ -1,6 +1,3 @@ -/** - * - */ package edu.wisc.my.restproxy.dao; import java.util.Map.Entry; @@ -21,20 +18,20 @@ /** * {@link RestProxyDao} implementation backed by a {@link RestTemplate}. - * + * * A default {@link RestTemplate} instance is provided, but consumers are strongly recommended to * configure their own instance and inject. However, this class will always use * {@link RestProxyResponseErrorHandler} because it's the client's responsiblity to deal with * errors. - * + * * @author Nicholas Blair */ @Service public class RestProxyDaoImpl implements RestProxyDao, InitializingBean { - + @Autowired(required=false) private RestTemplate restTemplate = new RestTemplate(); - + /* (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ @@ -42,7 +39,7 @@ public class RestProxyDaoImpl implements RestProxyDao, InitializingBean { public void afterPropertiesSet() throws Exception { this.restTemplate.setErrorHandler(new RestProxyResponseErrorHandler()); }; - + private static final Logger logger = LoggerFactory.getLogger(RestProxyDaoImpl.class); /* (non-Javadoc) * @see edu.wisc.my.restproxy.dao.RestProxyDao#proxyRequest(edu.wisc.my.restproxy.ProxyRequestContext) @@ -59,13 +56,13 @@ public ResponseEntity proxyRequest(ProxyRequestContext context) { String base64Creds = new String(base64CredsBytes); headers.add("Authorization", "Basic " + base64Creds); } - + for(Entry entry: context.getHeaders().entries()) { headers.add(entry.getKey(), entry.getValue()); } - + HttpEntity request = context.getRequestBody() == null ? new HttpEntity(headers) : new HttpEntity(context.getRequestBody().getBody(), headers); - ResponseEntity response = restTemplate.exchange(context.getUri(), + ResponseEntity response = restTemplate.exchange(context.getUri(), context.getHttpMethod(), request, Object.class, context.getAttributes()); logger.trace("completed request for {}, response= {}", context, response); return response; diff --git a/src/main/java/edu/wisc/my/restproxy/dao/RestProxyResponseErrorHandler.java b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/dao/RestProxyResponseErrorHandler.groovy similarity index 90% rename from src/main/java/edu/wisc/my/restproxy/dao/RestProxyResponseErrorHandler.java rename to rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/dao/RestProxyResponseErrorHandler.groovy index 953ac4b..4a3513a 100644 --- a/src/main/java/edu/wisc/my/restproxy/dao/RestProxyResponseErrorHandler.java +++ b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/dao/RestProxyResponseErrorHandler.groovy @@ -1,10 +1,6 @@ -/** - * - */ -package edu.wisc.my.restproxy.dao; - -import java.io.IOException; +package edu.wisc.my.restproxy.dao +import groovy.transform.CompileStatic; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpResponse; import org.springframework.web.client.ResponseErrorHandler; @@ -12,18 +8,19 @@ /** * {@link ResponseErrorHandler} implementation that does nothing and considers every * {@link ClientHttpRequest} a success. - * - * This class does nothing because RestProxy is responsible soley for relaying requests and + * + * This class does nothing because RestProxy is responsible solely for relaying requests and * responses. We don't care what's in the response, we just forward it on. It's up to the client to deal * with responses, whether they're successes or errors. - * + * * @author Collin Cudd */ +@CompileStatic public class RestProxyResponseErrorHandler implements ResponseErrorHandler { /* * (non-Javadoc) - * + * * @see * org.springframework.web.client.ResponseErrorHandler#handleError(org.springframework.http.client * .ClientHttpResponse) diff --git a/src/main/java/edu/wisc/my/restproxy/service/RestProxyService.java b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/service/RestProxyService.groovy similarity index 83% rename from src/main/java/edu/wisc/my/restproxy/service/RestProxyService.java rename to rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/service/RestProxyService.groovy index 5e26673..26b65cd 100644 --- a/src/main/java/edu/wisc/my/restproxy/service/RestProxyService.java +++ b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/service/RestProxyService.groovy @@ -1,7 +1,6 @@ -/** - * - */ -package edu.wisc.my.restproxy.service; +package edu.wisc.my.restproxy.service + +import groovy.transform.CompileStatic; import javax.servlet.http.HttpServletRequest; @@ -11,14 +10,15 @@ /** * Service interface for proxying a REST API. - * + * * @see ProxyRequestContext * @author Nicholas Blair */ +@CompileStatic public interface RestProxyService { /** - * + * * @param resourceKey * @param request * @return the {@link ResponseEntity} returned from the REST API (may return null) diff --git a/src/main/java/edu/wisc/my/restproxy/service/RestProxyServiceImpl.java b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/service/RestProxyServiceImpl.groovy similarity index 94% rename from src/main/java/edu/wisc/my/restproxy/service/RestProxyServiceImpl.java rename to rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/service/RestProxyServiceImpl.groovy index cf7c80b..c0d888f 100644 --- a/src/main/java/edu/wisc/my/restproxy/service/RestProxyServiceImpl.java +++ b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/service/RestProxyServiceImpl.groovy @@ -1,10 +1,6 @@ -/** - * - */ -package edu.wisc.my.restproxy.service; +package edu.wisc.my.restproxy.service -import java.io.IOException; -import java.io.InputStream; +import groovy.transform.CompileStatic; import javax.servlet.http.HttpServletRequest; @@ -31,6 +27,7 @@ * * @author Nicholas Blair */ +@CompileStatic @Service public class RestProxyServiceImpl implements RestProxyService { @@ -41,8 +38,8 @@ public class RestProxyServiceImpl implements RestProxyService { private static final Logger logger = LoggerFactory.getLogger(RestProxyServiceImpl.class); /** - * Visible for testing. - * + * Visible for testing. + * * @param env the env to set */ void setEnv(Environment env) { @@ -50,26 +47,26 @@ void setEnv(Environment env) { } /** * {@inheritDoc} - * + * * Inspects the {@link Environment} for necessary properties about the target API: *
    *
  • Resource root URI
  • *
  • Credentials
  • *
- * + * * Delegates to {@link RestProxyDao#proxyRequest(ProxyRequestContext)} - * + * * @see KeyUtils#getProxyHeaders(Environment, String, HttpServletRequest) */ @Override public ResponseEntity proxyRequest(final String resourceKey, final HttpServletRequest request) { - final String resourceRoot = env.getProperty(resourceKey + ".uri"); + final String resourceRoot = env.getProperty(resourceKey + ".uri"); if(StringUtils.isBlank(resourceRoot)) { logger.info("unknown resourceKey {}", resourceKey); return null; } StringBuilder uri = new StringBuilder(resourceRoot); - + String resourcePath = (String) request.getAttribute( HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ); if(StringUtils.isNotBlank(resourcePath)) { if(resourcePath.startsWith("/"+resourceKey)) { @@ -80,7 +77,7 @@ public ResponseEntity proxyRequest(final String resourceKey, final HttpS } uri.append(resourcePath); } - + if(StringUtils.isNotBlank(request.getQueryString())) { uri.append("?"); uri.append(request.getQueryString()); @@ -97,7 +94,7 @@ public ResponseEntity proxyRequest(final String resourceKey, final HttpS .setUri(uri.toString()) .setUsername(username); - RequestBody requestBody = null; + RequestBody requestBody; try { InputStream inputStream = request.getInputStream(); final String contentType = request.getContentType(); @@ -105,18 +102,18 @@ public ResponseEntity proxyRequest(final String resourceKey, final HttpS if(inputStream != null && contentLength > 0) { requestBody = new RequestBody() .setBody(FileCopyUtils.copyToByteArray(inputStream)); - + if(StringUtils.isNotBlank(contentType)) { requestBody.setContentType(contentType); } - + context.setRequestBody(requestBody) .getHeaders().put(HttpHeaders.CONTENT_TYPE, contentType); } } catch (IOException e) { logger.debug("caught IOException attempting to check request inputStream, no requestBody provided", e); } - + logger.debug("proxying request {}", context); return proxyDao.proxyRequest(context); } diff --git a/src/main/java/edu/wisc/my/restproxy/web/ResourceProxyController.java b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/web/ResourceProxyController.groovy similarity index 90% rename from src/main/java/edu/wisc/my/restproxy/web/ResourceProxyController.java rename to rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/web/ResourceProxyController.groovy index 3d7ea22..538aeb5 100644 --- a/src/main/java/edu/wisc/my/restproxy/web/ResourceProxyController.java +++ b/rest-proxy-core/src/main/groovy/edu/wisc/my/restproxy/web/ResourceProxyController.groovy @@ -1,7 +1,6 @@ -/** - * - */ -package edu.wisc.my.restproxy.web; +package edu.wisc.my.restproxy.web + +import groovy.transform.CompileStatic; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -20,9 +19,10 @@ /** * {@link RestController} for proxying other REST resources. - * + * * @author Nicholas Blair */ +@CompileStatic @Controller public class ResourceProxyController { @@ -42,22 +42,22 @@ void setEnv(Environment env) { * Proxies the request and then calls {@link HttpServletResponse#setStatus(int)} with the * {@link HttpStatus} recieved. If the proxy response contains content it's simply returned here * as an {@link Object}. - * + * * @param request * @param response * @param key * @return the body of the proxy response or null. */ @RequestMapping("/{key}/**") - public @ResponseBody Object proxyResource(HttpServletRequest request, + public @ResponseBody Object proxyResource(HttpServletRequest request, HttpServletResponse response, @PathVariable String key) { - ResponseEntity responseEntity = proxyService.proxyRequest(key, request); + ResponseEntity responseEntity = proxyService.proxyRequest(key, request); if(responseEntity == null || responseEntity.getStatusCode() == null) { response.setStatus(HttpStatus.NOT_FOUND.value()); return null; } response.setStatus(responseEntity.getStatusCode().value()); - return responseEntity.hasBody() ? responseEntity.getBody() : null; + return responseEntity.hasBody() ? responseEntity.getBody() : null; } } diff --git a/src/main/resources/.gitignore b/rest-proxy-core/src/main/resources/.gitignore similarity index 100% rename from src/main/resources/.gitignore rename to rest-proxy-core/src/main/resources/.gitignore diff --git a/src/main/resources/endpoint.properties.example b/rest-proxy-core/src/main/resources/endpoint.properties.example similarity index 87% rename from src/main/resources/endpoint.properties.example rename to rest-proxy-core/src/main/resources/endpoint.properties.example index 50f6370..6768697 100644 --- a/src/main/resources/endpoint.properties.example +++ b/rest-proxy-core/src/main/resources/endpoint.properties.example @@ -2,7 +2,7 @@ #key.username : the username to login to service (basic auth) * #key.password : the password for the service (basic auth) * #key.attributes : the csv of attributes -#key.proxyHeaders : a comma separated list of headers to add output. Can put placeholders for values to get local request attributes. +#key.proxyHeaders : a comma separated list of headers to add output. Can put placeholders for values to get local request attributes. #key.cache : how long to cache the information for that URI (with variables replaced) - not implemented yet # # * : not required @@ -29,4 +29,4 @@ uwmadisonreddit.attributes= someservice.uri=http://somewhere.wisc.edu/foo someservice.username=user someservice.password=pass -someservice.proxyHeaders=On-Behalf-Of: {wiscedupvi},Some-Other-Header: staticvalue \ No newline at end of file +someservice.proxyHeaders=On-Behalf-Of: {wiscedupvi},Some-Other-Header: staticvalue diff --git a/src/test/java/edu/wisc/my/restproxy/KeyUtilsTest.java b/rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/KeyUtilsTest.groovy similarity index 99% rename from src/test/java/edu/wisc/my/restproxy/KeyUtilsTest.java rename to rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/KeyUtilsTest.groovy index d40d832..df6c69e 100644 --- a/src/test/java/edu/wisc/my/restproxy/KeyUtilsTest.java +++ b/rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/KeyUtilsTest.groovy @@ -1,6 +1,3 @@ -/** - * - */ package edu.wisc.my.restproxy; import static org.junit.Assert.assertEquals; @@ -17,7 +14,7 @@ /** * Tests for {@link KeyUtils}. - * + * * @author Nicholas Blair */ public class KeyUtilsTest { diff --git a/src/test/java/edu/wisc/my/restproxy/ValidationResult.java b/rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/ValidationResult.groovy similarity index 79% rename from src/test/java/edu/wisc/my/restproxy/ValidationResult.java rename to rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/ValidationResult.groovy index e93a91e..4b08daf 100644 --- a/src/test/java/edu/wisc/my/restproxy/ValidationResult.java +++ b/rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/ValidationResult.groovy @@ -1,16 +1,14 @@ -/** - * - */ package edu.wisc.my.restproxy; /** - * Just an example of an object that could be retruned by rest api. + * Just an example of an object that could be returned by rest api. * @author Collin Cudd */ public class ValidationResult { boolean success; String message; + /** * @param success * @param message @@ -19,5 +17,5 @@ public ValidationResult(boolean success, String message) { this.success = success; this.message = message; } - + } diff --git a/src/test/java/edu/wisc/my/restproxy/dao/RestProxyDaoImplTest.java b/rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/dao/RestProxyDaoImplTest.groovy similarity index 87% rename from src/test/java/edu/wisc/my/restproxy/dao/RestProxyDaoImplTest.java rename to rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/dao/RestProxyDaoImplTest.groovy index f30cc8f..7762358 100644 --- a/src/test/java/edu/wisc/my/restproxy/dao/RestProxyDaoImplTest.java +++ b/rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/dao/RestProxyDaoImplTest.groovy @@ -1,7 +1,4 @@ -/** - * - */ -package edu.wisc.my.restproxy.dao; +package edu.wisc.my.restproxy.dao import static org.junit.Assert.assertEquals; @@ -22,11 +19,13 @@ import org.springframework.web.client.RestTemplate; import edu.wisc.my.restproxy.KeyUtils; -import edu.wisc.my.restproxy.ProxyRequestContext; +import edu.wisc.my.restproxy.ProxyRequestContext + +import static org.mockito.Mockito.when; /** * Tests for {@link RestProxyDaoImpl}. - * + * * @author Collin Cudd */ @RunWith(MockitoJUnitRunner.class) @@ -35,10 +34,10 @@ public class RestProxyDaoImplTest { private MockEnvironment env = new MockEnvironment(); @Mock private RestTemplate restTemplate; @InjectMocks private RestProxyDaoImpl proxyDao = new RestProxyDaoImpl(); - + @Mock ResponseEntity expectedResponse; - + /** * @return {@link ProxyRequestContext}. */ @@ -46,7 +45,7 @@ protected ProxyRequestContext getContext() { String resourceKey = "proxytest"; MockHttpServletRequest request = new MockHttpServletRequest(); request.setMethod("GET"); - + ProxyRequestContext context = new ProxyRequestContext(resourceKey) .setAttributes(KeyUtils.getHeaders(env, request, resourceKey)) .setHttpMethod(HttpMethod.valueOf(request.getMethod())) @@ -54,10 +53,10 @@ protected ProxyRequestContext getContext() { .setHeaders(KeyUtils.getProxyHeaders(env, resourceKey, request)) .setUri("localhost:8080/foo") .setUsername("foouser"); - + return context; } - + /** * Control test for {@link RestProxyDaoImpl#proxyRequest(ProxyRequestContext)} */ @@ -72,26 +71,26 @@ public void proxyRequest_control() { byte[] base64CredsBytes = Base64.encodeBase64(creds.getBytes()); String base64Creds = new String(base64CredsBytes); headers.add("Authorization", "Basic " + base64Creds); - + HttpEntity expectedRequest = new HttpEntity(headers); - Mockito.when( + when( restTemplate.exchange( - Matchers.eq(context.getUri()), - Matchers.eq(context.getHttpMethod()), + Matchers.eq(context.getUri()), + Matchers.eq(context.getHttpMethod()), Matchers.eq(expectedRequest), - Matchers.eq(Object.class), + (Class)Matchers.anyObject(), Matchers.eq(context.getAttributes()) ) ).thenReturn(expectedResponse); Object proxyResponse = proxyDao.proxyRequest(context); Mockito.verify(restTemplate).exchange( - Matchers.eq(context.getUri()), - Matchers.eq(context.getHttpMethod()), + Matchers.eq(context.getUri()), + Matchers.eq(context.getHttpMethod()), Matchers.eq(expectedRequest), - Matchers.eq(Object.class), + (Class)Matchers.anyObject(), Matchers.eq(context.getAttributes()) ); assertEquals(expectedResponse, proxyResponse); - } + } } diff --git a/src/test/java/edu/wisc/my/restproxy/service/RestProxyServiceImplTest.java b/rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/service/RestProxyServiceImplTest.groovy similarity index 97% rename from src/test/java/edu/wisc/my/restproxy/service/RestProxyServiceImplTest.java rename to rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/service/RestProxyServiceImplTest.groovy index e0b05aa..70d031c 100644 --- a/src/test/java/edu/wisc/my/restproxy/service/RestProxyServiceImplTest.java +++ b/rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/service/RestProxyServiceImplTest.groovy @@ -1,6 +1,3 @@ -/** - * - */ package edu.wisc.my.restproxy.service; import static org.junit.Assert.assertEquals; @@ -28,7 +25,7 @@ /** * Tests for {@link RestProxyServiceImpl}. - * + * * @author Nicholas Blair */ @RunWith(MockitoJUnitRunner.class) @@ -37,7 +34,7 @@ public class RestProxyServiceImplTest { private MockEnvironment env = new MockEnvironment(); @Mock private RestProxyDao proxyDao; @InjectMocks private RestProxyServiceImpl proxy = new RestProxyServiceImpl(); - + @Before public void setup() { proxy.setEnv(env); @@ -49,7 +46,7 @@ public void setup() { @Test public void proxyRequest_control() { final ResponseEntity result = new ResponseEntity(new Object(), HttpStatus.OK); - + MockHttpServletRequest request = new MockHttpServletRequest(); request.setMethod("GET"); request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/control/foo"); @@ -57,15 +54,15 @@ public void proxyRequest_control() { //note the resourceKey ('control' in this context) is stripped from the uri ProxyRequestContext expected = new ProxyRequestContext("control").setUri("http://destination/foo"); - + when(proxyDao.proxyRequest(expected)).thenReturn(result); assertEquals(result, proxy.proxyRequest("control", request)); } - + @Test public void withQueryString() { final ResponseEntity result = new ResponseEntity(new Object(), HttpStatus.OK); - + MockHttpServletRequest request = new MockHttpServletRequest(); request.setMethod("GET"); request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/control/foo"); @@ -74,14 +71,14 @@ public void withQueryString() { //note the resourceKey ('control' in this context) is stripped from the uri ProxyRequestContext expected = new ProxyRequestContext("control").setUri("http://destination/foo?search=bar&name=bucky"); - + when(proxyDao.proxyRequest(expected)).thenReturn(result); assertEquals(result, proxy.proxyRequest("control", request)); } /** - * Test simulates a proxy request which fails with a http 400 error. + * Test simulates a proxy request which fails with a http 400 error. * An error like this could be encountered if you were to post invalid data to a form. - * Test verifies the HttpStatus AND the body (which likely contins validation error message) are passed back to the client. + * Test verifies the HttpStatus AND the body (which likely contains validation error message) are passed back to the client. */ @Test public void proxyRequest_failsWithBadRequest() { @@ -98,7 +95,7 @@ public void proxyRequest_failsWithBadRequest() { assertEquals(expectedResult, result); assertEquals(validationFailure, result.getBody()); } - + /** * Experiment for {@link RestProxyServiceImpl#proxyRequest(String, HttpServletRequest)}, confirms * expected behavior when the configuration contains credentials. @@ -106,7 +103,7 @@ public void proxyRequest_failsWithBadRequest() { @Test public void proxyRequest_withCredentials() { final ResponseEntity result = new ResponseEntity(new Object(), HttpStatus.OK); - + MockHttpServletRequest request = new MockHttpServletRequest(); request.setMethod("GET"); env.setProperty("withCredentials.uri", "http://localhost/foo"); @@ -114,11 +111,11 @@ public void proxyRequest_withCredentials() { env.setProperty("withCredentials.password", "pass"); ProxyRequestContext expected = new ProxyRequestContext("withCredentials").setUri("http://localhost/foo") .setUsername("user").setPassword("pass"); - + when(proxyDao.proxyRequest(expected)).thenReturn(result); assertEquals(result, proxy.proxyRequest("withCredentials", request)); } - + /** * Experiment for {@link RestProxyServiceImpl#proxyRequest(String, HttpServletRequest)}, confirms * expected behavior when the configuration contains a request for additional headers with static values. @@ -126,7 +123,7 @@ public void proxyRequest_withCredentials() { @Test public void proxyRequest_withAdditionalHeader() { final ResponseEntity result = new ResponseEntity(new Object(), HttpStatus.OK); - + MockHttpServletRequest request = new MockHttpServletRequest(); request.setAttribute("wiscedupvi", "UW111A111"); request.setMethod("GET"); @@ -134,7 +131,7 @@ public void proxyRequest_withAdditionalHeader() { env.setProperty("withAdditionalHeaders.proxyHeaders", "Some-Header: staticvalue"); ProxyRequestContext expected = new ProxyRequestContext("withAdditionalHeaders").setUri("http://localhost/foo"); expected.getHeaders().put("Some-Header", "staticvalue"); - + when(proxyDao.proxyRequest(expected)).thenReturn(result); assertEquals(result, proxy.proxyRequest("withAdditionalHeaders", request)); } @@ -146,7 +143,7 @@ public void proxyRequest_withAdditionalHeader() { @Test public void proxyRequest_withAdditionalHeaders_andPlaceholders() { final ResponseEntity result = new ResponseEntity(new Object(), HttpStatus.OK); - + MockHttpServletRequest request = new MockHttpServletRequest(); request.setAttribute("wiscedupvi", "UW111A111"); request.setMethod("GET"); @@ -154,11 +151,11 @@ public void proxyRequest_withAdditionalHeaders_andPlaceholders() { env.setProperty("withAdditionalHeaders2.proxyHeaders", "On-Behalf-Of: {wiscedupvi}"); ProxyRequestContext expected = new ProxyRequestContext("withAdditionalHeaders2").setUri("http://localhost/foo"); expected.getHeaders().put("On-Behalf-Of", "UW111A111"); - + when(proxyDao.proxyRequest(expected)).thenReturn(result); assertEquals(result, proxy.proxyRequest("withAdditionalHeaders2", request)); } - + /** * Experiment for {@link RestProxyServiceImpl#proxyRequest(String, HttpServletRequest)}, confirms * expected behavior when the request path contains additional fragments. @@ -166,13 +163,13 @@ public void proxyRequest_withAdditionalHeaders_andPlaceholders() { @Test public void proxyRequest_withAdditionalPath() { final ResponseEntity result = new ResponseEntity(new Object(), HttpStatus.OK); - + MockHttpServletRequest request = new MockHttpServletRequest(); request.setMethod("GET"); request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "api/v2/employee/123"); env.setProperty("withAdditionalPath.uri", "http://localhost/foo"); ProxyRequestContext expected = new ProxyRequestContext("withAdditionalPath").setUri("http://localhost/foo/api/v2/employee/123"); - + when(proxyDao.proxyRequest(expected)).thenReturn(result); assertEquals(result, proxy.proxyRequest("withAdditionalPath", request)); } @@ -181,7 +178,7 @@ public void proxyRequest_withAdditionalPath() { * where the request has a 'application/json' body. */ @Test - public void proxyRequest_withRequestBody() { + public void proxyRequest_withRequestBody() { MockHttpServletRequest request = new MockHttpServletRequest(); request.setMethod("PUT"); request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/withRequestBody/foo"); @@ -197,7 +194,7 @@ public void proxyRequest_withRequestBody() { * where the request has a body but not the 'application/json' content-type. */ @Test - public void proxyRequest_withRequestBody_notjson() { + public void proxyRequest_withRequestBody_notjson() { MockHttpServletRequest request = new MockHttpServletRequest(); request.setMethod("PUT"); request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/notjson/foo"); diff --git a/src/test/java/edu/wisc/my/restproxy/web/ResourceProxyControllerTest.java b/rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/web/ResourceProxyControllerTest.groovy similarity index 100% rename from src/test/java/edu/wisc/my/restproxy/web/ResourceProxyControllerTest.java rename to rest-proxy-core/src/test/groovy/edu/wisc/my/restproxy/web/ResourceProxyControllerTest.groovy diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..63ff200 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = 'rest-proxy-parent' +include 'rest-proxy-boot' +include 'rest-proxy-core' diff --git a/src/main/java/edu/wisc/my/restproxy/ProxyRequestContext.java b/src/main/java/edu/wisc/my/restproxy/ProxyRequestContext.java deleted file mode 100644 index 7df3c3e..0000000 --- a/src/main/java/edu/wisc/my/restproxy/ProxyRequestContext.java +++ /dev/null @@ -1,207 +0,0 @@ -/** - * - */ -package edu.wisc.my.restproxy; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.http.HttpMethod; - -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; - -/** - * Java Bean representing all of the context about a REST Request this library is proxying. - * - * @author Nicholas Blair - */ -public class ProxyRequestContext { - - private final String resourceKey; - private HttpMethod httpMethod = HttpMethod.GET; - private String uri; - private String username; - private String password; - private Map attributes = new HashMap<>(); - private Multimap headers = ArrayListMultimap.create(); - private RequestBody requestBody; - /** - * - * @param resourceKey required - */ - public ProxyRequestContext(String resourceKey) { - this.resourceKey = resourceKey; - } - /** - * @return the resourceKey - */ - public String getResourceKey() { - return resourceKey; - } - /** - * Defaults to {@link HttpMethod#GET} if not set explicitly. - * - * @return the httpMethod - */ - public HttpMethod getHttpMethod() { - return httpMethod; - } - /** - * @param httpMethod the httpMethod to set - */ - public ProxyRequestContext setHttpMethod(HttpMethod httpMethod) { - this.httpMethod = httpMethod; - return this; - } - /** - * @return the the full URI (including scheme, host, port, path) - */ - public String getUri() { - return uri; - } - /** - * @param uri the full URI (including scheme, host, port, path) - */ - public ProxyRequestContext setUri(String uri) { - this.uri = uri; - return this; - } - /** - * @return the username - */ - public String getUsername() { - return username; - } - /** - * @param username the username to set - */ - public ProxyRequestContext setUsername(String username) { - this.username = username; - return this; - } - /** - * @return the password - */ - public String getPassword() { - return password; - } - /** - * @param password the password to set - */ - public ProxyRequestContext setPassword(String password) { - this.password = password; - return this; - } - /** - * @return the attributes - */ - public Map getAttributes() { - return attributes; - } - /** - * @param attributes the attributes to set - */ - public ProxyRequestContext setAttributes(Map attributes) { - this.attributes = attributes; - return this; - } - /** - * @return the headers - */ - public Multimap getHeaders() { - return headers; - } - /** - * @param headers the headers to set - */ - public ProxyRequestContext setHeaders(Multimap headers) { - this.headers = headers; - return this; - } - /** - * @return the requestBody - */ - public RequestBody getRequestBody() { - return requestBody; - } - /** - * @param requestBody the requestBody to set - */ - public ProxyRequestContext setRequestBody(RequestBody requestBody) { - this.requestBody = requestBody; - return this; - } - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "ProxyRequestContext [resourceKey=" + resourceKey + ", httpMethod=" + httpMethod - + ", uri=" + uri + ", username=" + username + ", password=" + ( password != null ? "" : "empty") - + ", attributes=" + attributes + ", headers=" + headers + "]"; - } - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((attributes == null) ? 0 : attributes.hashCode()); - result = prime * result + ((headers == null) ? 0 : headers.hashCode()); - result = prime * result + ((httpMethod == null) ? 0 : httpMethod.hashCode()); - result = prime * result + ((password == null) ? 0 : password.hashCode()); - result = prime * result + ((resourceKey == null) ? 0 : resourceKey.hashCode()); - result = prime * result + ((uri == null) ? 0 : uri.hashCode()); - result = prime * result + ((username == null) ? 0 : username.hashCode()); - return result; - } - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ProxyRequestContext other = (ProxyRequestContext) obj; - if (attributes == null) { - if (other.attributes != null) - return false; - } else if (!attributes.equals(other.attributes)) - return false; - if (headers == null) { - if (other.headers != null) - return false; - } else if (!headers.equals(other.headers)) - return false; - if (httpMethod != other.httpMethod) - return false; - if (password == null) { - if (other.password != null) - return false; - } else if (!password.equals(other.password)) - return false; - if (resourceKey == null) { - if (other.resourceKey != null) - return false; - } else if (!resourceKey.equals(other.resourceKey)) - return false; - if (uri == null) { - if (other.uri != null) - return false; - } else if (!uri.equals(other.uri)) - return false; - if (username == null) { - if (other.username != null) - return false; - } else if (!username.equals(other.username)) - return false; - return true; - } - -} diff --git a/src/main/java/edu/wisc/my/restproxy/RequestBody.java b/src/main/java/edu/wisc/my/restproxy/RequestBody.java deleted file mode 100644 index c7fdf7b..0000000 --- a/src/main/java/edu/wisc/my/restproxy/RequestBody.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * - */ -package edu.wisc.my.restproxy; - -/** - * Bean to represent a request body. - * - * @author Nicholas Blair - */ -public class RequestBody { - - private byte[] body; - private String contentType; - /** - * @return the body - */ - public byte[] getBody() { - return body; - } - /** - * @param body the body to set - */ - public RequestBody setBody(byte[] body) { - this.body = body; - return this; - } - /** - * @return the contentType - */ - public String getContentType() { - return contentType; - } - /** - * @param contentType the contentType to set - */ - public RequestBody setContentType(String contentType) { - this.contentType = contentType; - return this; - } - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "RequestBody [body=" + body + ", contentType=" + contentType + "]"; - } -}