Skip to content

Commit

Permalink
feat: #68 Added "up" command. NPM macos initial layout
Browse files Browse the repository at this point in the history
  • Loading branch information
satran004 committed Dec 19, 2024
1 parent b15582b commit ce7c2c1
Show file tree
Hide file tree
Showing 15 changed files with 400 additions and 133 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.bloxbean.cardano.yacicli;

import lombok.RequiredArgsConstructor;
import org.springframework.boot.ApplicationArguments;
import org.springframework.core.annotation.Order;
import org.springframework.shell.ShellRunner;
import org.springframework.shell.jline.InteractiveShellRunner;
import org.springframework.shell.jline.NonInteractiveShellRunner;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
@Order(-100)
public class CustomShellRunner implements ShellRunner {
private final NonInteractiveShellRunner nonInteractiveShellRunner;
private final InteractiveShellRunner interactiveShellRunner;

@Override
public boolean canRun(ApplicationArguments args) {
return true;
}

@Override
public void run(ApplicationArguments args) throws Exception {
boolean canRun = nonInteractiveShellRunner.canRun(args);
if (canRun)
nonInteractiveShellRunner.run(args);

var interactive = args.containsOption("i") || args.containsOption("interactive");

if (interactive) {
interactiveShellRunner.run(args);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
package com.bloxbean.cardano.yacicli;

import com.bloxbean.cardano.yacicli.localcluster.ClusterConfig;
import com.bloxbean.cardano.yacicli.localcluster.config.GenesisConfig;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.shell.jline.NonInteractiveShellRunner;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@SpringBootApplication
@EnableConfigurationProperties(GenesisConfig.class)
Expand All @@ -32,42 +18,6 @@ public static void main(String[] args) {
.run(args);
}

@Component
public class InitBean{
ClusterConfig clusterConfig;
NonInteractiveShellRunner nonInteractiveShellRunner;

public InitBean(ClusterConfig clusterConfig, NonInteractiveShellRunner nonInteractiveShellRunner) {
this.clusterConfig = clusterConfig;
this.nonInteractiveShellRunner = nonInteractiveShellRunner;
}

@PostConstruct
public void initialize() throws IOException {
Path path = Path.of(clusterConfig.getCLIBinFolder());
if (!Files.exists(path))
Files.createDirectories(path);

nonInteractiveShellRunner.setCommandsFromInputArgs(commandsFromInputArgs);
}
}

//Used to parse multiple comma separate commands for NonInteractiveShellRunner
private Function<ApplicationArguments, List<String>> commandsFromInputArgs = args -> {
if (args.getSourceArgs().length == 0) {
return Collections.emptyList();
}

String raw = Arrays.stream(args.getSourceArgs())
.collect(Collectors.joining(" "));
String[] commands = raw.split(",");
for (String cmd: commands) {
if (log.isDebugEnabled())
log.debug("Command: " + cmd);
}
return Arrays.asList(commands);
};

@PreDestroy
public void onShutDown() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,138 @@

import com.bloxbean.cardano.yacicli.commands.common.DownloadService;
import com.bloxbean.cardano.yacicli.commands.common.Groups;
import com.bloxbean.cardano.yacicli.localcluster.ClusterCommands;
import com.bloxbean.cardano.yacicli.localcluster.config.ApplicationConfig;
import com.bloxbean.cardano.yacicli.localcluster.profiles.GenesisProfile;
import lombok.RequiredArgsConstructor;
import org.springframework.shell.Availability;
import org.springframework.shell.standard.*;

import static com.bloxbean.cardano.yacicli.util.ConsoleWriter.error;
import static com.bloxbean.cardano.yacicli.util.ConsoleWriter.writeLn;
import java.util.ArrayList;
import java.util.Arrays;

import static com.bloxbean.cardano.yacicli.util.ConsoleWriter.*;

@ShellComponent
@ShellCommandGroup(Groups.GENERAL_CMD_GROUP)
@RequiredArgsConstructor
public class DownloadCommand {
private final ApplicationConfig applicationConfig;
private final DownloadService downloadService;
private final ClusterCommands clusterCommands;

@ShellMethod(value = "Download", key = "download")
@ShellMethodAvailability("generalCmdAvailability")
public void download(
@ShellOption(value = {"--component", "-c"}, defaultValue = "all", help = "node,ogmios,kupo,yaci-store,yaci-store-jar") String component,
@ShellMethodAvailability({"nonDockerCommandAvailability"})
public boolean download(
@ShellOption(value = {"--component", "-c"}, defaultValue = "all", help = "Provide list of components separated by space. Components: node,ogmios,kupo,yaci-store,yaci-store-jar") String[] components,
@ShellOption(value = {"-o", "--overwrite"}, defaultValue = "false", help = "Overwrite existing installation. default: false") boolean overwrite
) {

try {

if (component == null) {
if (components == null) {
writeLn(error("Component is not provided. Please provide the component to download"));
return;
return false;
}

if (component.equals("node")) {
var componentList = Arrays.asList(components);
boolean validComponent = false;

if (componentList.contains("all") || componentList.contains("node")) {
downloadService.downloadNode(overwrite);
} else if (component.equals("yaci-store")) {
validComponent = true;
}

if (componentList.contains("all") || componentList.contains("yaci-store")) {
downloadService.downloadYaciStoreNative(overwrite);
} else if (component.equals("yaci-store-jar")) {
validComponent = true;
}

if (componentList.contains("all") || componentList.contains("yaci-store-jar")) {
downloadService.downloadYaciStoreJar(overwrite);
} else if (component.equals("ogmios")) {
downloadService.downloadOgmios(overwrite);
} else if (component.equals("kupo")) {
downloadService.downloadKupo(overwrite);
} else if (component.equals("all")) {
downloadService.downloadNode(overwrite);
downloadService.downloadYaciStoreNative(overwrite);
validComponent = true;
}

if (componentList.contains("all") || componentList.contains("ogmios")) {
downloadService.downloadOgmios(overwrite);
validComponent = true;
}

if (componentList.contains("all") || componentList.contains("kupo")) {
downloadService.downloadKupo(overwrite);
} else {
writeLn(error("Invalid component : " + component));
validComponent = true;
}

if (!validComponent) {
writeLn(error("Invalid components : " + componentList));
return false;
}

} catch (Exception e) {
writeLn(error("Error downloading component : " + e.getMessage()));
return false;
}

return true;
}

@ShellMethod(value = "Download and Start DevNet with other selected components", key = "up")
@ShellMethodAvailability({"nonDockerCommandAvailability"})
public void downloadAndStart(
@ShellOption(value = {"--component", "-c"}, defaultValue = "node", help = "Provide list of components separated by space. Components: node,ogmios,kupo,yaci-store,yaci-store-jar") String[] components,
@ShellOption(value = {"-o", "--overwrite"}, defaultValue = "false", help = "Overwrite existing installation. default: false") boolean overwrite,
@ShellOption(value = {"-n", "--name"}, defaultValue = "default", help = "Node Name") String clusterName,
@ShellOption(value = {"--port"}, help = "Node port (Used with --create option only)", defaultValue = "3001") int port,
@ShellOption(value = {"--submit-api-port"}, help = "Submit Api Port", defaultValue = "8090") int submitApiPort,
@ShellOption(value = {"-s", "--slot-length"}, help = "Slot Length in sec. (0.1 to ..)", defaultValue = "1") double slotLength,
@ShellOption(value = {"-b", "--block-time"}, help = "Block time in sec. (1 - 20)", defaultValue = "1") double blockTime,
@ShellOption(value = {"-e", "--epoch-length"}, help = "No of slots in an epoch", defaultValue = "600") int epochLength,
@ShellOption(value = {"--genesis-profile"}, defaultValue = ShellOption.NULL,
help = "Use a pre-defined genesis profile (Options: zero_fee, zero_min_utxo_value, zero_fee_and_min_utxo_value)") GenesisProfile genesisProfile,
@ShellOption(value = {"--enable-yaci-store"}, defaultValue = "false", help = "Enable Yaci Store. This will also enable Ogmios for Tx Evaluation") boolean enableYaciStore,
@ShellOption(value = {"--enable-kupomios"}, defaultValue = "false", help= "Enable Ogmios and Kupo") boolean enableKupomios,
@ShellOption(value = {"--interactive"}, defaultValue="false", help="To start in interactive mode when 'up' command is passed as an arg to yaci-cli") boolean interactive,
@ShellOption(value = {"--tail"}, defaultValue="false", help="To tail the network when 'up' command is passed as an arg to yaci-cli. Only works in non-interactive mode.") boolean tail
) {

if (components == null)
components = new String[0];

var componentList = new ArrayList<>(Arrays.asList(components));

if (enableYaciStore) {
applicationConfig.setYaciStoreEnabled(true);
applicationConfig.setOgmiosEnabled(true);
} else if (enableKupomios){
applicationConfig.setOgmiosEnabled(true);
applicationConfig.setKupoEnabled(true);
}

if (enableYaciStore) {
if (!componentList.contains("yaci-store"))
componentList.add("yaci-store");
if (!componentList.contains("ogmios")) {
componentList.add("ogmios");
}
} else if (enableKupomios) {
if (!componentList.contains("ogmios"))
componentList.add("ogmios");
if (!componentList.contains("kupo"))
componentList.add("kupo");
}

var status = download(componentList.toArray(new String[0]), overwrite);
if (status) {
clusterCommands.createCluster(clusterName, port, submitApiPort, slotLength, blockTime, epochLength,
true, true, null, genesisProfile, false);

if (!interactive && tail)
clusterCommands.ltail(true, true, true, true, true, true, null, null);
}
}

public Availability nonDockerCommandAvailability() {
return !applicationConfig.isDocker()
? Availability.available()
: Availability.unavailable("This command is only supported in non-Docker mode.");
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package com.bloxbean.cardano.yacicli.localcluster.config;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
@Getter
public class ApplicationConfig {
public final static String YACI_STORE_ENABLED = "yaci.store.enabled";
private final static String OGMIOS_ENABLED = "ogmios.enabled";
private final static String KUPO_ENABLED = "kupo.enabled";

private final Environment environment;

@Value("${is.docker:false}")
private boolean isDocker;
Expand All @@ -19,4 +27,31 @@ public class ApplicationConfig {
public void onApplicationEvent(final ServletWebServerInitializedEvent event) {
adminPort = event.getWebServer().getPort();
}

public boolean isYaciStoreEnabled() {
var enabled = environment.getProperty(YACI_STORE_ENABLED, Boolean.class);
return enabled != null? enabled: false;
}

public void setYaciStoreEnabled(boolean flag) {
System.setProperty(YACI_STORE_ENABLED, String.valueOf(flag));
}

public boolean isOgmiosEnabled() {
var enabled = environment.getProperty(OGMIOS_ENABLED, Boolean.class);
return enabled != null? enabled: false;
}

public void setOgmiosEnabled(boolean flag) {
System.setProperty(OGMIOS_ENABLED, String.valueOf(flag));
}

public boolean isKupoEnabled() {
var enabled = environment.getProperty(KUPO_ENABLED, Boolean.class);
return enabled != null? enabled: false;
}

public void setKupoEnabled(boolean flag) {
System.setProperty(KUPO_ENABLED, String.valueOf(flag));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.bloxbean.cardano.yacicli.commands.common.Groups;
import com.bloxbean.cardano.yacicli.common.CommandContext;
import com.bloxbean.cardano.yacicli.localcluster.config.ApplicationConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.shell.Availability;
Expand All @@ -17,6 +18,7 @@
@RequiredArgsConstructor
@Slf4j
public class OgmiosCommands {
private final ApplicationConfig appConfig;
private final OgmiosService ogmiosService;

@ShellMethod(value = "Show recent Ogmios logs", key = "ogmios-logs")
Expand All @@ -33,41 +35,41 @@ public void showKupoLogs() {

@ShellMethod(value = "Enable Ogmios & Kupo")
public void enableKupomios() {
ogmiosService.setEnableOgmios(true);
ogmiosService.setEnableKupo(true);
appConfig.setOgmiosEnabled(true);
appConfig.setKupoEnabled(true);
writeLn(infoLabel("OK", "Ogmios/Kupo Status: Enable"));
}

@ShellMethod(value = "Disble Ogmios & Kupo", key ={ "disable-kupomios", "disable-ogmios-kupo"})
public void disableOgmiosKupo() {
ogmiosService.setEnableOgmios(false);
ogmiosService.setEnableKupo(false);
appConfig.setOgmiosEnabled(false);
appConfig.setKupoEnabled(false);
writeLn(infoLabel("OK", "Ogmios/Kupo Status: Disable"));
}

@ShellMethod(value = "Enable Ogmios")
public void enableOgmios() {
ogmiosService.setEnableOgmios(true);
appConfig.setOgmiosEnabled(true);
writeLn(infoLabel("OK", "Ogmios Status: Enable"));
}

@ShellMethod(value = "Disble Ogmios")
public void disableOgmios() {
ogmiosService.setEnableOgmios(false);
appConfig.setOgmiosEnabled(false);
writeLn(infoLabel("OK", "Ogmios Status: Disable"));
}

@ShellMethod(value = "Check if Ogmios is enabled or disabled")
public void checkOgmiosStatus() {
if (ogmiosService.isEnableOgmios())
if (appConfig.isOgmiosEnabled())
writeLn(info("Ogmios Status: Enable"));
else
writeLn(info("Ogmios Status: disable"));
}

@ShellMethod(value = "Check if Kupo is enabled or disabled")
public void checkKupoStatus() {
if (ogmiosService.isEnableKupo())
if (appConfig.isKupoEnabled())
writeLn(info("Kupo Status: Enable"));
else
writeLn(info("Kupo Status: disable"));
Expand Down
Loading

0 comments on commit ce7c2c1

Please sign in to comment.