Skip to content

Commit 9047391

Browse files
committed
added utility class used to generate parameter whitelist
1 parent 3fd351a commit 9047391

File tree

3 files changed

+128
-2
lines changed

3 files changed

+128
-2
lines changed

README.md

+18-1
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,22 @@ Target jar will be created at: `build/lib`. Jar will be named: `aws-xray-paramet
4646

4747
It is possible to configure a custom parameter whitelist file instead of the default one provided with the package. This can be done either via a the environment variable: `AWS_XRAY_WHITELIST_URL` or the System property: `alt.aws.xray.whitelist.url`. The System property takes precedence over the environment variable. Value should be set to a resource path as specified by [Class.getResource()](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getResource-java.lang.String-). For example: `/com/myconpany/mypackage/MyParameterWhitelist.json`.
4848

49-
**Note**: If setting the System property programmatically, you need to set this before using the AWS SDK. The configuration is evaluated once upon first usage of the AWS SDK.
49+
**Note**: If setting the System property programmatically, you need to set this before using the AWS SDK. The configuration is evaluated once, upon first usage of the AWS SDK.
5050

51+
# Generating Your Own Parameter Whitelist
52+
53+
Source code includes a utility class which can be used to generate parameter whitelists for additional services. The class is under the test source tree and requires compiling the project from source to run. Class name: `com.github.functionalone.xray.handlers.GenerateParameterWhitelist`. The class uses parameters which are passed via java system properties. The following properties are used:
54+
55+
```
56+
gen.file: [output file name, default to whitelist.json]
57+
gen.class: <class to generate whitelist for, example: com.amazonaws.services.s3.AmazonS3Client'>
58+
gen.service: <service name, example: 'Amazon S3'>
59+
gen.params: <parameter names comma separated, example: BucketName,Key,VersionId,Prefix>
60+
gen.verbose: [true|false, default:false, will print more info on stdout regarding what is being done]
61+
```
62+
63+
There is a gradle task: `generateWhitelist` which can be used to run the class. For example the S3 parameter whitelist was generated using the following command line:
64+
65+
```
66+
./gradlew -Dgen.class=com.amazonaws.services.s3.AmazonS3Client -Dgen.service="Amazon S3" -Dgen.params=BucketName,Key,VersionId,Prefix,SourceBucketName,SourceKey,DestinationBucketName,DestinationKey generateWhitelist
67+
```

build.gradle

+11-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ dependencies {
3737
// Use JUnit test framework
3838
testImplementation (
3939
'junit:junit:4.12',
40-
'com.amazonaws:aws-java-sdk-dynamodb:1.11.259',
40+
'com.amazonaws:aws-java-sdk-dynamodb:1.11.268',
41+
'com.amazonaws:aws-java-sdk-kinesis:1.11.268',
4142
)
4243
}
4344

@@ -126,6 +127,15 @@ test {
126127
systemProperty "aws-xray-whitelist.s3-bucket", System.getProperty("aws-xray-whitelist.s3-bucket")
127128
}
128129

130+
task generateWhitelist (type:JavaExec) {
131+
132+
main = "com.github.functionalone.xray.handlers.GenerateParameterWhitelist"
133+
classpath = sourceSets.test.runtimeClasspath
134+
135+
/* Pass all system proprties*/
136+
systemProperties System.getProperties()
137+
}
138+
129139

130140

131141
jar {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.github.functionalone.xray.handlers;
2+
3+
import java.io.BufferedOutputStream;
4+
import java.io.File;
5+
import java.io.FileOutputStream;
6+
import java.lang.reflect.Method;
7+
import java.lang.reflect.Modifier;
8+
import java.util.ArrayList;
9+
import java.util.Arrays;
10+
import java.util.List;
11+
12+
import com.fasterxml.jackson.databind.ObjectMapper;
13+
import com.fasterxml.jackson.databind.node.ArrayNode;
14+
import com.fasterxml.jackson.databind.node.ObjectNode;
15+
16+
public class GenerateParameterWhitelist {
17+
18+
public static final String USAGE = "This program will generate a parameter whitelise based upon reflection. Paramaters are read from the System properties:\n"
19+
+ "gen.file: [output file name, default to whitelist.json]\n"
20+
+ "gen.class: <class to generate whitelist for, example: 'com.amazonaws.services.s3.AmazonS3Client'>\n"
21+
+ "gen.service: <service name, example: 'Amazon S3'>\n"
22+
+ "gen.params: <parameter names comma separated, example: BucketName,Key,VersionId,Prefix>\n"
23+
+ "gen.verbose: [true|false, default:false, will print more info on stdout regarding what is being done]";
24+
25+
private static String capitalizeFirst(String input) {
26+
return input.substring(0, 1).toUpperCase() + input.substring(1);
27+
}
28+
29+
private static boolean VERBOSE = false;
30+
31+
private static void debug(String msg) {
32+
if(VERBOSE) {
33+
System.out.println(msg);
34+
}
35+
}
36+
37+
/**
38+
* Uses system properties as parameters. See usage string.
39+
*
40+
* @param args
41+
*/
42+
public static void main(String[] args) throws Exception {
43+
String file = System.getProperty("gen.file", "whitelist.json"), serviceClass = System.getProperty("gen.class"),
44+
serviceName = System.getProperty("gen.service"), paramsStr = System.getProperty("gen.params");
45+
VERBOSE = Boolean.parseBoolean(System.getProperty("gen.verbose", "false"));
46+
if (null == serviceClass || null == serviceName || null == paramsStr) {
47+
System.err.println("\n\nMissing system parameters in order to run!!!\n\n" + USAGE);
48+
System.exit(1);
49+
return;
50+
}
51+
List<String> paramsList = Arrays.asList(paramsStr.split(","));
52+
File f = new File(file);
53+
ObjectMapper mapper = new ObjectMapper();
54+
ObjectNode root = (ObjectNode) mapper.createObjectNode();
55+
ObjectNode serviceNode = (ObjectNode) mapper.createObjectNode();
56+
root.put(serviceName, serviceNode);
57+
ObjectNode operations = (ObjectNode) mapper.createObjectNode();
58+
serviceNode.put("operations", operations);
59+
List<String> noParamMethods = new ArrayList<String>();
60+
Class cls = Class.forName(serviceClass);
61+
Method[] methods = cls.getDeclaredMethods();
62+
for (Method method : methods) {
63+
if (Modifier.isPublic(method.getModifiers())) {
64+
Class[] params = method.getParameterTypes();
65+
if (params.length == 1 && params[0].getName().endsWith("Request")) {
66+
Class p = params[0];
67+
debug("Processing Method: " + method.getName() + " with param: " + p.getSimpleName());
68+
Method[] paramMethods = p.getMethods();
69+
ObjectNode paramsNode = (ObjectNode) mapper.createObjectNode();
70+
ArrayNode request_parameters = (ArrayNode) mapper.createArrayNode();
71+
paramsNode.put("request_parameters", request_parameters);
72+
boolean hasParam = false;
73+
for (Method paramMethod : paramMethods) {
74+
String pName = paramMethod.getName();
75+
if (pName.startsWith("get")) {
76+
pName = pName.substring("get".length());
77+
if (paramsList.contains(pName)) {
78+
debug("\t param name: " + pName);
79+
hasParam = true;
80+
request_parameters.add(pName);
81+
}
82+
}
83+
}
84+
if (!hasParam) {
85+
noParamMethods.add(method.getName());
86+
} else {
87+
operations.put(capitalizeFirst(method.getName()), paramsNode);
88+
}
89+
}
90+
}
91+
}
92+
System.out.println("Methods without params: " + noParamMethods);
93+
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(f));
94+
bout.write(mapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(root));
95+
bout.close();
96+
System.out.println("Json paramter whitelist written to file: " + f.getAbsolutePath());
97+
}
98+
99+
}

0 commit comments

Comments
 (0)