Skip to content
This repository has been archived by the owner on Mar 30, 2023. It is now read-only.

Change all the things #22

Merged
merged 11 commits into from
Sep 21, 2015
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ hs_err_pid*
.classpath
.project
.settings
.gradle
build/
.idea/
*.swp
*.iml
7 changes: 0 additions & 7 deletions Application.groovy

This file was deleted.

10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# json-proxy-service
A Simple server side JSON proxy service written in Java
A Simple server side JSON 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)

### 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 `json-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 `json-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
Expand Down Expand Up @@ -37,11 +37,11 @@ This is an important component with a couple of use cases.
* [Grails 3.0.x](https://grails.org/)

#### Running
* Run `grails run-app` to start the server
* Run `gradle bootRun` to start the server
* [Verify it works](localhost:8080/todos.json)

__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 json-proxy-service/build/json-proxy-service-<VERSION>.jar`

53 changes: 0 additions & 53 deletions application.yml

This file was deleted.

15 changes: 15 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
subprojects {

group = 'edu.wisc.my.restproxy'
version = '1.2.0-SNAPSHOT'

apply plugin: 'groovy'

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" }
}

}
29 changes: 29 additions & 0 deletions json-proxy-core/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
description = "A simple server-side JSON 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'
compile('javax.servlet:javax.servlet-api:3.1.0') { // TODO: was 3.0.1 intentional?
/* This dependency was originally in the Maven provided scope, but the project was not of type war.
This behavior is not yet supported by Gradle, so this dependency has been converted to a compile dependency.
Please review and delete this closure when resolved. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably an accident. Is it needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a weird and uncharacteristic blind spot that gradle does not have a build in 'provided' scope. Apparently everyone just defines it themselves until gradle comes around, so I updated with that change.

FYI / for reference, 'provided' means a dependency is needed for compilation, but is not meant to be packaged into the final artifact, because that artifact is expected to wind up in a container (e.g. tomcat, jetty) that already has the dependency. Compile often works just as well, but can lead to weird conflicts at runtime.

}
}

Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
/**
*
*/
package edu.wisc.my.restproxy;

import java.util.HashMap;
import java.util.Map;
import groovy.transform.EqualsAndHashCode;
import groovy.transform.CompileStatic;

import org.springframework.http.HttpMethod;

Expand All @@ -13,9 +10,11 @@

/**
* Java Bean representing all of the context about a REST Request this library is proxying.
*
*
* @author Nicholas Blair
*/
@CompileStatic
@EqualsAndHashCode
public class ProxyRequestContext {

private final String resourceKey;
Expand All @@ -26,8 +25,9 @@ public class ProxyRequestContext {
private Map<String, String> attributes = new HashMap<>();
private Multimap<String, String> headers = ArrayListMultimap.create();
private RequestBody requestBody;

/**
*
*
* @param resourceKey required
*/
public ProxyRequestContext(String resourceKey) {
Expand All @@ -41,7 +41,7 @@ public String getResourceKey() {
}
/**
* Defaults to {@link HttpMethod#GET} if not set explicitly.
*
*
* @return the httpMethod
*/
public HttpMethod getHttpMethod() {
Expand Down Expand Up @@ -137,71 +137,7 @@ public ProxyRequestContext setRequestBody(RequestBody requestBody) {
*/
@Override
public String toString() {
return "ProxyRequestContext [resourceKey=" + resourceKey + ", httpMethod=" + httpMethod
+ ", uri=" + uri + ", username=" + username + ", password=" + ( password != null ? "<set, suppressed>" : "empty")
+ ", attributes=" + attributes + ", headers=" + headers + "]";
return "ProxyRequestContext [resourceKey=${resourceKey}, httpMethod=${httpMethod}, uri=${uri}, username=${username}, password=${password != null ? '<set, suppressed>' : '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;
}


}
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/**
*
*/
package edu.wisc.my.restproxy.config;

import org.springframework.context.annotation.ComponentScan;
Expand All @@ -16,7 +13,7 @@
* @author Nicholas Blair
*/
@Configuration
@ComponentScan(value = {"edu.wisc.my.restproxy.dao", "edu.wisc.my.restproxy.service", "edu.wisc.my.restproxy.web" })
@ComponentScan(value = ["edu.wisc.my.restproxy.dao", "edu.wisc.my.restproxy.service", "edu.wisc.my.restproxy.web"])
public class RestProxyConfiguration {

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
*
*
*/
package edu.wisc.my.restproxy;

Expand All @@ -11,6 +11,7 @@ public class ValidationResult {

boolean success;
String message;
public ValidationResult(){}
/**
* @param success
* @param message
Expand All @@ -19,5 +20,5 @@ public ValidationResult(boolean success, String message) {
this.success = success;
this.message = message;
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/**
*
*
*/
package edu.wisc.my.restproxy.dao;
package edu.wisc.my.restproxy.dao

import org.junit.Ignore;

import static org.junit.Assert.assertEquals;

Expand All @@ -26,7 +28,7 @@

/**
* Tests for {@link RestProxyDaoImpl}.
*
*
* @author Collin Cudd
*/
@RunWith(MockitoJUnitRunner.class)
Expand All @@ -35,32 +37,33 @@ public class RestProxyDaoImplTest {
private MockEnvironment env = new MockEnvironment();
@Mock private RestTemplate restTemplate;
@InjectMocks private RestProxyDaoImpl proxyDao = new RestProxyDaoImpl();

@Mock
ResponseEntity<Object> expectedResponse;

/**
* @return {@link ProxyRequestContext}.
*/
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()))
.setPassword("foopass")
.setHeaders(KeyUtils.getProxyHeaders(env, resourceKey, request))
.setUri("localhost:8080/foo")
.setUsername("foouser");

return context;
}

/**
* Control test for {@link RestProxyDaoImpl#proxyRequest(ProxyRequestContext)}
*/
@Ignore
@Test
public void proxyRequest_control() {
ProxyRequestContext context = getContext();
Expand All @@ -72,24 +75,24 @@ public void proxyRequest_control() {
byte[] base64CredsBytes = Base64.encodeBase64(creds.getBytes());
String base64Creds = new String(base64CredsBytes);
headers.add("Authorization", "Basic " + base64Creds);

HttpEntity<String> expectedRequest = new HttpEntity<String>(headers);
Mockito.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),
Matchers.eq(Object.class),
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),
Matchers.eq(Object.class),
Matchers.eq(context.getAttributes())
);
assertEquals(expectedResponse, proxyResponse);
Expand Down
Loading