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?
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)
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
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:
jdbc
connect
jdbc:derby:memory:EmbeddedDB;create=true
Ce qui suit contient:
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
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