web-dev-qa-db-fra.com

comment construire la commande de console dans l'application web de démarrage de printemps en utilisant le shell de printemps?

J'ai créé une application Web reposante en utilisant un démarreur Web à ressort qui fonctionne bien. Je peux y accéder via des URL.

Mais j'ai besoin de créer une commande de console qui peut calculer et stocker certaines valeurs au niveau du backend. Je veux pouvoir exécuter la commande de console manuellement ou via le script bash.

Je n'ai trouvé aucune documentation sur la façon d'intégrer le projet Spring-Shell dans l'application Web Spring Boot.

Il n'y a pas non plus d'option pour choisir la dépendance Spring-Shell dans le démarreur à démarrage à ressort https://start.spring.io/

1) La webapp et la console doivent-elles être deux applications distinctes et dois-je les déployer séparément?

2) Est-il possible de déployer une application Web et d'exécuter des commandes de console dans la même application?

3) Quelle est la meilleure approche pour partager du code commun (modèle, services, entités, logique métier) entre Shell et les applications Web?

Quelqu'un peut-il m'aider à ce sujet?

13
vishal

Voici 2 options:

(1) API Rest appelée depuis la ligne de commande

Vous pouvez créer un ressort @RestController, que vous appelez ensuite depuis la ligne de commande?

curl -X POST -i -H "Content-type: application/json" -c cookies.txt -X POST http://hostname:8080/service -d '
    {
        "field":"value",
        "field2":"value2"
    }
    '

Vous pouvez facilement l'intégrer dans un script Nice Shell.

(2) Utiliser Spring-boot-remote-Shell (obsolète)

Bien que ce soit principalement à des fins de surveillance/d'administration, vous pouvez utiliser spring-boot-remote-Shell pour cela.

Dépendances

Vous avez besoin des dépendances suivantes pour activer le shell distant:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-remote-Shell</artifactId>
</dependency>
<dependency>
    <groupId>org.crsh</groupId>
    <artifactId>crsh.Shell.telnet</artifactId>
    <version>1.3.0-beta2</version>
</dependency>

Script Groovy :

Ajoutez le script suivant dans src/main/resources/custom.groovy:

package commands

import org.crsh.cli.Command
import org.crsh.cli.Usage
import org.crsh.command.InvocationContext

class custom {

    @Usage("Custom command")
    @Command
    def main(InvocationContext context) {
        return "Hello"
    }
}

Pour obtenir un bean Spring à partir de ce script groovy (source: https://stackoverflow.com/a/24300534/641627 ):

BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
MyController myController = beanFactory.getBean(MyController.class);

Lancez votre SpringBootApp

Avec Spring-boot-remote-Shell sur le chemin de classe, l'application Spring Boot écoute sur le port 5000 (par défaut). Vous pouvez maintenant faire ceci:

$ telnet localhost 5000
Trying ::1...
Connected to localhost.
Escape character is '^]'.
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::  (v1.3.5.RELEASE)

Aide

Vous pouvez taper help pour voir la liste des commandes disponibles:

NAME       DESCRIPTION                                                                                                                                                                 
autoconfig Display auto configuration report from ApplicationContext                                                                                                                   
beans      Display beans in ApplicationContext                                                                                                                                         
cron       manages the cron plugin                                                                                                                                                     
custom     Custom command                                                                                                                                                              
dashboard                                                                                                                                                                              
egrep      search file(s) for lines that match a pattern                                                                                                                               
endpoint   Invoke actuator endpoints                                                                                                                                                   
env        display the term env                                                                                                                                                        
filter     A filter for a stream of map                                                                                                                                                
help       provides basic help                                                                                                                                                         
Java       various Java language commands                                                                                                                                              
jmx        Java Management Extensions                                                                                                                                                  
jul        Java.util.logging commands                                                                                                                                                  
jvm        JVM informations                                                                                                                                                            
less       opposite of more                                                                                                                                                            
log        logging commands                                                                                                                                                            
mail       interact with emails                                                                                                                                                        
man        format and display the on-line manual pages                                                                                                                                 
metrics    Display metrics provided by Spring Boot                                                                                                                                     
Shell      Shell related command                                                                                                                                                       
sleep      sleep for some time                                                                                                                                                         
sort       Sort a map                                                                                                                                                                  
system     vm system properties commands                                                                                                                                               
thread     JVM thread commands 

Appelez notre commande personnalisée

Notre commande personnalisée est répertoriée (la quatrième à partir du haut), vous pouvez l'appeler:

> custom
Hello

Donc, essentiellement, votre crontab ferait un telnet 5000 et exécutez custom

(3) Comment utiliser les arguments et les options (pour répondre à la question dans les commentaires)

Arguments

Pour utiliser des arguments, vous pouvez jeter un œil à la documentation :

class date {
  @Usage("show the current time")
  @Command
  Object main(
     @Usage("the time format")
     @Option(names=["f","format"])
     String format) {
    if (format == null)
      format = "EEE MMM d HH:mm:ss z yyyy";
    def date = new Date();
    return date.format(format);
  }
}

% date -h
% usage: date [-h | --help] [-f | --format]
% [-h | --help]   command usage
% [-f | --format] the time format

% date -f yyyyMMdd

Sous-commande (ou options)

Toujours de leur documentation :

@Usage("JDBC connection")
class jdbc {

  @Usage("connect to database with a JDBC connection string")
  @Command
  public String connect(
          @Usage("The username")
          @Option(names=["u","username"])
          String user,
          @Usage("The password")
          @Option(names=["p","password"])
          String password,
          @Usage("The extra properties")
          @Option(names=["properties"])
          Properties properties,
          @Usage("The connection string")
          @Argument
          String connectionString) {
     ...
  }

  @Usage("close the current connection")
  @Command
  public String close() {
     ...
  }
}

% jdbc connect jdbc:derby:memory:EmbeddedDB;create=true

La dernière commande s'exécute:

  • la commande jdbc
  • avec la sous-commande connect
  • et l'argument jdbc:derby:memory:EmbeddedDB;create=true

Un exemple complet

Ce qui suit contient:

  • un constructeur;
  • une commande avec des arguments;
  • un haricot géré au printemps;
  • une sous-commande avec des arguments.

Le code:

package commands

import org.crsh.cli.Command
import org.crsh.cli.Usage
import org.crsh.command.InvocationContext
import org.springframework.beans.factory.BeanFactory
import com.alexbt.goodies.MyBean

class SayMessage {
    String message;
    SayMessage(){
        this.message = "Hello";
    }

    @Usage("Default command")
    @Command
    def main(InvocationContext context, @Usage("A Parameter") @Option(names=["p","param"]) String param) {
        BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
        MyBean bean = beanFactory.getBean(MyBean.class);
        return message + " " + bean.getValue() + " " + param;
    }

    @Usage("Hi subcommand")
    @Command
    def hi(InvocationContext context, @Usage("A Parameter") @Option(names=["p","param"]) String param) {
        BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
        MyBean bean = beanFactory.getBean(MyBean.class);
        return "Hi " + bean.getValue() + " " + param;
    }
}

> saymsg -p Johnny
> Hello my friend Johnny

> saymsg hi -p Johnny
> Hi my friend Johnny
8
alexbt

Il semble que vous ayez ici deux cas d'utilisation distincts: l'exécution de tâches planifiées et l'exécution de commandes manuellement. D'après ma compréhension, Spring Shell ne fait pas partie de l'écosystème Boot. Vous pouvez écrire une application Spring Shell externe à votre application Web de démarrage, mais elle ne sera pas intégrée à celle-ci. Du moins d'après mon expérience.

Pour le premier cas de tâches planifiées, vous devriez regarder Spring's Scheduler . Vous devriez être en mesure de configurer une application Spring (démarrage ou normale) contenant un planificateur de tâches. Ensuite, vous pouvez configurer vos tâches qui peuvent être planifiées, laissant le planificateur faire le travail.

Pour exécuter manuellement les commandes, vous disposez de quelques options ici. Si vous utilisez Spring Shell, supposez qu'il s'exécute dans son propre processus, externe au processus Spring Boot. Vous devez avoir l'appel de l'application Shell dans l'application de démarrage (en supposant que c'est là que vous voulez travailler) en utilisant des technologies d'invocation de méthodes à distance (par exemple, RMI, REST, etc.).

Une alternative à Spring Shell consiste à intégrer un shell distant dans votre application de démarrage. Essentiellement, vous pouvez utiliser SSH pour vous connecter à votre application de démarrage et définir des commandes d'une manière similaire à Spring Shell. L'avantage est qu'il s'agit du même processus que l'application de démarrage. Vous pouvez donc injecter le Planificateur de tâches et exécuter manuellement les mêmes tâches que celles planifiées. Cela peut être une bonne option si vous souhaitez lancer manuellement les mêmes tâches en cours de planification. Doco pour la console distante est ici .

J'espère que cela t'aides

2
EdH