Skip to content

Commit 2a7ba3b

Browse files
authored
Merge pull request #1560 from NASA-AMMOS/feat/proc-external-profiles
External profiles in procedural scheduling
2 parents 86108a9 + 2c02928 commit 2a7ba3b

File tree

20 files changed

+550
-208
lines changed

20 files changed

+550
-208
lines changed

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
- name: Assemble
7979
run: ./gradlew assemble --parallel
8080
- name: Build scheduling procedure jars for testing
81-
run: ./gradlew procedural:examples:foo-procedures:buildAllSchedulingProcedureJars
81+
run: ./gradlew e2e-tests:buildAllSchedulingProcedureJars
8282
- name: Start Services
8383
run: |
8484
docker compose -f ./e2e-tests/docker-compose-test.yml up -d --build

e2e-tests/build.gradle

+73-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
2+
13
plugins {
24
id 'java-library'
35
id 'jacoco'
6+
id 'com.gradleup.shadow' version '8.3.0'
47
}
58

69
java {
@@ -54,12 +57,17 @@ task e2eTest(type: Test) {
5457
}
5558

5659
dependencies {
57-
testImplementation project(":procedural:timeline")
60+
annotationProcessor project(':procedural:processor')
61+
62+
implementation project(":procedural:scheduling")
63+
implementation project(":procedural:timeline")
64+
implementation project(':merlin-sdk')
65+
implementation project(':type-utils')
66+
implementation project(':contrib')
67+
5868
testImplementation project(":procedural:remote")
5969
testImplementation "com.zaxxer:HikariCP:5.1.0"
6070
testImplementation("org.postgresql:postgresql:42.6.0")
61-
testImplementation project(':merlin-driver')
62-
testImplementation project(':type-utils')
6371

6472
testImplementation 'com.microsoft.playwright:playwright:1.37.0'
6573

@@ -69,3 +77,65 @@ dependencies {
6977
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.0'
7078
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.0'
7179
}
80+
81+
tasks.register('buildAllSchedulingProcedureJars') {
82+
group = 'SchedulingProcedureJars'
83+
84+
dependsOn "generateSchedulingProcedureJarTasks"
85+
dependsOn {
86+
tasks.findAll { task -> task.name.startsWith('buildSchedulingProcedureJar_') }
87+
}
88+
}
89+
90+
tasks.create("generateSchedulingProcedureJarTasks") {
91+
group = 'SchedulingProcedureJars'
92+
93+
final proceduresDir = findFirstMatchingBuildDir("generated/procedures")
94+
95+
if (proceduresDir == null) {
96+
println "No procedures folder found"
97+
return
98+
}
99+
println "Generating jar tasks for the following procedures directory: ${proceduresDir}"
100+
101+
final files = file(proceduresDir).listFiles()
102+
if (files.length == 0) {
103+
println "No procedures available within folder ${proceduresDir}"
104+
return
105+
}
106+
107+
files.toList().each { file ->
108+
final nameWithoutExtension = file.name.replace(".java", "")
109+
final taskName = "buildSchedulingProcedureJar_${nameWithoutExtension}"
110+
111+
println "Generating ${taskName} task, which will build ${nameWithoutExtension}.jar"
112+
113+
tasks.create(taskName, ShadowJar) {
114+
group = 'SchedulingProcedureJars'
115+
configurations = [project.configurations.compileClasspath]
116+
from sourceSets.main.output
117+
archiveBaseName = "" // clear
118+
archiveClassifier.set(nameWithoutExtension) // set output jar name
119+
manifest {
120+
attributes 'Main-Class': getMainClassFromGeneratedFile(file)
121+
}
122+
minimize()
123+
}
124+
}
125+
}
126+
127+
private String findFirstMatchingBuildDir(String pattern) {
128+
String found = null
129+
final generatedDir = file("build/generated/sources")
130+
generatedDir.mkdirs()
131+
generatedDir.eachDirRecurse { dir -> if (dir.path.contains(pattern)) found = dir.path }
132+
return found
133+
}
134+
135+
private static String getMainClassFromGeneratedFile(File file) {
136+
final fileString = file.toString()
137+
final prefix = "build/generated/sources/annotationProcessor/java/main/"
138+
final index = fileString.indexOf(prefix) + prefix.length()
139+
final trimmed = fileString.substring(index).replace(".java", "")
140+
return trimmed.replace("/", ".")
141+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@WithMappers(BasicValueMappers.class)
2+
package gov.nasa.jpl.aerie.e2e.procedural.scheduling;
3+
4+
import gov.nasa.jpl.aerie.contrib.serialization.rulesets.BasicValueMappers;
5+
import gov.nasa.ammos.aerie.procedural.scheduling.annotations.WithMappers;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package gov.nasa.jpl.aerie.e2e.procedural.scheduling.procedures;
2+
3+
import gov.nasa.ammos.aerie.procedural.scheduling.plan.EditablePlan;
4+
import gov.nasa.ammos.aerie.procedural.scheduling.Goal;
5+
import gov.nasa.ammos.aerie.procedural.scheduling.annotations.SchedulingProcedure;
6+
import gov.nasa.ammos.aerie.procedural.scheduling.plan.NewDirective;
7+
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.AnyDirective;
8+
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration;
9+
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.DirectiveStart;
10+
import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue;
11+
import org.jetbrains.annotations.NotNull;
12+
13+
import java.util.Map;
14+
15+
/**
16+
* Waits 24hrs into the plan, then places `quantity` number of BiteBanana activities,
17+
* one every 6hrs.
18+
*/
19+
@SchedulingProcedure
20+
public record DumbRecurrenceGoal(int quantity) implements Goal {
21+
@Override
22+
public void run(@NotNull final EditablePlan plan) {
23+
final var firstTime = Duration.hours(24);
24+
final var step = Duration.hours(6);
25+
26+
var currentTime = firstTime;
27+
for (var i = 0; i < quantity; i++) {
28+
plan.create(
29+
new NewDirective(
30+
new AnyDirective(Map.of("biteSize", SerializedValue.of(1))),
31+
"It's a bite banana activity",
32+
"BiteBanana",
33+
new DirectiveStart.Absolute(currentTime)
34+
)
35+
);
36+
currentTime = currentTime.plus(step);
37+
}
38+
plan.commit();
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package gov.nasa.jpl.aerie.e2e.procedural.scheduling.procedures;
2+
3+
import gov.nasa.ammos.aerie.procedural.scheduling.Goal;
4+
import gov.nasa.ammos.aerie.procedural.scheduling.annotations.SchedulingProcedure;
5+
import gov.nasa.ammos.aerie.procedural.scheduling.plan.EditablePlan;
6+
import gov.nasa.ammos.aerie.procedural.timeline.collections.profiles.Booleans;
7+
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.DirectiveStart;
8+
import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue;
9+
import org.jetbrains.annotations.NotNull;
10+
11+
import java.util.Map;
12+
13+
@SchedulingProcedure
14+
public record ExternalProfileGoal() implements Goal {
15+
@Override
16+
public void run(@NotNull final EditablePlan plan) {
17+
final var myBoolean = plan.resource("/my_boolean", Booleans.deserializer());
18+
for (final var interval: myBoolean.highlightTrue()) {
19+
plan.create(
20+
"BiteBanana",
21+
new DirectiveStart.Absolute(interval.start),
22+
Map.of("biteSize", SerializedValue.of(1))
23+
);
24+
}
25+
26+
plan.commit();
27+
}
28+
}

0 commit comments

Comments
 (0)