Skip to content

Commit 1bb6707

Browse files
authored
Merge pull request #897 from p-org/dev/pobserve-cli
Add PObserve cli
2 parents 21017c8 + 8c3702f commit 1bb6707

File tree

58 files changed

+3571
-0
lines changed

Some content is hidden

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

58 files changed

+3571
-0
lines changed
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
import com.github.spotbugs.snom.SpotBugsTask
2+
3+
plugins {
4+
application
5+
id("java")
6+
id("maven-publish")
7+
id("checkstyle")
8+
id("com.github.spotbugs") version "5.+"
9+
id("com.diffplug.spotless") version "6.+"
10+
id("java-library")
11+
id("jacoco")
12+
id("com.github.johnrengelman.shadow") version "7.1.2"
13+
}
14+
15+
group = "io.github.p-org"
16+
version = "1.0.0"
17+
18+
repositories {
19+
mavenLocal()
20+
mavenCentral()
21+
}
22+
23+
// spotbugs
24+
spotbugs {
25+
toolVersion.set("4.7.3")
26+
ignoreFailures.set(true)
27+
excludeFilter.set(File("${project.rootDir}/config/spotbugs/excludeFilter.xml"))
28+
}
29+
30+
tasks.withType<SpotBugsTask>() {
31+
reports {
32+
create("html") {
33+
enabled = true
34+
outputLocation.set(file(layout.buildDirectory.dir("reports/spotbugs/spotbugs.html")))
35+
}
36+
}
37+
}
38+
39+
// checkstyle
40+
checkstyle {
41+
sourceSets = listOf(the<SourceSetContainer>()["main"], the<SourceSetContainer>()["test"])
42+
configFile = File("${project.rootDir}/config/checkstyle/checkstyle.xml")
43+
setIgnoreFailures(false)
44+
}
45+
46+
tasks.withType<Checkstyle>().configureEach {
47+
exclude("**/PGenerated/**")
48+
}
49+
50+
tasks.jacocoTestReport {
51+
reports {
52+
xml.required.set(false)
53+
csv.required.set(false)
54+
html.outputLocation.set(layout.buildDirectory.dir("jacocoHtml"))
55+
}
56+
}
57+
58+
tasks.jacocoTestCoverageVerification {
59+
violationRules {
60+
rule {
61+
isEnabled = true
62+
element = "CLASS"
63+
includes = listOf("pobserve.*")
64+
excludes = listOf(
65+
"pobserve.models.*",
66+
"pobserve.utils.*"
67+
)
68+
limit {
69+
counter = "LINE"
70+
value = "COVEREDRATIO"
71+
minimum = 0.toBigDecimal()
72+
}
73+
}
74+
}
75+
}
76+
77+
application {
78+
mainClass.set("pobserve.PObserve")
79+
applicationDefaultJvmArgs = listOf("-Dlog4j.configurationFile=log4j2.properties")
80+
}
81+
82+
// Fix for Gradle detected implicit dependency problems
83+
tasks.named("distZip") {
84+
dependsOn("shadowJar")
85+
}
86+
87+
tasks.named("distTar") {
88+
dependsOn("shadowJar")
89+
}
90+
91+
tasks.named("startScripts") {
92+
dependsOn("shadowJar")
93+
}
94+
95+
// Fix for startShadowScripts dependency issue
96+
tasks.named("startShadowScripts") {
97+
dependsOn("jar")
98+
}
99+
100+
tasks.check {
101+
dependsOn(tasks.jacocoTestCoverageVerification)
102+
dependsOn(tasks.jacocoTestReport)
103+
}
104+
105+
tasks.build {
106+
dependsOn(tasks.named("shadowJar"), tasks.spotlessApply, tasks.jacocoTestReport)
107+
}
108+
109+
tasks.test {
110+
useJUnitPlatform()
111+
testLogging {
112+
events("passed", "skipped", "failed")
113+
}
114+
115+
// Print url for test report, even if tests pass
116+
doLast {
117+
if (state.failure == null) {
118+
val reportUrl = file("build/brazil-unit-tests/index.html").absolutePath
119+
println("\n\n\nAll tests passed. See the report at: file://$reportUrl\n\n")
120+
}
121+
}
122+
123+
}
124+
125+
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
126+
archiveClassifier.set("super")
127+
archiveFileName.set("PObserve-${version}.jar")
128+
mergeServiceFiles()
129+
130+
isZip64 = true
131+
exclude(
132+
"**/Log4j2Plugins.dat",
133+
"**/com/esotericsoftware/kryo/Kryo.class**",
134+
"**/com/esotericsoftware/kryo/Kryo\$1.class**",
135+
"**/com/esotericsoftware/kryo/Kryo\$2.class**")
136+
137+
manifest {
138+
attributes(
139+
"Main-Class" to "pobserve.PObserve",
140+
"Build-Jdk" to System.getProperty("java.version")
141+
)
142+
}
143+
}
144+
145+
sourceSets {
146+
main {
147+
java {
148+
srcDirs("src/main/java")
149+
}
150+
resources {
151+
srcDir("src/resources")
152+
}
153+
}
154+
test {
155+
java {
156+
srcDirs("src/test/java")
157+
}
158+
}
159+
}
160+
161+
dependencies {
162+
implementation("io.github.p-org:pobserve-commons:1.0.0")
163+
implementation("io.github.p-org:pobserve-regression-testing:1.0.1")
164+
implementation("com.beust:jcommander:1.82")
165+
implementation("com.googlecode.json-simple:json-simple:1.1.1")
166+
implementation("com.google.code.findbugs:annotations:3.0.1")
167+
implementation("com.fasterxml.jackson.core:jackson-core:2.16.1")
168+
implementation("com.fasterxml.jackson.core:jackson-databind:2.16.1")
169+
implementation("de.ruedigermoeller:fst:2.50")
170+
implementation("org.apache.logging.log4j:log4j-slf4j-impl:2.20.0")
171+
172+
compileOnly("org.projectlombok:lombok:1.18.30")
173+
annotationProcessor("org.projectlombok:lombok:1.18.30")
174+
175+
testCompileOnly("org.projectlombok:lombok:1.18.30")
176+
testAnnotationProcessor("org.projectlombok:lombok:1.18.30")
177+
178+
testImplementation("org.junit.jupiter:junit-jupiter-api:5.11.3")
179+
testImplementation("org.junit.jupiter:junit-jupiter-params:5.11.3")
180+
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.11.3")
181+
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
182+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0"?>
2+
<!-- This Source Code Form is subject to the terms of the Mozilla Public
3+
- License, v. 2.0. If a copy of the MPL was not distributed with this
4+
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
5+
<!DOCTYPE module PUBLIC
6+
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
7+
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
8+
<module name="Checker">
9+
<property name="charset" value="UTF-8"/>
10+
11+
<module name="FileTabCharacter">
12+
<property name="eachLine" value="true"/>
13+
</module>
14+
15+
<module name="RegexpSingleline">
16+
<property name="format" value="\s+$"/>
17+
<property name="message" value="Trailing whitespace"/>
18+
</module>
19+
20+
<module name="TreeWalker">
21+
<module name="GenericWhitespace"/>
22+
<module name="NoLineWrap">
23+
<property name="tokens" value="IMPORT,PACKAGE_DEF"/>
24+
</module>
25+
<module name="OuterTypeFilename"/>
26+
<module name="WhitespaceAfter" />
27+
<module name="WhitespaceAround">
28+
<property name="allowEmptyConstructors" value="true"/>
29+
<property name="allowEmptyMethods" value="true"/>
30+
<property name="allowEmptyTypes" value="true"/>
31+
</module>
32+
<module name="NeedBraces" />
33+
<module name="LeftCurly" />
34+
<module name="RightCurly" />
35+
<module name="OneStatementPerLine" />
36+
<module name="FallThrough" />
37+
38+
<!-- Imports -->
39+
<module name="AvoidStarImport" />
40+
<module name="IllegalImport" />
41+
<module name="RedundantImport" />
42+
<module name="UnusedImports" />
43+
</module>
44+
45+
</module>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<FindBugsFilter>
3+
<Match>
4+
<package name="pobserve.*"/>
5+
<Bug pattern="EI_EXPOSE_REP2" />
6+
</Match>
7+
<Match>
8+
<package name="pobserve.*"/>
9+
<Bug pattern="EI_EXPOSE_REP" />
10+
</Match>
11+
<Match>
12+
<package name="pobserve.*"/>
13+
<Bug pattern="NP_METHOD_PARAMETER_TIGHTENS_ANNOTATION" />
14+
</Match>
15+
<Match>
16+
<package name="pobserve.*"/>
17+
<Bug pattern="EQ_DOESNT_OVERRIDE_EQUALS" />
18+
</Match>
19+
</FindBugsFilter>
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package pobserve;
2+
3+
import pobserve.commandline.PObserveCommandLineParameters;
4+
import pobserve.commandline.PObserveExitStatus;
5+
import pobserve.config.PObserveConfig;
6+
import pobserve.executor.PObserveExecutor;
7+
import pobserve.logger.PObserveLogger;
8+
import pobserve.metrics.MetricConstants;
9+
import pobserve.report.PObserveError;
10+
import pobserve.report.TrackErrors;
11+
import pobserve.source.socket.PObserveSocketServer;
12+
13+
import com.beust.jcommander.JCommander;
14+
import com.beust.jcommander.ParameterException;
15+
16+
import static pobserve.config.PObserveConfig.getPObserveConfig;
17+
import static pobserve.metrics.PObserveMetrics.getPObserveMetrics;
18+
19+
public final class PObserve {
20+
/**
21+
* Main function of the program. It parses program parameters, instantiates a Sequencer, and
22+
* executes it.
23+
*
24+
* @param args is arguments of PObserve.
25+
* @throws Exception if given arguments are not well-formed.
26+
*/
27+
public static void main(String[] args) throws Exception {
28+
PObserveCommandLineParameters params = new PObserveCommandLineParameters();
29+
JCommander jc = JCommander.newBuilder().addObject(params).build();
30+
31+
// parse the commandline arguments and load the config
32+
try {
33+
jc.parse(args);
34+
35+
// Check if help was requested
36+
if (params.isHelp()) {
37+
jc.usage();
38+
return;
39+
}
40+
41+
PObserveConfig.validateAndLoadPObserveConfig();
42+
} catch (ParameterException e) {
43+
PObserveLogger.error("Failed parsing ::");
44+
PObserveLogger.error(e.getMessage());
45+
jc.usage();
46+
System.exit(PObserveExitStatus.CMDLINEERROR.getValue());
47+
}
48+
49+
// Check if we should run in socket mode
50+
if (getPObserveConfig().isSocketMode()) {
51+
runSocketMode();
52+
} else {
53+
runStandardMode();
54+
}
55+
}
56+
57+
/**
58+
* Run PObserve in standard file processing mode.
59+
*/
60+
private static void runStandardMode() {
61+
try {
62+
var job = new PObserveExecutor();
63+
job.run();
64+
} catch (Exception ex) {
65+
TrackErrors.addError(new PObserveError(ex));
66+
} finally {
67+
TrackErrors.emitErrorsReport();
68+
getPObserveMetrics().outputMetricsSummary();
69+
printFinalMessage();
70+
System.exit(TrackErrors.getExitStatus().getValue());
71+
}
72+
}
73+
74+
/**
75+
* Run PObserve in socket server mode.
76+
*/
77+
private static void runSocketMode() {
78+
PObserveLogger.info("Starting PObserve in socket mode");
79+
PObserveSocketServer server = new PObserveSocketServer(
80+
getPObserveConfig().getHost(),
81+
getPObserveConfig().getPort()
82+
);
83+
84+
try {
85+
// Register shutdown hook to stop the server gracefully on JVM exit
86+
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
87+
PObserveLogger.info("Shutting down PObserve socket server");
88+
server.stop();
89+
}));
90+
91+
// Start the server (this call blocks until the server is stopped)
92+
server.start();
93+
94+
} catch (Exception ex) {
95+
PObserveLogger.error("Error in socket server mode: " + ex.getMessage());
96+
TrackErrors.addError(new PObserveError(ex));
97+
TrackErrors.emitErrorsReport();
98+
System.exit(PObserveExitStatus.INTERNALERROR.getValue());
99+
}
100+
}
101+
102+
private static void printFinalMessage() {
103+
int errorCount = getPObserveMetrics().getMetricsMap().get(MetricConstants.TOTAL_SPEC_ERRORS).get()
104+
+ getPObserveMetrics().getMetricsMap().get(MetricConstants.TOTAL_EVENT_OUT_OF_ORDER_ERRORS).get()
105+
+ getPObserveMetrics().getMetricsMap().get(MetricConstants.TOTAL_UNKNOWN_ERRORS).get();
106+
assert errorCount == TrackErrors.numErrors();
107+
if (errorCount > 0) {
108+
PObserveLogger.error("PObserve run completed with " + errorCount + " error(s)");
109+
PObserveLogger.error("Run details and replay event logs can be found in " + getPObserveConfig().getOutputDir().getAbsolutePath());
110+
} else {
111+
PObserveLogger.info("PObserve run completed with " + errorCount + " error(s)");
112+
PObserveLogger.info("Run details can be found in " + getPObserveConfig().getOutputDir().getAbsolutePath());
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)