Подходящий способ реализации приложения cli, которое также использует профиль службы с Micronaut.

У меня нет проблем с созданием REST-сервера или приложения Picocli CLI. Но что, если я хочу иметь оба в одном приложении?

Дело в том, что я хочу иметь приложение, которое обеспечивает некоторую бизнес-логику через REST-сервер (нет проблем), но в некоторых других случаях я хочу запускать бизнес-логику через CLI без запуска HTTP-сервера (например, для CI/CD). ).

Я не уверен, что у меня возникнут проблемы, если я запущу приложение через PicocliRunner.run(Application.class, args), и если задан конкретный аргумент, запустите сервер с помощью Micronaut.run(Application.class);, поскольку они создают другой контекст.

Кто-нибудь знает правильный способ добиться этого?

Вот как я это решил:

import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.runtime.Micronaut;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;

@Command(
        name = "RestAndCliExample",
        description = "...",
        mixinStandardHelpOptions = true
)
public class Application implements Runnable {
    private enum Mode {serve, run}

    @Parameters(index = "0", description = "Execution mode: ${COMPLETION-CANDIDATES}")
    private Mode mode;

    public static void main(String[] args) throws Exception {
        args = new String[]{"run"};
        PicocliRunner.run(Application.class, args);
    }

    public void run() {
        if (Mode.serve.equals(mode)) {
            // Start REST API
            Micronaut.run(Application.class);
        } else {
            // TODO run code directly
        }
    }
}

person sren    schedule 19.08.2019    source источник


Ответы (1)


Один из способов добиться этого — @Inject добавить ApplicationContext в ваш @Command-аннотированный класс. Это позволяет вашей команде использовать один и тот же контекст приложения вместо необходимости запуска отдельного.

Затем в вашем методе run вы можете запустить сервер REST, получив EmbeddedServer из контекста приложения и вызвав в нем start, или вы можете выполнить функциональность напрямую без сервера REST.

См. также этот ответ для более подробной информации: https://stackoverflow.com/a/56751733/1446916

person Remko Popma    schedule 20.08.2019
comment
Выглядит очень многообещающе, но сервер не запускается после вызова server.start(). Приложение просто закрывается. Я делаю что-то неправильно? - person sren; 20.08.2019
comment
Решил это сейчас с помощью наблюдателя Thread ... но это не самое элегантное решение! Разве Micronaut не может справиться с этим самостоятельно? - person sren; 21.08.2019
comment
Это хороший вопрос. Давайте попробуем привлечь к этому людей из Micronaut. Я спросил на канале Micronaut Gitter. - person Remko Popma; 21.08.2019