Skip to content

Commit

Permalink
Added the mokamint-application start command
Browse files Browse the repository at this point in the history
  • Loading branch information
spoto committed Feb 28, 2024
1 parent c3d81ed commit 9f2674a
Show file tree
Hide file tree
Showing 15 changed files with 332 additions and 30 deletions.
2 changes: 1 addition & 1 deletion io-mokamint-application-tools/mokamint-application
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"

DIR=$DIR"/.."

java --module-path $DIR/modules/explicit:$DIR/modules/automatic --class-path $DIR"/modules/unnamed/*" --module io.mokamint.application.tools/io.mokamint.application.tools.MokamintApplication "$@"
java --module-path $DIR/modules/explicit:$DIR/modules/automatic --class-path $DIR"/modules/unnamed/*" --add-modules org.glassfish.tyrus.container.grizzly.server --module io.mokamint.application.tools/io.mokamint.application.tools.MokamintApplication "$@"
2 changes: 1 addition & 1 deletion io-mokamint-application-tools/mokamint-application.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
set SOURCE=%~dp0
set DIR=%SOURCE%

java --module-path "%DIR%modules\explicit";"%DIR%modules\automatic" --class-path "%DIR%modules\unnamed\*" --module io.mokamint.application.tools/io.mokamint.application.tools.MokamintApplication %*
java --module-path "%DIR%modules\explicit";"%DIR%modules\automatic" --class-path "%DIR%modules\unnamed\*" --add-modules org.glassfish.tyrus.container.grizzly.server --module io.mokamint.application.tools/io.mokamint.application.tools.MokamintApplication %*
7 changes: 6 additions & 1 deletion io-mokamint-application-tools/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<dependencies>
<dependency>
<groupId>io.mokamint</groupId>
<artifactId>io-mokamint-application-api</artifactId>
<artifactId>io-mokamint-application</artifactId>
<version>${mokamint.version}</version>
</dependency>
<dependency>
Expand All @@ -29,6 +29,11 @@
<artifactId>io-mokamint-tools</artifactId>
<version>${mokamint.version}</version>
</dependency>
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-client-api</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.mokamint.application.tools;

import io.mokamint.application.tools.internal.List;
import io.mokamint.application.tools.internal.Start;
import io.mokamint.tools.AbstractTool;
import picocli.CommandLine.Command;

Expand All @@ -32,7 +33,8 @@
header = "This is the command-line tool for Mokamint applications.",
footer = "Copyright (c) 2024 Fausto Spoto",
subcommands = {
List.class
List.class,
Start.class
}
)
public class MokamintApplication extends AbstractTool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
package io.mokamint.application.tools.internal;

import java.time.LocalDateTime;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
import java.util.concurrent.TimeoutException;

import io.hotmoka.closeables.api.OnCloseHandler;
import io.mokamint.application.Applications;
import io.mokamint.application.api.Application;
import io.mokamint.application.api.ApplicationException;
import io.mokamint.application.api.Description;
Expand All @@ -32,6 +32,7 @@
import io.mokamint.node.api.Transaction;
import io.mokamint.nonce.api.Deadline;
import io.mokamint.tools.AbstractCommand;
import io.mokamint.tools.AbstractRow;
import io.mokamint.tools.AbstractTable;
import io.mokamint.tools.CommandException;
import io.mokamint.tools.Table;
Expand All @@ -52,7 +53,7 @@ protected void execute() throws CommandException {
new MyTable().print();
}

private static class Row implements io.mokamint.tools.Row {
private static class Row extends AbstractRow {
private final String name;
private final String className;
private final String description;
Expand Down Expand Up @@ -95,7 +96,7 @@ public String toString(int pos, Table table) {
private class MyTable extends AbstractTable {
private MyTable() {
super(new Row("name", "class", "description"), 3, json);
ServiceLoader.load(Application.class).stream().forEach(this::add);
Applications.available().forEach(this::add);
}

private void add(Provider<Application> provider) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
Copyright 2024 Fausto Spoto
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package io.mokamint.application.tools.internal;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;

import io.mokamint.application.Applications;
import io.mokamint.application.api.ApplicationException;
import io.mokamint.application.service.ApplicationServices;
import io.mokamint.tools.AbstractCommand;
import io.mokamint.tools.CommandException;
import jakarta.websocket.DeploymentException;
import picocli.CommandLine.Command;
import picocli.CommandLine.Help.Ansi;
import picocli.CommandLine.Parameters;

@Command(name = "start",
description = "Start a network service for an application.",
showDefaultValues = true)
public class Start extends AbstractCommand {

@Parameters(index = "0", description = "the name of the application to start")
private String application;

@Parameters(index = "1", description = "the port number where the service to the application will be published", defaultValue = "8050")
private int port;

private final static Logger LOGGER = Logger.getLogger(Start.class.getName());

@Override
protected void execute() throws CommandException {
System.out.print("Publishing a service for application " + application + " at ws://localhost:" + port + "... ");

try (var app = Applications.load(application); var service = ApplicationServices.open(app, port)) {
System.out.println(Ansi.AUTO.string("@|blue done.|@"));

try (var reader = new BufferedReader(new InputStreamReader(System.in))) {
System.out.print(Ansi.AUTO.string("@|green Press ENTER to stop the application service: |@"));
reader.readLine();
}
catch (IOException e) {
System.out.println(Ansi.AUTO.string("@|red Cannot access the standard input!|@"));
LOGGER.log(Level.WARNING, "cannot access the standard input", e);
}
}
catch (DeploymentException | IOException e) {
throw new CommandException("Failed to open the application service. Is port " + port + " available?", e);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new CommandException("The application service has been interrupted", e);
}
catch (ApplicationException e) {
throw new CommandException("The application is misbehaving", e);
}
}
}
6 changes: 3 additions & 3 deletions io-mokamint-application-tools/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@

// TODO: remove at the end
provides io.mokamint.application.api.Application with io.mokamint.application.tools.internal.List.App1, io.mokamint.application.tools.internal.List.App42;
uses io.mokamint.application.api.Application;

requires io.mokamint.application.api;
//requires io.mokamint.application.service;
requires io.mokamint.application;
requires io.mokamint.application.service;
requires io.mokamint.tools;
requires jakarta.websocket.client;
requires java.logging;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
Copyright 2024 Fausto Spoto
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package io.mokamint.application;

import java.util.ServiceLoader.Provider;
import java.util.stream.Stream;

import io.mokamint.application.api.Application;
import io.mokamint.application.internal.ApplicationLoader;

/**
* Provider of applications.
*/
public abstract class Applications {

private Applications() {}

/**
* Loads from the module path the application with the given name.
*
* @return the application
* @throws IllegalArgumentException if there is no application with the given name
* or if there is more than one
*/
public static Application load(String name) {
return ApplicationLoader.load(name);
}

/**
* Yields the providers of the applications accessible from the module path.
*
* @return the providers
*/
public static Stream<Provider<Application>> available() {
return ApplicationLoader.available();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
Copyright 2024 Fausto Spoto
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package io.mokamint.application.internal;

import java.util.List;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import io.mokamint.application.api.Application;
import io.mokamint.application.api.Name;

/**
* A loader of an application from the module path.
*/
public class ApplicationLoader {

/**
* Loads from the module path the application with the given name.
*
* @return the application
* @throws IllegalArgumentException if there is no application with the given name
* or if there is more than one
*/
public static Application load(String name) {
List<Provider<Application>> providers = available()
.filter(app -> provides(name, app))
.collect(Collectors.toList());

if (providers.size() == 0)
throw new IllegalArgumentException("There are no providers for application " + name);
else if (providers.size() > 1)
throw new IllegalArgumentException("There is more than one provider for application " + name);

return providers.get(0).get();
}

/**
* Yields the providers of the applications accessible from the module path.
*
* @return the providers
*/
public static Stream<Provider<Application>> available() {
return ServiceLoader.load(Application.class).stream();
}

private static boolean provides(String name, ServiceLoader.Provider<Application> provider) {
Name ann = provider.type().getAnnotation(Name.class);
return ann != null && name.equals(ann.value());
}
}
2 changes: 2 additions & 0 deletions io-mokamint-application/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@
requires transitive io.mokamint.application.api;
requires io.hotmoka.closeables;
requires io.hotmoka.annotations;

uses io.mokamint.application.api.Application;
}
5 changes: 5 additions & 0 deletions io-mokamint-node-tools/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@
<version>${mokamint.version}</version>
</dependency>
<dependency>
<groupId>io.mokamint</groupId>
<artifactId>io-mokamint-application</artifactId>
<version>${mokamint.version}</version>
</dependency>
<dependency>
<groupId>io.hotmoka</groupId>
<artifactId>io-hotmoka-exceptions</artifactId>
<version>${hotmoka.version}</version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,12 @@
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import io.hotmoka.crypto.Entropies;
import io.mokamint.application.Applications;
import io.mokamint.application.api.Application;
import io.mokamint.application.api.Name;
import io.mokamint.miner.local.LocalMiners;
import io.mokamint.node.api.DatabaseException;
import io.mokamint.node.api.NodeException;
Expand Down Expand Up @@ -374,17 +371,13 @@ private Application mkApplication() throws CommandException {

if (application != null) {
System.out.print("Creating the " + application + " application... ");
ServiceLoader<Application> serviceLoader = ServiceLoader.load(Application.class);
List<Provider<Application>> providers = serviceLoader.stream()
.filter(this::providesRequiredApplication)
.collect(Collectors.toList());

if (providers.size() == 0)
throw new CommandException("There are no providers for application " + application);
else if (providers.size() > 1)
throw new CommandException("There is more than one provider for application " + application);

app = providers.get(0).get();
try {
app = Applications.load(application);
}
catch (IllegalArgumentException e) {
throw new CommandException(e.getMessage());
}
}
else {
System.out.print("Connecting to the application at " + applicationUri + "... ");
Expand All @@ -395,11 +388,6 @@ else if (providers.size() > 1)
return app;
}

private boolean providesRequiredApplication(ServiceLoader.Provider<Application> provider) {
Name ann = provider.type().getAnnotation(Name.class);
return ann != null && application.equals(ann.value());
}

private void waitForKeyPress() throws CommandException {
try (var reader = new BufferedReader(new InputStreamReader(System.in))) {
System.out.print(Ansi.AUTO.string("@|green Press any key to stop the node.|@"));
Expand Down
2 changes: 1 addition & 1 deletion io-mokamint-node-tools/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@
requires io.mokamint.node.remote;
requires io.mokamint.plotter;
requires io.mokamint.tools;
requires io.mokamint.application;
requires io.mokamint.node.service;
requires io.hotmoka.crypto;
requires io.hotmoka.exceptions;
requires io.hotmoka.websockets.beans;
requires com.google.gson;
requires java.logging;

uses io.mokamint.application.api.Application;
provides io.mokamint.application.api.Application with io.mokamint.node.tools.internal.EmptyApplication;
}

0 comments on commit 9f2674a

Please sign in to comment.