Skip to content

Commit 2f3ec00

Browse files
authored
Merge pull request #320 from ibi-group/dev
Release
2 parents 821ea63 + b771ff9 commit 2f3ec00

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1446
-695
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ before_deploy:
8989
- ls target/*.jar
9090
# Copy packaged jar over to deploy dir.
9191
- cp target/dt-*.jar deploy/
92-
- cp target/dt-*.jar "deploy/dt-latest-BRANCH_CLEAN.jar"
92+
- cp target/dt-*.jar "deploy/dt-latest-$BRANCH_CLEAN.jar"
9393
deploy:
9494
provider: s3
9595
skip_cleanup: true

jmeter/amazon-linux-startup-script.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
yum install java-1.8.0 -y
55
yum remove java-1.7.0-openjdk -y
66

7+
source jmeter-version.sh
8+
79
# install jmeter
810
./install-jmeter.sh
911

1012
# TODO: update jmeter.properties file
1113
# http://www.testingdiaries.com/jmeter-on-aws/
1214

1315
# start up jmeter server
14-
apache-jmeter-3.3/bin/jmeter-server
16+
apache-jmeter-$JMETER_VER/bin/jmeter-server

jmeter/install-jmeter.sh

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
#!/bin/bash
22

3+
source jmeter-version.sh
4+
35
# install jmeter
4-
wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-3.3.zip
5-
unzip apache-jmeter-3.3.zip
6-
rm -rf apache-jmeter-3.3.zip
6+
wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-$JMETER_VER.zip
7+
unzip apache-jmeter-$JMETER_VER.zip
8+
rm -rf apache-jmeter-$JMETER_VER.zip
79

810
# install jmeter plugin manager
9-
wget -O apache-jmeter-3.3/lib/ext/jmeter-plugins-manager-0.16.jar https://jmeter-plugins.org/get/
11+
wget -O apache-jmeter-$JMETER_VER/lib/ext/jmeter-plugins-manager-0.16.jar https://jmeter-plugins.org/get/
1012

1113
# install command line runner
12-
wget -O apache-jmeter-3.3/lib/cmdrunner-2.0.jar http://search.maven.org/remotecontent?filepath=kg/apc/cmdrunner/2.0/cmdrunner-2.0.jar
14+
wget -O apache-jmeter-$JMETER_VER/lib/cmdrunner-2.0.jar https://search.maven.org/remotecontent?filepath=kg/apc/cmdrunner/2.0/cmdrunner-2.0.jar
1315

1416
# run jmeter to generate command line script
15-
java -cp apache-jmeter-3.3/lib/ext/jmeter-plugins-manager-0.16.jar org.jmeterplugins.repository.PluginManagerCMDInstaller
17+
java -cp apache-jmeter-$JMETER_VER/lib/ext/jmeter-plugins-manager-0.16.jar org.jmeterplugins.repository.PluginManagerCMDInstaller
1618

1719
# install jpgc-json-2
18-
apache-jmeter-3.3/bin/PluginsManagerCMD.sh install jpgc-json
20+
apache-jmeter-$JMETER_VER/bin/PluginsManagerCMD.sh install jpgc-json
1921

2022
# install jar file for commons csv
21-
wget -O apache-jmeter-3.3/lib/ext/commons-csv-1.5.jar http://central.maven.org/maven2/org/apache/commons/commons-csv/1.5/commons-csv-1.5.jar
23+
wget -O apache-jmeter-$JMETER_VER/lib/ext/commons-csv-1.5.jar https://repo1.maven.org/maven2/org/apache/commons/commons-csv/1.5/commons-csv-1.5.jar

jmeter/jmeter-version.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
JMETER_VER="5.2.1"

jmeter/run-gui.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
#!/bin/sh
22

3-
apache-jmeter-3.3/bin/jmeter.sh -t test-script.jmx
3+
source jmeter-version.sh
4+
5+
apache-jmeter-$JMETER_VER/bin/jmeter.sh -t test-script.jmx

jmeter/run-tests.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/bin/sh
22

3+
source jmeter-version.sh
4+
35
if [ -z $1 ]
46
then
57
>&2 echo 'Must supply "batch", "fetch", "query" or "upload" as first argument'
@@ -42,7 +44,7 @@ mkdir output/report
4244

4345
echo "starting jmeter script"
4446

45-
jmeter_cmd="apache-jmeter-3.3/bin/jmeter.sh -n -t test-script.jmx -l output/result/result.csv -e -o output/report -Jmode=$1 -Jthreads=$2 -Jloops=$3"
47+
jmeter_cmd="apache-jmeter-$JMETER_VER/bin/jmeter.sh -n -t test-script.jmx -l output/result/result.csv -e -o output/report -Jmode=$1 -Jthreads=$2 -Jloops=$3"
4648

4749
if [ -n "$4" ]
4850
then

pom.xml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,13 @@
167167
<updatePolicy>always</updatePolicy>
168168
</snapshots>
169169
</repository>
170+
<!-- Repository for geotools (as of April 2020) -->
170171
<repository>
171172
<id>osgeo</id>
172-
<name>Open Source Geospatial Foundation Repository</name>
173-
<url>http://download.osgeo.org/webdav/geotools/</url>
174-
<snapshots>
175-
<enabled>true</enabled>
176-
<updatePolicy>always</updatePolicy>
177-
</snapshots>
173+
<name>OSGeo Release Repository</name>
174+
<url>https://repo.osgeo.org/repository/release/</url>
175+
<snapshots><enabled>false</enabled></snapshots>
176+
<releases><enabled>true</enabled></releases>
178177
</repository>
179178
<repository>
180179
<id>sonatype</id>
@@ -251,7 +250,7 @@
251250
<dependency>
252251
<groupId>com.conveyal</groupId>
253252
<artifactId>gtfs-lib</artifactId>
254-
<version>5.0.7</version>
253+
<version>6.0.3</version>
255254
<!-- Exclusions added in order to silence SLF4J warnings about multiple bindings:
256255
http://www.slf4j.org/codes.html#multiple_bindings
257256
-->

src/main/java/com/conveyal/datatools/common/status/MonitorableJob.java

Lines changed: 71 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.conveyal.datatools.manager.DataManager;
44
import com.conveyal.datatools.manager.auth.Auth0UserProfile;
55
import com.fasterxml.jackson.annotation.JsonProperty;
6-
import com.google.common.collect.Sets;
76
import org.apache.commons.lang3.exception.ExceptionUtils;
87
import org.slf4j.Logger;
98
import org.slf4j.LoggerFactory;
@@ -76,6 +75,7 @@ public MonitorableJob(Auth0UserProfile owner, String name, JobType type) {
7675
}
7776
this.owner = owner;
7877
this.name = name;
78+
status.name = name;
7979
this.type = type;
8080
registerJob();
8181
}
@@ -150,21 +150,19 @@ public void run () {
150150
int subJobsTotal = subJobs.size() + 1;
151151

152152
for (MonitorableJob subJob : subJobs) {
153+
String subJobName = subJob.getClass().getSimpleName();
153154
if (!parentJobErrored && !subTaskErrored) {
155+
// Calculate completion based on number of sub jobs remaining.
156+
double percentComplete = subJobNumber * 100D / subJobsTotal;
154157
// Run sub-task if no error has errored during parent job or previous sub-task execution.
155-
// FIXME this will overwrite a message if message is set somewhere else.
156-
// FIXME If a subtask fails, cancel the parent task and cancel or remove subsequent sub-tasks.
157-
// status.message = String.format("Finished %d/%d sub-tasks", subJobNumber, subJobsTotal);
158-
status.percentComplete = subJobNumber * 100D / subJobsTotal;
159-
status.error = false; // FIXME: remove this error=false assignment
158+
status.update(String.format("Waiting on %s...", subJobName), percentComplete);
160159
subJob.run();
161-
162160
// Record if there has been an error in the execution of the sub-task. (Note: this will not
163161
// incorrectly overwrite a 'true' value with 'false' because the sub-task is only run if
164162
// jobHasErrored is false.
165163
if (subJob.status.error) {
166164
subTaskErrored = true;
167-
cancelMessage = String.format("Task cancelled due to error in %s task", subJob.getClass().getSimpleName());
165+
cancelMessage = String.format("Task cancelled due to error in %s task", subJobName);
168166
}
169167
} else {
170168
// Cancel (fail) next sub-task and continue.
@@ -178,24 +176,21 @@ public void run () {
178176
// because the error presumably already occurred and has a better error message.
179177
cancel(cancelMessage);
180178
}
181-
// Set duration of job in case it is needed by finishing step (e.g., storing the job duration in a database).
182-
status.duration = System.currentTimeMillis() - status.startTime;
179+
// Complete the job (as success if no errors encountered, as failure otherwise).
180+
if (!parentJobErrored && !subTaskErrored) status.completeSuccessfully("Job complete!");
181+
else status.complete(true);
183182
// Run final steps of job pending completion or error. Note: any tasks that depend on job success should
184-
// check job status to determine if final step should be executed (e.g., storing feed version in MongoDB).
183+
// check job status in jobFinished to determine if final step should be executed (e.g., storing feed
184+
// version in MongoDB).
185185
// TODO: should we add separate hooks depending on state of job/sub-tasks (e.g., success, catch, finally)
186186
jobFinished();
187187

188-
status.completed = true;
189-
190188
// We retain finished or errored jobs on the server until they are fetched via the API, which implies they
191189
// could be displayed by the client.
192-
} catch (Exception ex) {
193-
// Set job status to failed
194-
LOG.error("Job failed", ex);
195-
status.update(true, ex.getMessage(), 100, true);
196-
status.duration = System.currentTimeMillis() - status.startTime;
190+
} catch (Exception e) {
191+
status.fail("Job failed due to unhandled exception!", e);
197192
}
198-
LOG.info("{} {} {} in {} ms", type, jobId, status.error ? "errored" : "completed", status.duration);
193+
LOG.info("{} (jobId={}) {} in {} ms", type, jobId, status.error ? "errored" : "completed", status.duration);
199194
}
200195

201196
/**
@@ -206,8 +201,7 @@ public void run () {
206201
private void cancel(String message) {
207202
// Updating the job status with error is all we need to do in order to move the job into completion. Once the
208203
// user fetches the errored job, it will be automatically removed from the system.
209-
status.update(true, message, 100);
210-
status.completed = true;
204+
status.fail(message);
211205
// FIXME: Do we need to run any clean up here?
212206
}
213207

@@ -260,39 +254,76 @@ public static class Status {
260254
// Name of file/item once completed
261255
public String completedName;
262256

257+
/**
258+
* Update status message and percent complete. This method should be used while job is still in progress.
259+
*/
263260
public void update (String message, double percentComplete) {
261+
LOG.info("Job updated `{}`: `{}`\n{}", name, message, getCallingMethodTrace());
264262
this.message = message;
265263
this.percentComplete = percentComplete;
266264
}
267265

268-
public void update (boolean isError, String message, double percentComplete) {
269-
this.error = isError;
270-
this.message = message;
271-
this.percentComplete = percentComplete;
266+
/**
267+
* Gets stack trace from method calling {@link #update(String, double)} or {@link #fail(String)} for logging
268+
* purposes.
269+
*/
270+
private String getCallingMethodTrace() {
271+
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
272+
// Get trace from method calling update or fail. To trace this back:
273+
// 0. this thread
274+
// 1. this method
275+
// 2. Status#update or Status#fail
276+
// 3. line where update/fail is called in server job
277+
return stackTrace.length >= 3 ? stackTrace[3].toString() : "WARNING: Stack trace not found.";
272278
}
273279

274-
public void update (boolean isError, String message, double percentComplete, boolean isComplete) {
275-
this.error = isError;
276-
this.message = message;
277-
this.percentComplete = percentComplete;
278-
this.completed = isComplete;
280+
/**
281+
* Shorthand method to update status object on successful job completion.
282+
*/
283+
public void completeSuccessfully(String message) {
284+
this.complete(false, message);
279285
}
280286

281-
public void fail (String message, Exception e) {
282-
this.error = true;
287+
/**
288+
* Set job status to completed with error and message information.
289+
*/
290+
private void complete(boolean isError, String message) {
291+
this.error = isError;
292+
// Skip message update if null.
293+
if (message != null) this.message = message;
283294
this.percentComplete = 100;
284295
this.completed = true;
285-
this.message = message;
286-
this.exceptionDetails = ExceptionUtils.getStackTrace(e);
287-
this.exceptionType = e.getMessage();
296+
this.duration = System.currentTimeMillis() - this.startTime;
288297
}
289298

290-
public void fail (String message) {
291-
this.error = true;
292-
this.percentComplete = 100;
293-
this.completed = true;
294-
this.message = message;
299+
/**
300+
* Shorthand method to complete job without overriding current message.
301+
*/
302+
private void complete(boolean isError) {
303+
complete(isError, null);
304+
}
305+
306+
/**
307+
* Fail job status with message and exception.
308+
*/
309+
public void fail (String message, Exception e) {
310+
if (e != null) {
311+
this.exceptionDetails = ExceptionUtils.getStackTrace(e);
312+
this.exceptionType = e.getMessage();
313+
// If exception is null, overloaded fail method was called and message already logged with trace.
314+
String logMessage = String.format("Job `%s` failed with message: `%s`", name, message);
315+
LOG.warn(logMessage, e);
316+
}
317+
this.complete(true, message);
295318
}
296319

320+
/**
321+
* Fail job status with message.
322+
*/
323+
public void fail (String message) {
324+
// Log error with stack trace from calling method in job.
325+
LOG.error("Job failed with message {}\n{}", message, getCallingMethodTrace());
326+
fail(message, null);
327+
}
297328
}
298329
}

src/main/java/com/conveyal/datatools/common/utils/AWSUtils.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,11 @@ public static AWSStaticCredentialsProvider getCredentialsForRole(String role, St
148148
* Shorthand method to obtain an EC2 client for the provided role ARN. If role is null, the default EC2 credentials
149149
* will be used.
150150
*/
151-
public static AmazonEC2 getEC2ClientForRole (String role) {
151+
public static AmazonEC2 getEC2ClientForRole (String role, String region) {
152152
AWSStaticCredentialsProvider credentials = getCredentialsForRole(role, "ec2-client");
153-
return getEC2ClientForCredentials(credentials);
153+
return region == null
154+
? getEC2ClientForCredentials(credentials)
155+
: getEC2ClientForCredentials(credentials, region);
154156
}
155157

156158
/**
@@ -161,6 +163,14 @@ public static AmazonEC2 getEC2ClientForCredentials (AWSCredentialsProvider crede
161163
return AmazonEC2Client.builder().withCredentials(credentials).build();
162164
}
163165

166+
/**
167+
* Shorthand method to obtain an EC2 client for the provided credentials and region. If credentials are null, the
168+
* default EC2 credentials will be used.
169+
*/
170+
public static AmazonEC2 getEC2ClientForCredentials (AWSCredentialsProvider credentials, String region) {
171+
return AmazonEC2Client.builder().withCredentials(credentials).withRegion(region).build();
172+
}
173+
164174
/**
165175
* Shorthand method to obtain an S3 client for the provided credentials. If credentials are null, the default EC2
166176
* credentials will be used.

src/main/java/com/conveyal/datatools/common/utils/SparkUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ public static void logRequestOrResponse(
234234
LOG.warn("Request object is null. Cannot log.");
235235
return;
236236
}
237+
// don't log job status requests/responses, they clutter things up
238+
if (request.pathInfo().contains("status/jobs")) return;
237239
Auth0UserProfile userProfile = request.attribute("user");
238240
String userEmail = userProfile != null ? userProfile.getEmail() : "no-auth";
239241
String queryString = request.queryParams().size() > 0 ? "?" + request.queryString() : "";

0 commit comments

Comments
 (0)