11package io .quarkiverse .flow .deployment ;
22
3- import java .util .ArrayList ;
43import java .util .Collections ;
54import java .util .List ;
5+ import java .util .Set ;
6+ import java .util .stream .Collectors ;
67
78import jakarta .enterprise .context .ApplicationScoped ;
9+ import jakarta .inject .Inject ;
810import jakarta .ws .rs .Priorities ;
911
12+ import org .objectweb .asm .Opcodes ;
1013import org .slf4j .Logger ;
1114import org .slf4j .LoggerFactory ;
1215
16+ import io .quarkiverse .flow .config .FlowDefinitionsConfig ;
1317import io .quarkiverse .flow .config .FlowTracingConfig ;
1418import io .quarkiverse .flow .providers .CredentialsProviderSecretManager ;
1519import io .quarkiverse .flow .providers .HttpClientProvider ;
1923import io .quarkiverse .flow .recorders .SDKRecorder ;
2024import io .quarkiverse .flow .recorders .WorkflowApplicationRecorder ;
2125import io .quarkiverse .flow .recorders .WorkflowDefinitionRecorder ;
26+ import io .quarkus .arc .Unremovable ;
2227import io .quarkus .arc .deployment .AdditionalBeanBuildItem ;
28+ import io .quarkus .arc .deployment .GeneratedBeanBuildItem ;
29+ import io .quarkus .arc .deployment .GeneratedBeanGizmoAdaptor ;
2330import io .quarkus .arc .deployment .SyntheticBeanBuildItem ;
2431import io .quarkus .arc .deployment .UnremovableBeanBuildItem ;
2532import io .quarkus .deployment .IsDevelopment ;
2633import io .quarkus .deployment .annotations .BuildProducer ;
2734import io .quarkus .deployment .annotations .BuildStep ;
2835import io .quarkus .deployment .annotations .ExecutionTime ;
36+ import io .quarkus .deployment .annotations .Produce ;
2937import io .quarkus .deployment .annotations .Record ;
3038import io .quarkus .deployment .builditem .FeatureBuildItem ;
3139import io .quarkus .deployment .builditem .HotDeploymentWatchedFileBuildItem ;
3240import io .quarkus .deployment .builditem .LaunchModeBuildItem ;
3341import io .quarkus .deployment .builditem .ShutdownContextBuildItem ;
42+ import io .quarkus .gizmo .ClassCreator ;
43+ import io .quarkus .gizmo .FieldCreator ;
44+ import io .quarkus .gizmo .MethodDescriptor ;
3445import io .quarkus .resteasy .reactive .spi .ExceptionMapperBuildItem ;
46+ import io .serverlessworkflow .api .types .Workflow ;
3547import io .serverlessworkflow .impl .WorkflowApplication ;
3648import io .serverlessworkflow .impl .WorkflowDefinition ;
3749import io .serverlessworkflow .impl .WorkflowException ;
@@ -92,10 +104,8 @@ void registerWorkflowExceptionMapper(BuildProducer<ExceptionMapperBuildItem> map
92104 @ BuildStep
93105 void produceWorkflowDefinitions (WorkflowDefinitionRecorder recorder ,
94106 BuildProducer <SyntheticBeanBuildItem > beans ,
95- List <DiscoveredFlowBuildItem > discoveredFlows ,
96- List <DiscoveredWorkflowFileBuildItem > workflows ) {
97-
98- List <String > identifiers = new ArrayList <>();
107+ BuildProducer <FlowIdentifierBuildItem > identifiers ,
108+ List <DiscoveredFlowBuildItem > discoveredFlows ) {
99109
100110 for (DiscoveredFlowBuildItem it : discoveredFlows ) {
101111 beans .produce (SyntheticBeanBuildItem .configure (WorkflowDefinition .class )
@@ -105,23 +115,76 @@ void produceWorkflowDefinitions(WorkflowDefinitionRecorder recorder,
105115 .addQualifier ().annotation (DotNames .IDENTIFIER ).addValue ("value" , it .getClassName ()).done ()
106116 .supplier (recorder .workflowDefinitionSupplier (it .getClassName ()))
107117 .done ());
108- identifiers .add ( it .getClassName ());
118+ identifiers .produce ( new FlowIdentifierBuildItem ( Set . of ( it .getClassName ()) ));
109119 }
120+ }
110121
122+ @ BuildStep
123+ @ Record (ExecutionTime .RUNTIME_INIT )
124+ void produceWorkflowDefinitionsFromFile (
125+ List <DiscoveredWorkflowFileBuildItem > workflows ,
126+ BuildProducer <SyntheticBeanBuildItem > beans ,
127+ BuildProducer <FlowIdentifierBuildItem > identifiers ,
128+ WorkflowDefinitionRecorder recorder ,
129+ FlowDefinitionsConfig config ) {
111130 for (DiscoveredWorkflowFileBuildItem workflow : workflows ) {
131+
132+ String flowSubclassIdentifier = WorkflowNamingConverter .generateFlowClassIdentifier (
133+ workflow .namespace (), workflow .name (), config .namespace ().prefix ());
134+
112135 beans .produce (SyntheticBeanBuildItem .configure (WorkflowDefinition .class )
113136 .scope (ApplicationScoped .class )
114137 .unremovable ()
115138 .setRuntimeInit ()
116139 .addQualifier ().annotation (DotNames .IDENTIFIER )
117- .addValue ("value" , workflow .identifier ()).done ()
118- .supplier (recorder .workflowDefinitionFromFileSupplier (workflow .locationString ()))
140+ .addValue ("value" , workflow .regularIdentifier ()).done ()
141+ .addQualifier ().annotation (DotNames .IDENTIFIER )
142+ .addValue ("value" , flowSubclassIdentifier ).done ()
143+ .supplier (recorder .workflowDefinitionFromFileSupplier (workflow .location ()))
119144 .done ());
120145
121- identifiers .add (workflow .identifier ());
146+ identifiers .produce (new FlowIdentifierBuildItem (
147+ Set .of (flowSubclassIdentifier , workflow .regularIdentifier ())));
122148 }
149+ }
150+
151+ @ BuildStep
152+ void produceGeneratedFlows (List <DiscoveredWorkflowFileBuildItem > workflows ,
153+ BuildProducer <GeneratedBeanBuildItem > classes ,
154+ FlowDefinitionsConfig definitionsConfig ) {
155+
156+ GeneratedBeanGizmoAdaptor gizmo = new GeneratedBeanGizmoAdaptor (classes );
157+ for (DiscoveredWorkflowFileBuildItem workflow : workflows ) {
158+ String flowSubclassIdentifier = WorkflowNamingConverter .generateFlowClassIdentifier (
159+ workflow .namespace (), workflow .name (), definitionsConfig .namespace ().prefix ());
160+
161+ try (ClassCreator creator = ClassCreator .builder ()
162+ .className (flowSubclassIdentifier )
163+ .superClass (DotNames .FLOW .toString ())
164+ .classOutput (gizmo )
165+ .build ()) {
166+
167+ creator .addAnnotation (Unremovable .class );
168+ creator .addAnnotation (ApplicationScoped .class );
169+ creator .addAnnotation (Identifier .class ).add ("value" , flowSubclassIdentifier );
170+
171+ // workflowDefinition field
172+ FieldCreator fieldCreator = creator .getFieldCreator ("workflowDefinition" ,
173+ WorkflowDefinition .class .getName ());
174+ fieldCreator .setModifiers (Opcodes .ACC_PUBLIC );
175+ fieldCreator .addAnnotation (Inject .class );
176+ fieldCreator .addAnnotation (Identifier .class )
177+ .add ("value" , flowSubclassIdentifier );
123178
124- logWorkflowList (identifiers );
179+ // descriptor() method
180+ var method = creator .getMethodCreator ("descriptor" , Workflow .class );
181+ method .setModifiers (Opcodes .ACC_PUBLIC );
182+ method .returnValue (
183+ method .invokeVirtualMethod (
184+ MethodDescriptor .ofMethod (WorkflowDefinition .class , "workflow" , Workflow .class ),
185+ method .readInstanceField (fieldCreator .getFieldDescriptor (), method .getThis ())));
186+ }
187+ }
125188 }
126189
127190 @ Record (ExecutionTime .RUNTIME_INIT )
@@ -144,6 +207,17 @@ void registerWorkflowApp(WorkflowApplicationRecorder recorder,
144207 LOG .info ("Flow: Registering Workflow Application bean: {}" , WorkflowApplication .class .getName ());
145208 }
146209
210+ @ BuildStep
211+ @ Produce (SyntheticBeanBuildItem .class )
212+ void logRegisteredWorkflows (
213+ List <FlowIdentifierBuildItem > registeredIdentifiers ) {
214+ List <String > allIdentifiers = registeredIdentifiers .stream ().map (FlowIdentifierBuildItem ::identifiers )
215+ .map (set -> String .join (", " , set ))
216+ .distinct ()
217+ .collect (Collectors .toList ());
218+ logWorkflowList (allIdentifiers );
219+ }
220+
147221 private void logWorkflowList (List <String > identifiers ) {
148222 if (identifiers .isEmpty ()) {
149223 LOG .info ("Flow: No WorkflowDefinition beans were registered." );
@@ -184,7 +258,7 @@ public void watchChanges(List<DiscoveredWorkflowFileBuildItem> workflows,
184258 BuildProducer <HotDeploymentWatchedFileBuildItem > watchedFiles ) {
185259 for (DiscoveredWorkflowFileBuildItem workflow : workflows ) {
186260 watchedFiles .produce (HotDeploymentWatchedFileBuildItem .builder ()
187- .setLocation (workflow .locationString ())
261+ .setLocation (workflow .location ())
188262 .setRestartNeeded (true )
189263 .build ());
190264 }
0 commit comments