Shrink Cloud Foundry Connector Footprint

Previously, the Cloud Foundry Connector utilized Jackson for parsing the
VCAP_SERVICES JSON payload.  While Jackson should be the default choice for
most JSON parsing, the fact that the project does not need Object binding
means that it is overkill for the need.  In addition, since whichever JSON
parser is chosen must be included in the distributable JAR and not shared with
the rest of the application (which is likely to have its own version of
Jackson) the size of the Jackson libraries becomes a significant concern.

This change updates the code to use the org.json:json parser and shrinks the
spring-cloud-cloudfoundry-connector from 1.2M to 84K with no difference in
functionality.

[resolves #73]
This commit is contained in:
Ben Hale
2017-11-04 10:15:39 -07:00
parent 8145a53f1f
commit f3d76237f9
4 changed files with 15 additions and 21 deletions

View File

@@ -13,21 +13,20 @@ apply plugin: 'com.github.johnrengelman.shadow'
apply from: "publish-maven.gradle"
ext {
jacksonVersion = "2.3.3"
jsonVersion = "20171018"
}
dependencies {
compile project(':spring-cloud-connectors-core')
compile("com.fasterxml.jackson.core:jackson-core:$jacksonVersion")
compile("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
compile("org.json:json:$jsonVersion")
}
shadowJar {
classifier = null
dependencies {
include dependency('com.fasterxml.jackson.core:jackson-.*')
include dependency('org.json:json')
}
relocate 'com.fasterxml.jackson', 'org.springframework.cloud.cloudfoundry.com.fasterxml.jackson'
relocate 'org.json', 'org.springframework.cloud.cloudfoundry.org.json'
}
assemble.dependsOn shadowJar

View File

@@ -4,7 +4,10 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.json.JSONObject;
import org.springframework.cloud.AbstractCloudConnector;
import org.springframework.cloud.CloudException;
import org.springframework.cloud.FallbackServiceInfoCreator;
@@ -12,8 +15,6 @@ import org.springframework.cloud.app.ApplicationInstanceInfo;
import org.springframework.cloud.service.BaseServiceInfo;
import org.springframework.cloud.util.EnvironmentAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
*
* @author Ramnivas Laddad
@@ -21,7 +22,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
*/
public class CloudFoundryConnector extends AbstractCloudConnector<Map<String,Object>> {
private ObjectMapper objectMapper = new ObjectMapper();
private EnvironmentAccessor environment = new EnvironmentAccessor();
private ApplicationInstanceInfoCreator applicationInstanceInfoCreator = new ApplicationInstanceInfoCreator();
@@ -43,8 +43,8 @@ public class CloudFoundryConnector extends AbstractCloudConnector<Map<String,Obj
public ApplicationInstanceInfo getApplicationInstanceInfo() {
try {
@SuppressWarnings("unchecked")
Map<String, Object> rawApplicationInstanceInfo
= objectMapper.readValue(environment.getEnvValue("VCAP_APPLICATION"), Map.class);
Map<String, Object> rawApplicationInstanceInfo
= new JSONObject(environment.getEnvValue("VCAP_APPLICATION")).toMap();
return applicationInstanceInfoCreator.createApplicationInstanceInfo(rawApplicationInstanceInfo);
} catch (Exception e) {
throw new CloudException(e);
@@ -71,7 +71,8 @@ public class CloudFoundryConnector extends AbstractCloudConnector<Map<String,Obj
if (servicesString != null && servicesString.length() > 0) {
try {
rawServices = objectMapper.readValue(servicesString, CloudFoundryRawServiceData.class);
rawServices = new CloudFoundryRawServiceData(new JSONObject(servicesString).toMap().entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> (List<Map<String, Object>>) entry.getValue())));
} catch (Exception e) {
throw new CloudException(e);
}

View File

@@ -8,6 +8,7 @@ import java.util.List;
import java.util.Map;
import java.util.Scanner;
import org.json.JSONObject;
import org.junit.Before;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -15,8 +16,6 @@ import org.springframework.cloud.service.ServiceInfo;
import org.springframework.cloud.service.UriBasedServiceInfo;
import org.springframework.cloud.util.EnvironmentAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -36,8 +35,6 @@ public abstract class AbstractCloudFoundryConnectorTest {
protected static final int port = 1234;
protected static String username = "myuser";
protected static final String password = "mypass";
private static ObjectMapper objectMapper = new ObjectMapper();
@Before
public void setup() {
@@ -116,7 +113,7 @@ public abstract class AbstractCloudFoundryConnectorTest {
@SuppressWarnings("unchecked")
private static String getServiceLabel(String servicePayload) {
try {
Map<String, Object> serviceMap = objectMapper.readValue(servicePayload, Map.class);
Map<String, Object> serviceMap = new JSONObject(servicePayload).toMap();
return serviceMap.get("label").toString();
} catch (Exception e) {
return null;

View File

@@ -22,11 +22,10 @@ import static org.junit.Assert.*;
import java.util.List;
import java.util.Map;
import org.json.JSONObject;
import org.junit.Test;
import org.springframework.cloud.service.common.CassandraServiceInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Unit tests for link {@link CassandraServiceInfoCreator}.
*
@@ -34,8 +33,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
*/
public class CassandraServiceInfoCreatorTests extends AbstractCloudFoundryConnectorTest {
private ObjectMapper mapper = new ObjectMapper();
@Test
public void shouldCreateServiceInfo() throws Exception {
@@ -91,7 +88,7 @@ public class CassandraServiceInfoCreatorTests extends AbstractCloudFoundryConnec
}
private Map readServiceData(String resource) throws java.io.IOException {
return mapper.readValue(readTestDataFile(resource), Map.class);
return new JSONObject(readTestDataFile(resource)).toMap();
}
@SuppressWarnings("unchecked")