Обработка аннотации балерины не работает должным образом

Я пытаюсь реализовать простой процессор аннотаций с помощью балерины (jBallerina-1.0.5 в MacOS Catalina). В этом примере мне нужно:

  1. Перебирать доступные resource функции заданного service
  2. Для каждой итерации получайте значения заданного @annotation, как указано в resource.

Например:

...
service my_service on new http:Listener(8080) {
    @my_annonatation {
        value: "my-value-for-resource-1"
    }
    resource function my_resource_1() {}

    @my_annonatation {
        value: "my-value-for-resource-2"
    }
    resource function my_resource_2() {}
}

В соответствии с приведенным выше фрагментом кода service мне нужно получить имена resource как ["my_resource_1", "my_resource_2"] и значение @annotation как my-value-for-resource-1, my-value-for-resource-2 для my_resource_1 и my_resource_2 соответственно.

Мои вопросы:

  1. Как я могу получить resources, определенные в данном service с балериной
  2. Я попытался с function getServiceAnnotations(service serviceType, string annotName, string? moduleName = ()) returns any модуля ballerina/reflect получить значение @annotation. Но он ничего не дает взамен (очевидно, он возвращает пустую строку или может быть нулевым).

Я не вижу ни одной хорошей статьи по обработке аннотаций балерины, за исключением старых предварительных выпусков балерины 0.x 1. Я обнаружил, что модуль ballerina/reflect теперь обновлен 2 3 с предварительных выпусков 0.x как я сравнивал с исходным кодом балерины (но это не упоминается в примечаниях к выпуску балерины 4 ).

А также в статье «Расширение балерины» 5 упоминается альтернативный способ обработка аннотаций через расширения компилятора, которые делегируют операцию Java. Однако у нас есть ограничение на передачу зависимостей Java в файл ballerina central.

Пожалуйста, предложите мне обходной путь, чтобы получить ожидаемый результат, и я высоко ценю код на чистом языке балерины.

Ссылки

  1. Пример обработки аннотаций Ballerina для выпусков 0.9.x
  2. ballerina/reflect из 0.x
  3. ballerina/reflect версии 1.0.5
  4. Примечания к выпуску Ballerina
  5. Расширение балерины

person Channa Jayamuni    schedule 14.12.2019    source источник
comment
Пожалуйста, обратитесь сюда, как мы можем читать аннотации ресурсов и служб, а также приводить аннотации к типу записи. Затем, используя записанный тип, вы можете получить значение аннотации github.com/wso2/product-microgateway/blob/jballerina/components/   -  person Rajith Roshan    schedule 15.12.2019
comment
@RajithRoshan, вы на месте !, я имел в виду исходный код микро-шлюза и успешно скомпилировал его локально, включая ядро ​​микро-шлюза, которое содержит операции обработки аннотаций. Как я обнаружил, микро-шлюз использует другую версию Ballerina, и модуль ballerina/reflect теперь обновлен. Тестирую на jballerina-1.0.5.   -  person Channa Jayamuni    schedule 15.12.2019


Ответы (2)


Обработка аннотаций может выполняться либо во время компиляции, либо во время выполнения. Прямо сейчас (с Ballerina 1.0.5 и более ранними версиями) обработка аннотаций во время компиляции может выполняться только с помощью расширений компилятора, как описано в документе «Extending Ballerina», тогда как доступ к аннотациям во время выполнения может осуществляться с помощью выражение доступа к аннотации или через модуль ballerina/reflect (только те, которые невозможны через выражение доступа к аннотации теперь доступны в модуле ballerina/reflect — хотя это дополнение упоминается в примечаниях к выпуску «Для доступа к значениям аннотаций во время выполнения был введен бинарный оператор .@», тот факт, что это удаляет некоторые функции из модуля ballerina/reflect, похоже, был пропущенный).

https://github.com/ballerina-platform/ballerina-lang/issues/19325 описывает предлагаемую архитектуру подключаемого модуля компилятора Ballerina, которая позволит писать расширения в Ballerina.

Во время выполнения:

  1. Получение имен ресурсов, определенных в службе — IINM в настоящее время невозможно без написания внешнего метода (с использованием Java-взаимодействия). Имена ресурсов неизвестны во время компиляции? Не могли бы вы создать проблему в репозитории ballerina-lang с требованием?

  2. Доступ к аннотациям ресурсов — это можно сделать с помощью метода reflect:getResourceAnnotations

import ballerina/http;
import ballerina/io;
import ballerina/reflect;

type AnnotRecord record {| 
    string value; 
|};

annotation AnnotRecord my_annonatation on resource function;

string[] resourceNames = ["my_resource_1", "my_resource_2"];

service my_service on new http:Listener(8080) {
    @my_annonatation {
        value: "my-value-for-resource-1"
    }
    resource function my_resource_1(http:Caller caller, http:Request request) {}

    @my_annonatation {
        value: "my-value-for-resource-2"
    }
    resource function my_resource_2(http:Caller caller, http:Request request) {}
}

public function main() {
    foreach var resourceName in resourceNames {
        any annot = reflect:getResourceAnnotations(my_service, resourceName, "my_annonatation");
        if annot is AnnotRecord {
            io:println(annot.value);
        }
    }
}
person MaryamZi    schedule 15.12.2019
comment
Спасибо за ответ. И это хорошая идея отправить вопрос, чтобы запросить функцию списка ресурсов в будущем выпуске. Я пробовал с функцией reflect:getResourceAnnotations точно так же. К сожалению, это не работает для меня, и это просто дает мне пустое значение. Сможете ли вы получить ожидаемый результат из приведенного выше фрагмента кода? А какую версию балерины вы сейчас используете? Jballerina-1.0.5 плохо ко мне относится даже из-за приведенного выше кода. - person Channa Jayamuni; 15.12.2019
comment
@ChannaJayamuni Я попробовал это с 1.0.5. ``` $ ballerina -v Ballerina 1.0.5 Спецификация языка 2019R3 ``` Вывод был следующим: ``` $ ballerina run xyz.bal Источник компиляции xyz.bal Генерация исполняемых файлов Запуск исполняемых файлов my-value-for-resource-1 my -value-for-resource-2 [ballerina/http] запустил прослушиватель HTTP/WS 0.0.0.0:8080 ``` Есть ли возможность поделиться кодом, который вы используете? Можете ли вы также подтвердить, определена ли аннотация в том же файле/модуле или в другом? Вы тоже получаете пустое значение для этого образца? - person MaryamZi; 15.12.2019
comment
это странно! это работает для отдельных файлов балерин, но не для проектов балерин. Я поместил тот же код в проект балерины, поэтому я не получаю значение аннотации. Как вы думаете, есть ли какая-то конкретная причина для такого поведения? Или, возможно, мне нужно добавить некоторые конфиги в файл toml? - person Channa Jayamuni; 15.12.2019
comment
Можете ли вы попробовать передать <org-name>/<module-name>:<version> в качестве последнего аргумента функции reflect:getResourceAnnotations? Например, any annot = reflect:getResourceAnnotations(my_service, resourceName, "my_annonatation", "userone/foo:0.1.0"); В идеале этим должен заниматься сам модуль ballerina/reflect. Я создал github.com/ballerina-platform/ballerina-lang/issues/ 20396, чтобы отслеживать это. - person MaryamZi; 15.12.2019
comment
Бум !!! Это сработало как по волшебству! Спасибо @MaryamZi. Я добавил ‹org-name›/‹module-name›:‹version› в функцию. И я ценю, что вы создали проблему для этого. - person Channa Jayamuni; 15.12.2019

ОБНОВЛЕНИЕ:

Решение @MaryamZis хорошо работает для отдельных файлов балерин, но не для проектов балерин. Как она и предложила, я передал <org-name>/<module>:<version> в параметр module функции reflect:getResourceAnnotations, чтобы она заработала.

...
any annot = reflect:getResourceAnnotations(
    my_service, 
    resourceName, 
    "my_annonatation", 
    "my_org/my_module:0.1.0"
);
...

//NOTE: org-name and version are defined in Ballerina.toml of the project

Однако ожидается, что аннотации текущих проектов будут обнаруживаться с помощью reflect функций без указания модуля. Эта проблема зарегистрирована @MaryamZi в репозитории балерины git.

person Channa Jayamuni    schedule 15.12.2019