diff --git a/src/main/java/com/oracle/dragon/model/LocalDragonConfiguration.java b/src/main/java/com/oracle/dragon/model/LocalDragonConfiguration.java index 0d3bb54..0ebf4cd 100644 --- a/src/main/java/com/oracle/dragon/model/LocalDragonConfiguration.java +++ b/src/main/java/com/oracle/dragon/model/LocalDragonConfiguration.java @@ -3,6 +3,7 @@ public class LocalDragonConfiguration { private String redirect; + private String ocid; private String databaseServiceURL; private String sqlDevWebAdmin; private String sqlDevWeb; @@ -158,4 +159,12 @@ public String getRedirect() { public void setRedirect(String redirect) { this.redirect = redirect; } + + public String getOcid() { + return ocid; + } + + public void setOcid(String ocid) { + this.ocid = ocid; + } } diff --git a/src/main/java/com/oracle/dragon/stacks/CodeGenerator.java b/src/main/java/com/oracle/dragon/stacks/CodeGenerator.java index 9aa9974..8ef4be9 100644 --- a/src/main/java/com/oracle/dragon/stacks/CodeGenerator.java +++ b/src/main/java/com/oracle/dragon/stacks/CodeGenerator.java @@ -40,14 +40,18 @@ public class CodeGenerator { private final String name; private final String override; private final LocalDragonConfiguration localConfiguration; + private final String profileName; + private final String configFilename; private DSSession.Section section; private StackMetadata stackMetadata; - public CodeGenerator(StackType type, String name, String override, LocalDragonConfiguration localConfiguration) { + public CodeGenerator(StackType type, String name, String override, LocalDragonConfiguration localConfiguration, String profileName, String configFilename) { this.type = type; this.name = name; this.override = override; this.localConfiguration = localConfiguration; + this.profileName = profileName; + this.configFilename = configFilename; } public void work() throws DSException { @@ -122,6 +126,8 @@ public void work() throws DSException { st.add("override", override); st.add("executable", EXECUTABLE_NAME); st.add("envRequirement", envRequirement); + st.add("profile",profileName); + st.add("dragonConfigFilename",configFilename); System.out.println(st.render()); @@ -199,6 +205,8 @@ public void work() throws DSException { st.add("stackName", name); st.add("config", localConfiguration); st.add("dbNameLower", localConfiguration.getDbName().toLowerCase()); + st.add("profile",profileName); + st.add("dragonConfigFilename",configFilename); for (String key : patchParameters.keySet()) { st.add(key, patchParameters.get(key)); @@ -268,6 +276,8 @@ public void work() throws DSException { st.add("path", dest.getAbsolutePath()); st.add("executable", EXECUTABLE_NAME); st.add("envRequirement", envRequirement); + st.add("profile",profileName); + st.add("dragonConfigFilename",configFilename); for (String key : patchParameters.keySet()) { st.add(key, patchParameters.get(key)); @@ -394,6 +404,8 @@ private void extractFileContent(String path, File parent, InputStream inputStrea st.add("stackName", name); st.add("config", localConfiguration); st.add("dbNameLower", localConfiguration.getDbName().toLowerCase()); + st.add("profile",profileName); + st.add("dragonConfigFilename",configFilename); try (PrintWriter out = new PrintWriter(new BufferedOutputStream(new FileOutputStream(new File(parent, realFilename))))) { out.print(st.render()); diff --git a/src/main/java/com/oracle/dragon/stacks/EnvironmentRequirement.java b/src/main/java/com/oracle/dragon/stacks/EnvironmentRequirement.java index 040c6b1..2e9be69 100644 --- a/src/main/java/com/oracle/dragon/stacks/EnvironmentRequirement.java +++ b/src/main/java/com/oracle/dragon/stacks/EnvironmentRequirement.java @@ -1,16 +1,14 @@ package com.oracle.dragon.stacks; -import com.oracle.dragon.stacks.requirements.JDKRequirement; -import com.oracle.dragon.stacks.requirements.NodeRequirement; -import com.oracle.dragon.stacks.requirements.Requirement; -import com.oracle.dragon.stacks.requirements.SQLCLRequirement; +import com.oracle.dragon.stacks.requirements.*; import com.oracle.dragon.util.DSSession; public enum EnvironmentRequirement { jdk11(new JDKRequirement(11)), //jdk8(new JDKRequirement(8)), node14(new NodeRequirement(14)), - sqlcl(new SQLCLRequirement(21)); + sqlcl(new SQLCLRequirement(21)), + mvn(new MavenRequirement("3.8.1")); private final Requirement req; diff --git a/src/main/java/com/oracle/dragon/stacks/StackType.java b/src/main/java/com/oracle/dragon/stacks/StackType.java index 30ec811..0bdcdd4 100644 --- a/src/main/java/com/oracle/dragon/stacks/StackType.java +++ b/src/main/java/com/oracle/dragon/stacks/StackType.java @@ -7,7 +7,7 @@ public enum StackType { REACT("React", "create-react-app", null), JET("Oracle JavaScript Extension Toolkit", "create-jet-app", null), SPRINGBOOTPETCLINIC("Spring Boot","create-spring-boot-petclinic", new SpringBootPetclinicCodePatcher()), - MICRO_SERVICE("Micro Service","create-micro-service", null); + MICRO_SERVICE("Microservice","create-micro-service", null); public final String resourceDir; public final String humanName; diff --git a/src/main/java/com/oracle/dragon/stacks/requirements/JDKRequirement.java b/src/main/java/com/oracle/dragon/stacks/requirements/JDKRequirement.java index 56cbf22..640bccb 100644 --- a/src/main/java/com/oracle/dragon/stacks/requirements/JDKRequirement.java +++ b/src/main/java/com/oracle/dragon/stacks/requirements/JDKRequirement.java @@ -30,7 +30,7 @@ public boolean isPresent(DSSession.Platform platform) { String javaVersion = (String) properties.get("JAVA_VERSION"); if (!Strings.isNullOrEmpty(javaVersion)) { - javaVersion = javaVersion.replaceAll("\"", ""); + javaVersion = javaVersion.replaceAll("\"", "").split("_")[0]; } Version version = new Version(javaVersion); @@ -52,7 +52,7 @@ public boolean isPresent(DSSession.Platform platform) { throw new RuntimeException(pb + " (" + p.exitValue() + "):\n" + getProcessOutput(p.getInputStream()).toString()); } - return new Version(sb.toString().split("\n")[0].split(" ")[2].replaceAll("\"", "")).getMajor() >= majorVersion; + return new Version(sb.toString().split("\n")[0].split(" ")[2].replaceAll("\"", "").split("_")[0]).getMajor() >= majorVersion; } catch (IOException | InterruptedException ignored) { } diff --git a/src/main/java/com/oracle/dragon/stacks/requirements/MavenRequirement.java b/src/main/java/com/oracle/dragon/stacks/requirements/MavenRequirement.java new file mode 100644 index 0000000..d693d22 --- /dev/null +++ b/src/main/java/com/oracle/dragon/stacks/requirements/MavenRequirement.java @@ -0,0 +1,87 @@ +package com.oracle.dragon.stacks.requirements; + +import com.google.common.base.Strings; +import com.oracle.dragon.model.Version; +import com.oracle.dragon.util.DSSession; + +import java.io.IOException; + +public class MavenRequirement extends AbstractRequirement { + private final String version; + + public MavenRequirement(String version) { + this.version = version; + } + + @Override + public boolean isPresent(DSSession.Platform platform) { + // Check M2_HOME/release file + final String m2Home = System.getenv("M2_HOME"); + + if (!Strings.isNullOrEmpty(m2Home)) { + final Version currentVersion = new Version(m2Home.substring(m2Home.lastIndexOf('-')+1)); + final Version expectedVersion = new Version(version); + + return currentVersion.compareTo(expectedVersion) >= 0; + } + + final ProcessBuilder pb = new ProcessBuilder("mvn", "--version") + .redirectErrorStream(true); + + try { + final Process p = pb.start(); + final StringBuilder sb = getProcessOutput(p.getInputStream()); + int a = p.waitFor(); + if (a != 0) { + throw new RuntimeException(pb + " (" + p.exitValue() + "):\n" + getProcessOutput(p.getInputStream()).toString()); + } + + final String header = sb.toString().split("\n")[0]; + final Version currentVersion = new Version(header.split(" ")[2]); + + final Version expectedVersion = new Version(version); + + return currentVersion.compareTo(expectedVersion) >= 0; + } catch (IOException | InterruptedException ignored) { + } + + return false; + } + + @Override + public String[] getCommands(DSSession.Platform platform, boolean ociCloudShell) { + switch (platform) { + case Linux: + case LinuxARM: + return new String[]{ + "wget https://mirrors.ircam.fr/pub/apache/maven/maven-3/"+version+"/binaries/apache-maven-"+version+"-bin.tar.gz", + "tar -xvf apache-maven-"+version+"-bin.tar.gz", + "export M2_HOME=\"`pwd`/apache-maven-"+version+"\"", + "export PATH=${M2_HOME}/bin:$PATH" + }; + + case Windows: + return new String[]{ + "powershell wget https://mirrors.ircam.fr/pub/apache/maven/maven-3/"+version+"/binaries/apache-maven-"+version+"-bin.zip -OutFile apache-maven-"+version+"-bin.zip", + "powershell Expand-Archive -Path apache-maven-"+version+"-bin.zip -DestinationPath .\\", + "set M2_HOME=%CD%\\apache-maven-"+version, + "set PATH=%M2_HOME%\\bin:%PATH%" + }; + + case MacOS: + return new String[]{ + "curl -L -O https://mirrors.ircam.fr/pub/apache/maven/maven-3/"+version+"/binaries/apache-maven-"+version+"-bin.tar.gz", + "tar -xvf apache-maven-"+version+"-bin.tar.gz", + "export M2_HOME=\"`pwd`/apache-maven-"+version+"\"", + "export PATH=${M2_HOME}/bin:$PATH" + }; + } + + return new String[]{"No command"}; + } + + @Override + public String getDescription() { + return "To install Maven version " + version + ", please follow these instructions:"; + } +} diff --git a/src/main/java/com/oracle/dragon/util/DSSession.java b/src/main/java/com/oracle/dragon/util/DSSession.java index 6a8e8f6..14fd902 100644 --- a/src/main/java/com/oracle/dragon/util/DSSession.java +++ b/src/main/java/com/oracle/dragon/util/DSSession.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Strings; import com.oracle.bmc.auth.AuthenticationDetailsProvider; -import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider; import com.oracle.bmc.database.DatabaseClient; import com.oracle.bmc.database.DatabaseWaiters; import com.oracle.bmc.database.model.*; @@ -68,7 +67,7 @@ public class DSSession { /** * Current version. */ - public static final String VERSION = "2.1.1"; + public static final String VERSION = "2.2.0"; public static final String CONFIGURATION_FILENAME = "dragon.config"; public static final String LOCAL_CONFIGURATION_FILENAME = "local_dragon.config.json"; @@ -277,12 +276,11 @@ enum LicenseType { final String osArchitecture = System.getProperty("os.arch").toLowerCase(); - if(osArchitecture.equals("aarch64")) { + if (osArchitecture.equals("aarch64")) { platform = Platform.LinuxARM; OCICloudShell = false; - } - else { + } else { platform = Platform.Linux; if (System.getenv("CLOUD_SHELL_TOOL_SET") != null && System.getenv("OCI_REGION") != null && System.getenv("OCI_TENANCY") != null) { @@ -442,7 +440,7 @@ public void analyzeCommandLineParameters(String[] args) throws DSException { case "-ct": case "--ct": section.printlnOK(); - final boolean hasToCreateKeys = checkForArgument(args, new String[]{"-create-keys", "--create-keys","-ck","--ck"}); + final boolean hasToCreateKeys = checkForArgument(args, new String[]{"-create-keys", "--create-keys", "-ck", "--ck"}); printlnConfigurationTemplate(hasToCreateKeys, Section.CreateKeys); System.exit(0); break; @@ -567,7 +565,7 @@ private void displayUsage() { println(ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "create" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "react" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "app" + ANSI_RESET + " [name] \tcreates a " + ANSI_VSC_BLUE + "React" + ANSI_RESET + " frontend (default name: frontend, overrides supported)"); println(ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "create" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "jet" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "app" + ANSI_RESET + " [name] \tcreates an " + ANSI_BRIGHT_RED + "Oracle JET" + ANSI_RESET + " frontend (default name: frontend)"); println(ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "create" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "spring" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "boot" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "petclinic" + ANSI_RESET + " [name]\tcreates the " + ANSI_BRIGHT_GREEN + "Spring Boot" + ANSI_RESET + " Petclinic (default name: petclinic)"); - println(ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "create" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "micro" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "service" + ANSI_VSC_DASH + ANSI_RESET + " [name] \tcreates a " + ANSI_BRIGHT_WHITE + "Micro Service" + ANSI_RESET + " (default name: backend, overrides supported)"); + println(ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "create" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "micro" + ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "service" + ANSI_VSC_DASH + ANSI_RESET + " [name] \tcreates a " + ANSI_BRIGHT_WHITE + "Microservice" + ANSI_RESET + " (default name: backend, overrides supported)"); println(" \t . If supported, overrides default stack using #, examples:"); println(" \t . -create-react-app#lab2"); println(" \t . -create-micro-service#json-po-generator "); @@ -578,7 +576,7 @@ private void displayUsage() { try { final String latestVersion = upgradeOrGetLastVersion(false); if (!VERSION.equals(latestVersion) && Version.isAboveVersion(latestVersion, VERSION)) { - println(ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "upgrade" + ANSI_RESET + " \tto download the latest version for your platform: v" + latestVersion); + println(ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "upgrade" + ANSI_RESET + " \tto download the " + ANSI_BRIGHT + "latest version for your platform: v" + latestVersion + ANSI_RESET); } else { println(ANSI_VSC_DASH + "-" + ANSI_VSC_BLUE + "upgrade" + ANSI_RESET + " \tto download the latest version for your platform... but you're already up to date :)"); } @@ -1036,7 +1034,7 @@ public void work() throws DSException { } if ((operation == Operation.CreateDatabase || operation == Operation.LoadDataJSON) && createStack) { - final CodeGenerator c = new CodeGenerator(stackType, stackName, stackOverride, localConfiguration); + final CodeGenerator c = new CodeGenerator(stackType, stackName, stackOverride, localConfiguration, profileName, this.configFile.getConfigFilename()); c.work(); } } @@ -1949,7 +1947,9 @@ private String getConfigurationAsJSON(AutonomousDatabase adb, ADBRESTService rSQ } private String getConfigurationAsJSON(AutonomousDatabase adb, ADBRESTService rSQLS, boolean local, File walletFile) { - return String.format("{\"databaseServiceURL\": \"%s\",\n" + + return String.format("{\n" + + "\"ocid\": \"%s\",\n" + + "\"databaseServiceURL\": \"%s\",\n" + "\"sqlDevWebAdmin\": \"%s\",\n" + "\"sqlDevWeb\": \"%s\",\n" + "\"apexURL\": \"%s\",\n" + @@ -1963,6 +1963,7 @@ private String getConfigurationAsJSON(AutonomousDatabase adb, ADBRESTService rSQ (local ? ",\n\"dbName\": \"%s\",\n\"dbUserName\": \"%s\",\n\"dbUserPassword\": \"%s\"" + (walletFile != null ? ",\n\"walletFile\": \"%s\",\n\"extractedWallet\": \"%s\"" : "%s%s") : "") + "}", + adb.getId(), adb.getServiceConsoleUrl(), adb.getConnectionUrls().getSqlDevWebUrl(), adb.getConnectionUrls().getSqlDevWebUrl().replaceAll("admin", databaseUserName.toLowerCase()), diff --git a/src/main/java/com/oracle/dragon/util/io/DRAGONConfigFile.java b/src/main/java/com/oracle/dragon/util/io/DRAGONConfigFile.java index 3de5b4d..5f6df44 100644 --- a/src/main/java/com/oracle/dragon/util/io/DRAGONConfigFile.java +++ b/src/main/java/com/oracle/dragon/util/io/DRAGONConfigFile.java @@ -23,6 +23,7 @@ public static ConfigFile parse(File workingDirectory, String configurationFilePa final File configFile = new File(workingDirectory, configurationFilePath); final ConfigFile config = parse(configFile.getAbsolutePath(), new FileInputStream(configFile), profile, StandardCharsets.UTF_8); config.setWorkingDirectory(workingDirectory,profile); + config.setConfigFilename(configFile.getCanonicalPath()); return config; } @@ -54,6 +55,7 @@ public static final class ConfigFile { private final String profile; private final String configurationFilePath; private File workingDirectory; + private String configFilename; public ConfigFile(ConfigAccumulator accumulator, String profile, String configurationFilePath) { this.accumulator = accumulator; @@ -139,6 +141,14 @@ public void setWorkingDirectory(File workingDirectory, String profile) { accumulator.configurationsByProfile.get(profile).put("key_file",keyFilename); } } + + public void setConfigFilename(String configFilename) { + this.configFilename = configFilename.replace('\\', '/'); + } + + public String getConfigFilename() { + return configFilename; + } } private static final class ConfigAccumulator { diff --git a/src/main/resources/stacks/create-micro-service/message.st b/src/main/resources/stacks/create-micro-service/message.st index 2b565ab..4b9b72e 100644 --- a/src/main/resources/stacks/create-micro-service/message.st +++ b/src/main/resources/stacks/create-micro-service/message.st @@ -1,6 +1,6 @@ Success! Created at -We suggest that you override this micro service with one of the existing samples: +We suggest that you override this microservice with one of the existing samples:  -create-micro-service#json-po-generator  diff --git a/src/main/resources/stacks/create-spring-boot-petclinic/metadata.json b/src/main/resources/stacks/create-spring-boot-petclinic/metadata.json index a98c6ac..371af30 100644 --- a/src/main/resources/stacks/create-spring-boot-petclinic/metadata.json +++ b/src/main/resources/stacks/create-spring-boot-petclinic/metadata.json @@ -1,5 +1,5 @@ { - "requires": ["jdk11"], + "requires": ["jdk11","mvn"], "url": "https://github.com/spring-projects/spring-petclinic/archive/main.zip", "skipDirectoryLevel": 1, "files": [