use of io.quarkus.gizmo.FieldCreator in project camel-quarkus by apache.
the class GrpcProcessor method createBindableServiceBeans.
@BuildStep
void createBindableServiceBeans(BuildProducer<GeneratedBeanBuildItem> generatedBean, BuildProducer<ReflectiveClassBuildItem> reflectiveClass, CombinedIndexBuildItem combinedIndexBuildItem) {
IndexView index = combinedIndexBuildItem.getIndex();
Collection<ClassInfo> bindableServiceImpls = index.getAllKnownImplementors(BINDABLE_SERVICE_DOT_NAME);
// This mimics similar logic in DefaultBindableServiceFactory that uses Javassist ProxyFactory & MethodHandler
for (ClassInfo service : bindableServiceImpls) {
if (!Modifier.isAbstract(service.flags())) {
continue;
}
if (service.name().withoutPackagePrefix().startsWith("Mutiny")) {
/* The generate-code goal of quarkus-maven-plugin generates also Mutiny service that we do not use
* Not skipping it here results in randomly registering the Mutiny one or the right one.
* In case the Mutiny service one is registered, the client throws something like
* io.grpc.StatusRuntimeException: UNIMPLEMENTED */
continue;
}
String superClassName = service.name().toString();
String generatedClassName = superClassName + "QuarkusMethodHandler";
// Register the service classes for reflection
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, service.name().toString()));
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, service.enclosingClass().toString()));
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, generatedClassName));
try (ClassCreator classCreator = ClassCreator.builder().classOutput(new GeneratedBeanGizmoAdaptor(generatedBean)).className(generatedClassName).superClass(superClassName).interfaces(CamelQuarkusBindableService.class).build()) {
classCreator.addAnnotation(Dependent.class);
FieldCreator serverMethodHandler = classCreator.getFieldCreator("methodHandler", GrpcMethodHandler.class.getName()).setModifiers(Modifier.PRIVATE);
// Create constructor
try (MethodCreator initMethod = classCreator.getMethodCreator("<init>", void.class)) {
initMethod.setModifiers(Modifier.PUBLIC);
initMethod.invokeSpecialMethod(MethodDescriptor.ofMethod(superClassName, "<init>", void.class), initMethod.getThis());
initMethod.returnValue(null);
}
// Create setMethodHandler override
try (MethodCreator setMethodHandlerMethod = classCreator.getMethodCreator("setMethodHandler", void.class, GrpcMethodHandler.class)) {
setMethodHandlerMethod.setModifiers(Modifier.PUBLIC);
ResultHandle self = setMethodHandlerMethod.getThis();
ResultHandle methodHandlerInstance = setMethodHandlerMethod.getMethodParam(0);
setMethodHandlerMethod.writeInstanceField(serverMethodHandler.getFieldDescriptor(), self, methodHandlerInstance);
setMethodHandlerMethod.returnValue(null);
}
// Override service methods that the gRPC component is interested in
// E.g methods with one or two parameters where one is of type StreamObserver
List<MethodInfo> methods = service.methods();
for (MethodInfo method : methods) {
if (isCandidateServiceMethod(method)) {
String[] params = method.parameters().stream().map(type -> type.name().toString()).toArray(String[]::new);
ClassInfo classInfo = index.getClassByName(DotName.createSimple(GrpcMethodHandler.class.getName()));
String returnType = method.returnType().name().toString();
try (MethodCreator methodCreator = classCreator.getMethodCreator(method.name(), returnType, params)) {
method.exceptions().stream().map(type -> type.name().toString()).forEach(methodCreator::addException);
if (method.parameters().size() == 1) {
ResultHandle returnValue = generateGrpcDelegateMethod(classInfo, serverMethodHandler, methodCreator, method, "handleForConsumerStrategy");
methodCreator.returnValue(returnValue);
} else if (method.parameters().size() == 2) {
generateGrpcDelegateMethod(classInfo, serverMethodHandler, methodCreator, method, "handle");
methodCreator.returnValue(null);
}
}
}
}
}
}
}
use of io.quarkus.gizmo.FieldCreator in project quarkus-github-app by quarkiverse.
the class GitHubAppProcessor method generateDispatcher.
/**
* The role of the dispatcher is to receive the CDI events emitted by the reactive route.
* <p>
* It parses the raw payload into the appropriate {@link GHEventPayload} and then emit
* an async CDI event with a MultiplexedEvent containing the payload instance,
* the GitHub instance and the DynamicGraphQLClient instance if needed.
* <p>
* It only generates code for the GitHub events actually listened to by the application.
*/
private static void generateDispatcher(ClassOutput beanClassOutput, CombinedIndexBuildItem combinedIndex, LaunchModeBuildItem launchMode, DispatchingConfiguration dispatchingConfiguration, BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
String dispatcherClassName = GitHubEvent.class.getName() + "DispatcherImpl";
reflectiveClasses.produce(new ReflectiveClassBuildItem(true, true, dispatcherClassName));
ClassCreator dispatcherClassCreator = ClassCreator.builder().classOutput(beanClassOutput).className(dispatcherClassName).build();
dispatcherClassCreator.addAnnotation(Singleton.class);
FieldCreator eventFieldCreator = dispatcherClassCreator.getFieldCreator(EVENT_EMITTER_FIELD, Event.class);
eventFieldCreator.addAnnotation(Inject.class);
eventFieldCreator.setModifiers(Modifier.PROTECTED);
FieldCreator gitHubServiceFieldCreator = dispatcherClassCreator.getFieldCreator(GITHUB_SERVICE_FIELD, GitHubService.class);
gitHubServiceFieldCreator.addAnnotation(Inject.class);
gitHubServiceFieldCreator.setModifiers(Modifier.PROTECTED);
MethodCreator dispatchMethodCreator = dispatcherClassCreator.getMethodCreator("dispatch", void.class, GitHubEvent.class);
dispatchMethodCreator.setModifiers(Modifier.PUBLIC);
dispatchMethodCreator.getParameterAnnotations(0).addAnnotation(DotNames.OBSERVES.toString());
ResultHandle gitHubEventRh = dispatchMethodCreator.getMethodParam(0);
ResultHandle installationIdRh = dispatchMethodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getInstallationId", Long.class), gitHubEventRh);
ResultHandle dispatchedEventRh = dispatchMethodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getEvent", String.class), gitHubEventRh);
ResultHandle dispatchedActionRh = dispatchMethodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getAction", String.class), gitHubEventRh);
ResultHandle dispatchedPayloadRh = dispatchMethodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getPayload", String.class), gitHubEventRh);
TryBlock tryBlock = dispatchMethodCreator.tryBlock();
ResultHandle gitHubRh = tryBlock.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubService.class, "getInstallationClient", GitHub.class, Long.class), tryBlock.readInstanceField(FieldDescriptor.of(dispatcherClassCreator.getClassName(), GITHUB_SERVICE_FIELD, GitHubService.class), tryBlock.getThis()), installationIdRh);
ResultHandle gitHubGraphQLClientRh = tryBlock.loadNull();
if (dispatchingConfiguration.requiresGraphQLClient()) {
gitHubGraphQLClientRh = tryBlock.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubService.class, "getInstallationGraphQLClient", DynamicGraphQLClient.class, Long.class), tryBlock.readInstanceField(FieldDescriptor.of(dispatcherClassCreator.getClassName(), GITHUB_SERVICE_FIELD, GitHubService.class), tryBlock.getThis()), installationIdRh);
}
for (EventDispatchingConfiguration eventDispatchingConfiguration : dispatchingConfiguration.getEventConfigurations().values()) {
ResultHandle eventRh = tryBlock.load(eventDispatchingConfiguration.getEvent());
String payloadType = eventDispatchingConfiguration.getPayloadType();
BytecodeCreator eventMatchesCreator = tryBlock.ifTrue(tryBlock.invokeVirtualMethod(MethodDescriptors.OBJECT_EQUALS, eventRh, dispatchedEventRh)).trueBranch();
ResultHandle payloadInstanceRh = eventMatchesCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHub.class, "parseEventPayload", GHEventPayload.class, Reader.class, Class.class), gitHubRh, eventMatchesCreator.newInstance(MethodDescriptor.ofConstructor(StringReader.class, String.class), dispatchedPayloadRh), eventMatchesCreator.loadClass(payloadType));
ResultHandle multiplexedEventRh = eventMatchesCreator.newInstance(MethodDescriptor.ofConstructor(MultiplexedEvent.class, GHEventPayload.class, GitHub.class, DynamicGraphQLClient.class), payloadInstanceRh, gitHubRh, gitHubGraphQLClientRh);
for (Entry<String, EventAnnotation> eventAnnotationEntry : eventDispatchingConfiguration.getEventAnnotations().entrySet()) {
String action = eventAnnotationEntry.getKey();
EventAnnotation eventAnnotation = eventAnnotationEntry.getValue();
Class<?>[] literalParameterTypes = new Class<?>[eventAnnotation.getValues().size()];
Arrays.fill(literalParameterTypes, String.class);
List<ResultHandle> literalParameters = new ArrayList<>();
ResultHandle annotationLiteralRh = eventMatchesCreator.newInstance(MethodDescriptor.ofConstructor(getLiteralClassName(eventAnnotation.getName()), (Object[]) literalParameterTypes), literalParameters.toArray(ResultHandle[]::new));
ResultHandle annotationLiteralArrayRh = eventMatchesCreator.newArray(Annotation.class, 1);
eventMatchesCreator.writeArrayValue(annotationLiteralArrayRh, 0, annotationLiteralRh);
if (Actions.ALL.equals(action)) {
fireAsyncAction(eventMatchesCreator, launchMode.getLaunchMode(), dispatcherClassCreator.getClassName(), gitHubEventRh, multiplexedEventRh, annotationLiteralArrayRh);
} else {
BytecodeCreator actionMatchesCreator = eventMatchesCreator.ifTrue(eventMatchesCreator.invokeVirtualMethod(MethodDescriptors.OBJECT_EQUALS, eventMatchesCreator.load(action), dispatchedActionRh)).trueBranch();
fireAsyncAction(actionMatchesCreator, launchMode.getLaunchMode(), dispatcherClassCreator.getClassName(), gitHubEventRh, multiplexedEventRh, annotationLiteralArrayRh);
}
}
}
CatchBlockCreator catchBlockCreator = tryBlock.addCatch(Throwable.class);
catchBlockCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(ErrorHandlerBridgeFunction.class, "apply", Void.class, Throwable.class), catchBlockCreator.newInstance(MethodDescriptor.ofConstructor(ErrorHandlerBridgeFunction.class, GitHubEvent.class), gitHubEventRh), catchBlockCreator.getCaughtException());
dispatchMethodCreator.returnValue(null);
dispatcherClassCreator.close();
}
use of io.quarkus.gizmo.FieldCreator in project quarkus-github-action by quarkiverse.
the class GitHubActionProcessor method generateActionMain.
/**
* This method generates the <code>@QuarkusMain</code> class.
* <p>
* It emits the GitHub events as CDI events that will then be caught by the multiplexers.
*/
private static void generateActionMain(ClassOutput beanClassOutput, CombinedIndexBuildItem combinedIndex, LaunchModeBuildItem launchMode, DispatchingConfiguration dispatchingConfiguration, BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
String gitHubEventHandlerClassName = GitHubEventHandler.class.getName() + "Impl";
reflectiveClasses.produce(new ReflectiveClassBuildItem(true, true, gitHubEventHandlerClassName));
ClassCreator gitHubEventHandlerClassCreator = ClassCreator.builder().classOutput(beanClassOutput).className(gitHubEventHandlerClassName).interfaces(GitHubEventHandler.class).build();
gitHubEventHandlerClassCreator.addAnnotation(Singleton.class);
FieldCreator eventFieldCreator = gitHubEventHandlerClassCreator.getFieldCreator(EVENT_EMITTER_FIELD, Event.class);
eventFieldCreator.addAnnotation(Inject.class);
eventFieldCreator.setModifiers(Modifier.PROTECTED);
MethodCreator handleMethodCreator = gitHubEventHandlerClassCreator.getMethodCreator("handle", void.class, GitHubEvent.class);
handleMethodCreator.setModifiers(Modifier.PUBLIC);
ResultHandle gitHubEventRh = handleMethodCreator.getMethodParam(0);
ResultHandle dispatchedNameRh = handleMethodCreator.invokeVirtualMethod(GITHUB_EVENT_GET_NAME, gitHubEventRh);
ResultHandle dispatchedEventRh = handleMethodCreator.invokeVirtualMethod(GITHUB_EVENT_GET_EVENT, gitHubEventRh);
ResultHandle dispatchedActionRh = handleMethodCreator.invokeVirtualMethod(GITHUB_EVENT_GET_EVENT_ACTION, gitHubEventRh);
for (Entry<String, Map<String, ActionDispatchingConfiguration>> actionConfigurationEntry : dispatchingConfiguration.getActionConfigurations().entrySet()) {
String name = actionConfigurationEntry.getKey();
Map<String, ActionDispatchingConfiguration> actionConfiguration = actionConfigurationEntry.getValue();
BytecodeCreator nameMatchesCreator = handleMethodCreator.ifTrue(handleMethodCreator.invokeVirtualMethod(MethodDescriptors.OBJECT_EQUALS, handleMethodCreator.load(name), dispatchedNameRh)).trueBranch();
ResultHandle actionAnnotationLiteralRh = nameMatchesCreator.newInstance(MethodDescriptor.ofConstructor(ActionLiteral.class, String.class), new ResultHandle[] { nameMatchesCreator.load(name) });
for (Entry<String, ActionDispatchingConfiguration> eventConfigurationEntry : actionConfiguration.entrySet()) {
String event = eventConfigurationEntry.getKey();
ActionDispatchingConfiguration eventDispatchingConfiguration = eventConfigurationEntry.getValue();
if (EventDefinition.ALL.equals(event)) {
ResultHandle annotationLiteralArrayRh = nameMatchesCreator.newArray(Annotation.class, 1);
nameMatchesCreator.writeArrayValue(annotationLiteralArrayRh, 0, actionAnnotationLiteralRh);
fireEvent(nameMatchesCreator, gitHubEventHandlerClassCreator.getClassName(), gitHubEventRh, annotationLiteralArrayRh);
continue;
}
BytecodeCreator eventMatchesCreator = nameMatchesCreator.ifTrue(nameMatchesCreator.invokeVirtualMethod(MethodDescriptors.OBJECT_EQUALS, nameMatchesCreator.load(event), dispatchedEventRh)).trueBranch();
for (Entry<String, EventAnnotation> eventAnnotationEntry : eventDispatchingConfiguration.getEventAnnotations().entrySet()) {
String action = eventAnnotationEntry.getKey();
EventAnnotation eventAnnotation = eventAnnotationEntry.getValue();
Class<?>[] literalParameterTypes = new Class<?>[eventAnnotation.getValues().size()];
Arrays.fill(literalParameterTypes, String.class);
List<ResultHandle> literalParameters = new ArrayList<>();
ResultHandle eventAnnotationLiteralRh = eventMatchesCreator.newInstance(MethodDescriptor.ofConstructor(getLiteralClassName(eventAnnotation.getName()), (Object[]) literalParameterTypes), literalParameters.toArray(ResultHandle[]::new));
ResultHandle annotationLiteralArrayRh = eventMatchesCreator.newArray(Annotation.class, 2);
eventMatchesCreator.writeArrayValue(annotationLiteralArrayRh, 0, actionAnnotationLiteralRh);
eventMatchesCreator.writeArrayValue(annotationLiteralArrayRh, 1, eventAnnotationLiteralRh);
if (Actions.ALL.equals(action)) {
fireEvent(eventMatchesCreator, gitHubEventHandlerClassCreator.getClassName(), gitHubEventRh, annotationLiteralArrayRh);
} else {
BytecodeCreator actionMatchesCreator = eventMatchesCreator.ifTrue(eventMatchesCreator.invokeVirtualMethod(MethodDescriptors.OBJECT_EQUALS, eventMatchesCreator.load(action), dispatchedActionRh)).trueBranch();
fireEvent(actionMatchesCreator, gitHubEventHandlerClassCreator.getClassName(), gitHubEventRh, annotationLiteralArrayRh);
}
}
}
}
handleMethodCreator.returnValue(null);
gitHubEventHandlerClassCreator.close();
}
Aggregations