diff --git a/aspire4j/aspire4j-extensions-azure-storage/src/main/java/com/microsoft/aspire/extensions/azure/storage/resources/AzureStorageResource.java b/aspire4j/aspire4j-extensions-azure-storage/src/main/java/com/microsoft/aspire/extensions/azure/storage/resources/AzureStorageResource.java index 1f64acf..8d0600f 100644 --- a/aspire4j/aspire4j-extensions-azure-storage/src/main/java/com/microsoft/aspire/extensions/azure/storage/resources/AzureStorageResource.java +++ b/aspire4j/aspire4j-extensions-azure-storage/src/main/java/com/microsoft/aspire/extensions/azure/storage/resources/AzureStorageResource.java @@ -5,26 +5,22 @@ import com.microsoft.aspire.resources.properties.EndpointReference; import com.microsoft.aspire.DistributedApplicationHelper; import com.microsoft.aspire.resources.traits.ResourceWithEndpoints; +import com.microsoft.aspire.utils.templates.TemplateEngine; -import java.io.IOException; -import java.io.InputStream; +import java.nio.file.Path; import java.util.List; +import java.util.Map; public class AzureStorageResource extends AzureBicepResource implements ResourceWithEndpoints { private static final ResourceType AZURE_STORAGE = ResourceType.fromString("azure.storage.v0"); - private static final String BICEP_TEMPLATE_FILE = "templates/bicep/storage.module.bicep"; - private static final String BICEP_OUTPUT_FILE = "%s.module.bicep"; - - private final String bicepOutputFilename; - public AzureStorageResource(String name) { super(AZURE_STORAGE, name); // This is the path to the output bicep file - bicepOutputFilename = String.format(BICEP_OUTPUT_FILE, name); - withPath(bicepOutputFilename); +// bicepOutputFilename = String.format(BICEP_OUTPUT_FILE, name); +// withPath(bicepOutputFilename); // FIXME just here because I saw other samples with it // withParameter("principalId", ""); @@ -43,20 +39,18 @@ public List getEndpoints() { } @Override - public List processTemplate() { - // read the file from our local resources directory - InputStream resourceAsStream = AzureStorageResource.class.getResourceAsStream(BICEP_TEMPLATE_FILE); - if (resourceAsStream == null) { - throw new RuntimeException("Resource file not found: " + BICEP_TEMPLATE_FILE); - } - try { - String bicepTemplate = new String(resourceAsStream.readAllBytes()); - - // If necessary, modify template variables - - return List.of(new TemplateFileOutput(bicepOutputFilename, bicepTemplate)); - } catch (IOException e) { - throw new RuntimeException(e); - } + public List processTemplate(Path outputPath) { + List templateFiles = List.of( + new TemplateDescriptor("/templates/bicep/storage.module.bicep", "${name}.module.bicep") + ); + + List templateOutput = TemplateEngine.process(AzureStorageResource.class, templateFiles, Map.of( + "name", getName() + )); + + // we know that we need to get the output filename from the first element, and set that as the path + withPath(outputPath.toString()); + + return templateOutput; } } diff --git a/aspire4j/aspire4j-extensions-azure-storage/src/main/java/module-info.java b/aspire4j/aspire4j-extensions-azure-storage/src/main/java/module-info.java index 6dd8d97..f537b9f 100644 --- a/aspire4j/aspire4j-extensions-azure-storage/src/main/java/module-info.java +++ b/aspire4j/aspire4j-extensions-azure-storage/src/main/java/module-info.java @@ -4,10 +4,13 @@ requires transitive com.microsoft.aspire; exports com.microsoft.aspire.extensions.azure.storage; + exports com.microsoft.aspire.extensions.azure.storage.resources; opens com.microsoft.aspire.extensions.azure.storage to org.hibernate.validator, com.fasterxml.jackson.databind; - exports com.microsoft.aspire.extensions.azure.storage.resources; opens com.microsoft.aspire.extensions.azure.storage.resources to com.fasterxml.jackson.databind, org.hibernate.validator; + // We conditionally open up the template files to the apphost, so it can write them out + opens templates.bicep to com.microsoft.aspire; + provides com.microsoft.aspire.Extension with AzureStorageExtension; } \ No newline at end of file diff --git a/aspire4j/aspire4j-extensions-azure-storage/src/main/resources/templates/bicep/storage.module.bicep b/aspire4j/aspire4j-extensions-azure-storage/src/main/resources/templates/bicep/storage.module.bicep index 07c1400..04e48cb 100644 --- a/aspire4j/aspire4j-extensions-azure-storage/src/main/resources/templates/bicep/storage.module.bicep +++ b/aspire4j/aspire4j-extensions-azure-storage/src/main/resources/templates/bicep/storage.module.bicep @@ -11,7 +11,7 @@ param principalType string resource storageAccount_1XR3Um8QY 'Microsoft.Storage/storageAccounts@2022-09-01' = { - name: toLower(take('storage${uniqueString(resourceGroup().id)}', 24)) + name: toLower(take('storage${r"${uniqueString(resourceGroup().id)"}}', 24)) location: location tags: { 'aspire-resource-name': 'storage' diff --git a/aspire4j/aspire4j-extensions-spring/src/main/java/com/microsoft/aspire/extensions/spring/resources/EurekaServiceDiscovery.java b/aspire4j/aspire4j-extensions-spring/src/main/java/com/microsoft/aspire/extensions/spring/resources/EurekaServiceDiscovery.java index 9f159d2..93e4201 100644 --- a/aspire4j/aspire4j-extensions-spring/src/main/java/com/microsoft/aspire/extensions/spring/resources/EurekaServiceDiscovery.java +++ b/aspire4j/aspire4j-extensions-spring/src/main/java/com/microsoft/aspire/extensions/spring/resources/EurekaServiceDiscovery.java @@ -1,27 +1,57 @@ package com.microsoft.aspire.extensions.spring.resources; import com.microsoft.aspire.resources.DockerFile; -import com.microsoft.aspire.resources.ResourceType; import com.microsoft.aspire.resources.traits.ResourceWithTemplate; +import com.microsoft.aspire.utils.templates.TemplateEngine; +import java.nio.file.Path; +import java.util.HashMap; import java.util.List; +import java.util.Map; -public class EurekaServiceDiscovery extends DockerFile - implements ResourceWithTemplate { +public final class EurekaServiceDiscovery extends DockerFile + implements ResourceWithTemplate { + + private final String PROPERTY_NAME = "name"; + private final String PROPERTY_PORT = "port"; + private final String PROPERTY_REGISTER_WITH_EUREKA = "registerWithEureka"; + private final String PROPERTY_FETCH_REGISTRY = "fetchRegistry"; + + private final Map properties; public EurekaServiceDiscovery(String name) { - super(ResourceType.fromString("spring.eureka.server.v0"), name); + super(name); + + this.properties = new HashMap<>(); + this.properties.put(PROPERTY_NAME, name); + this.properties.put(PROPERTY_PORT, 8761); + this.properties.put(PROPERTY_REGISTER_WITH_EUREKA, false); + this.properties.put(PROPERTY_FETCH_REGISTRY, false); + } - // TODO - // We have a template for the eureka server, consisting of a minimal Spring Boot application, as well as - // pom.xml, configuration file, and a Dockerfile to build the image. We need to allow for the template properties - // to be set by the user, such as the port, the name of the service, etc, and then we need to write these out - // to a temporary location, and then build the image from that location. + public EurekaServiceDiscovery withPort(int port) { + this.properties.put(PROPERTY_PORT, port); + return this; } @Override - public List processTemplate() { - return List.of(); + public List processTemplate(Path outputPath) { + final String inPrefix = "/templates/eureka/"; + final String outPrefix = "eureka/"; + List templateFiles = List.of( + new TemplateDescriptor(inPrefix+"pom.xml", outPrefix+"pom.xml"), + new TemplateDescriptor(inPrefix+"Dockerfile", outPrefix+"Dockerfile"), + new TemplateDescriptor(inPrefix+"EurekaServerApplication.java", outPrefix+"src/main/java/com/microsoft/aspire/spring/eureka/EurekaServerApplication.java"), + new TemplateDescriptor(inPrefix+"application.yaml", outPrefix+"src/main/resources/application.yaml") + ); + + List templateOutput = TemplateEngine.process(EurekaServiceDiscovery.class, templateFiles, properties); + + // TODO we know that we need to get the output filename from the first element, and set that as the path + withPath(outputPath.resolve(templateOutput.get(0).filename()).toString()); + withContext(outputPath.resolve(templateOutput.get(0).filename()).getParent().toString()); + + return templateOutput; } @Override diff --git a/aspire4j/aspire4j-extensions-spring/src/main/java/module-info.java b/aspire4j/aspire4j-extensions-spring/src/main/java/module-info.java index abc593e..79b4c49 100644 --- a/aspire4j/aspire4j-extensions-spring/src/main/java/module-info.java +++ b/aspire4j/aspire4j-extensions-spring/src/main/java/module-info.java @@ -7,10 +7,12 @@ requires java.logging; exports com.microsoft.aspire.extensions.spring; - - opens com.microsoft.aspire.extensions.spring to org.hibernate.validator, com.fasterxml.jackson.databind; exports com.microsoft.aspire.extensions.spring.resources; + opens com.microsoft.aspire.extensions.spring to org.hibernate.validator, com.fasterxml.jackson.databind; opens com.microsoft.aspire.extensions.spring.resources to com.fasterxml.jackson.databind, org.hibernate.validator; + // We conditionally open up the template files to the apphost, so it can write them out + opens templates.eureka to com.microsoft.aspire; + provides com.microsoft.aspire.Extension with SpringExtension; } \ No newline at end of file diff --git a/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/src/main/java/com/microsoft/aspire/spring.eureka/EurekaServerApplication.java b/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/EurekaServerApplication.java similarity index 100% rename from aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/src/main/java/com/microsoft/aspire/spring.eureka/EurekaServerApplication.java rename to aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/EurekaServerApplication.java diff --git a/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/application.yaml b/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/application.yaml new file mode 100644 index 0000000..a670117 --- /dev/null +++ b/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/application.yaml @@ -0,0 +1,9 @@ +spring: + application: + name: ${name} +server: + port: ${port?c} +eureka: + client: + register-with-eureka: ${registerWithEureka?string("true", "false")} + fetch-registry: ${fetchRegistry?string("true", "false")} \ No newline at end of file diff --git a/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/pom.xml b/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/pom.xml index 431f2fd..960b98c 100644 --- a/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/pom.xml +++ b/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/pom.xml @@ -35,7 +35,7 @@ org.springframework.cloud spring-cloud-dependencies - ${spring-cloud.version} + ${r"${spring-cloud.version}"} pom import diff --git a/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/src/main/resources/application.yaml b/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/src/main/resources/application.yaml deleted file mode 100644 index b7b3ceb..0000000 --- a/aspire4j/aspire4j-extensions-spring/src/main/resources/templates/eureka/src/main/resources/application.yaml +++ /dev/null @@ -1,9 +0,0 @@ -spring: - application: - name: eureka-server -server: - port: 8761 -eureka: - client: - register-with-eureka: false - fetch-registry: false \ No newline at end of file diff --git a/aspire4j/aspire4j/pom.xml b/aspire4j/aspire4j/pom.xml index edaf7b4..dd71cdb 100644 --- a/aspire4j/aspire4j/pom.xml +++ b/aspire4j/aspire4j/pom.xml @@ -32,6 +32,18 @@ expressly 5.0.0 + + + + + + + + + org.freemarker + freemarker + 2.3.33 + diff --git a/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/ManifestGenerator.java b/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/ManifestGenerator.java index 4a83b24..fb7a0f6 100644 --- a/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/ManifestGenerator.java +++ b/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/ManifestGenerator.java @@ -5,14 +5,11 @@ import java.io.File; import java.io.IOException; import java.nio.file.*; -import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import com.microsoft.aspire.implementation.json.RelativePathSerializer; -import com.microsoft.aspire.resources.AzureBicepResource; -import com.microsoft.aspire.resources.Resource; import com.microsoft.aspire.resources.traits.ResourceWithTemplate; import jakarta.validation.ConstraintViolation; import jakarta.validation.Validation; @@ -28,19 +25,24 @@ class ManifestGenerator { void generateManifest(AppHost appHost, Path outputPath) { this.outputPath = outputPath; + File outputDir = outputPath.toFile(); + if (!outputDir.exists()) { + outputDir.mkdirs(); + } + DistributedApplication app = new DistributedApplication(); appHost.configureApplication(app); app.performResourceIntrospection(); - processTemplates(app); + processTemplates(app, outputPath); writeManifest(app); } - private void processTemplates(DistributedApplication app) { + private void processTemplates(DistributedApplication app, Path outputPath) { LOGGER.info("Processing templates..."); app.manifest.getResources().values().stream() .filter(r -> r instanceof ResourceWithTemplate) .map(r -> (ResourceWithTemplate) r) - .map(ResourceWithTemplate::processTemplate) + .map(r -> r.processTemplate(outputPath)) .forEach(templateFiles -> templateFiles.forEach(this::writeTemplateFile)); LOGGER.info("Templates processed"); } @@ -70,11 +72,6 @@ private void writeManifest(DistributedApplication app) { LOGGER.info("Models validated...Writing manifest to file"); } - File outputDir = outputPath.toFile(); - if (!outputDir.exists()) { - outputDir.mkdirs(); - } - // Set the outputDir in the RelativePathSerializer RelativePathSerializer.setOutputPath(outputPath); @@ -84,7 +81,7 @@ private void writeManifest(DistributedApplication app) { try { objectMapper.writerWithDefaultPrettyPrinter() - .writeValue(new File(outputDir, "aspire-manifest.json"), app.manifest); + .writeValue(new File(outputPath.toFile(), "aspire-manifest.json"), app.manifest); } catch (IOException e) { e.printStackTrace(); } @@ -93,29 +90,13 @@ private void writeManifest(DistributedApplication app) { private void writeTemplateFile(ResourceWithTemplate.TemplateFileOutput templateFile) { try { - Files.write(Paths.get(outputPath.toString() + "/" + templateFile.filename()), templateFile.content().getBytes()); + Path path = Paths.get(outputPath.toString() + "/" + templateFile.filename()); + + // ensure the parent directories exist + Files.createDirectories(path.getParent()); + Files.write(path, templateFile.content().getBytes()); } catch (IOException e) { e.printStackTrace(); } } - -// private void writeBicep(DistributedApplication app) { -// LOGGER.info("Writing Bicep files..."); -// -// // iterate through the resources in the app, and for any that are of type AzureBicep, give them the opportunity -// // to write their bicep file to the output directory. -// for (Resource resource : app.manifest.getResources().values()) { -// if (resource instanceof AzureBicepResource azureBicepResource) { -// List bicepFiles = azureBicepResource.getBicepFiles(); -// -// for (ResourceWithTemplate.TemplateFileOutput bicepFile : bicepFiles) { -// try { -// Files.write(Paths.get(outputPath.toString() + "/" + bicepFile.filename()), bicepFile.content().getBytes()); -// } catch (IOException e) { -// e.printStackTrace(); -// } -// } -// } -// } -// } } diff --git a/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/resources/traits/ResourceWithTemplate.java b/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/resources/traits/ResourceWithTemplate.java index 498ef83..7ccaae5 100644 --- a/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/resources/traits/ResourceWithTemplate.java +++ b/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/resources/traits/ResourceWithTemplate.java @@ -1,5 +1,6 @@ package com.microsoft.aspire.resources.traits; +import java.nio.file.Path; import java.util.List; /** @@ -12,10 +13,12 @@ */ public interface ResourceWithTemplate> { - List processTemplate(); + List processTemplate(Path outputPath); T self(); + record TemplateDescriptor(String inputFilename, String outputFilename) { } + // FIXME at some point string content won't be sufficient, and we will want to support binary content too record TemplateFileOutput(String filename, String content) { } } diff --git a/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/utils/templates/FreeMarkerTemplateProcessor.java b/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/utils/templates/FreeMarkerTemplateProcessor.java new file mode 100644 index 0000000..d936c70 --- /dev/null +++ b/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/utils/templates/FreeMarkerTemplateProcessor.java @@ -0,0 +1,29 @@ +package com.microsoft.aspire.utils.templates; + +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; +import freemarker.template.Version; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Map; + +public class FreeMarkerTemplateProcessor implements TemplateEngine { + + @Override + public String processTemplate(String templateContent, Map context) { + Configuration cfg = new Configuration(new Version("2.3.31")); + StringWriter out = new StringWriter(); + + try { + Template template = new Template("template", new StringReader(templateContent), cfg); + template.process(context, out); + } catch (IOException | TemplateException e) { + throw new RuntimeException(e); + } + + return out.toString(); + } +} \ No newline at end of file diff --git a/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/utils/templates/TemplateEngine.java b/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/utils/templates/TemplateEngine.java new file mode 100644 index 0000000..0aac42b --- /dev/null +++ b/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/utils/templates/TemplateEngine.java @@ -0,0 +1,45 @@ +package com.microsoft.aspire.utils.templates; + +import com.microsoft.aspire.resources.traits.ResourceWithTemplate; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public interface TemplateEngine { + + static TemplateEngine getTemplateEngine() { + // TODO cache this + return new FreeMarkerTemplateProcessor(); + } + + static List process( + final Class cls, + final List templateDescriptorList, + final Map context) { + return templateDescriptorList.stream().map(templateDescriptor -> { + // read the file from our local resources directory + InputStream resourceAsStream = cls.getResourceAsStream(templateDescriptor.inputFilename()); + if (resourceAsStream == null) { + throw new RuntimeException("Resource file not found: " + templateDescriptor.inputFilename()); + } + final TemplateEngine templateEngine = TemplateEngine.getTemplateEngine(); + final String outputFilename = templateEngine.processTemplate(templateDescriptor.outputFilename(), context); + final String outputString = templateEngine.processTemplate(resourceAsStream, context); + return new ResourceWithTemplate.TemplateFileOutput(outputFilename, outputString); + }).collect(Collectors.toList()); + } + + String processTemplate(String templateContent, Map context); + + default String processTemplate(InputStream templateStream, Map context) { + try { + String templateContent = new String(templateStream.readAllBytes()); + return processTemplate(templateContent, context); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/utils/templates/VelocityTemplateProcessor.java b/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/utils/templates/VelocityTemplateProcessor.java new file mode 100644 index 0000000..4fa5b4e --- /dev/null +++ b/aspire4j/aspire4j/src/main/java/com/microsoft/aspire/utils/templates/VelocityTemplateProcessor.java @@ -0,0 +1,48 @@ +//package com.microsoft.aspire.utils.templates; +// +//import org.apache.velocity.app.Velocity; +//import org.apache.velocity.app.VelocityEngine; +//import org.apache.velocity.Template; +//import org.apache.velocity.VelocityContext; +// +//import java.io.InputStream; +//import java.io.InputStreamReader; +//import java.io.Reader; +//import java.io.StringWriter; +//import java.util.Properties; +// +//public class VelocityTemplateProcessor { +// private static final VelocityEngine velocityEngine; +// static { +// velocityEngine = new VelocityEngine(); +// Properties properties = new Properties(); +// properties.setProperty("resource.loader", "class"); +// properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); +// velocityEngine.init(properties); +// } +// +// private VelocityTemplateProcessor() { } +// +// public static String processTemplate(String templateName, VelocityContext context) { +// Template template = velocityEngine.getTemplate(templateName); +// +// // Merge the context with the template +// StringWriter writer = new StringWriter(); +// template.merge(context, writer); +// +// return writer.toString(); +// } +// +// public static String processTemplateFromString(String templateContent, VelocityContext context) { +// StringWriter writer = new StringWriter(); +// velocityEngine.evaluate(context, writer, "TemplateProcessor", templateContent); +// return writer.toString(); +// } +// +// public static String processTemplateFromStream(InputStream templateStream, VelocityContext context) { +// Reader reader = new InputStreamReader(templateStream); +// StringWriter writer = new StringWriter(); +// velocityEngine.evaluate(context, writer, "TemplateProcessor", reader); +// return writer.toString(); +// } +//} \ No newline at end of file diff --git a/aspire4j/aspire4j/src/main/java/module-info.java b/aspire4j/aspire4j/src/main/java/module-info.java index 576b5cd..2b99b41 100644 --- a/aspire4j/aspire4j/src/main/java/module-info.java +++ b/aspire4j/aspire4j/src/main/java/module-info.java @@ -4,10 +4,15 @@ requires transitive org.hibernate.validator; requires java.logging; + // Templating engines +// requires velocity.engine.core; + requires freemarker; + exports com.microsoft.aspire; exports com.microsoft.aspire.resources; exports com.microsoft.aspire.resources.properties; exports com.microsoft.aspire.resources.traits; + exports com.microsoft.aspire.utils.templates; opens com.microsoft.aspire.resources to org.hibernate.validator, com.fasterxml.jackson.databind; opens com.microsoft.aspire.resources.properties to org.hibernate.validator, com.fasterxml.jackson.databind; diff --git a/azure.yaml b/samples/storage-explorer/azure.yaml similarity index 100% rename from azure.yaml rename to samples/storage-explorer/azure.yaml diff --git a/samples/storage-explorer/storage-explorer-apphost/src/main/java/com/microsoft/aspire/storageexplorer/StorageExplorerAppHost.java b/samples/storage-explorer/storage-explorer-apphost/src/main/java/com/microsoft/aspire/storageexplorer/StorageExplorerAppHost.java index 402ad7c..0bb80fb 100644 --- a/samples/storage-explorer/storage-explorer-apphost/src/main/java/com/microsoft/aspire/storageexplorer/StorageExplorerAppHost.java +++ b/samples/storage-explorer/storage-explorer-apphost/src/main/java/com/microsoft/aspire/storageexplorer/StorageExplorerAppHost.java @@ -10,26 +10,26 @@ public class StorageExplorerAppHost implements AppHost { @Override public void configureApplication(DistributedApplication app) { app.printExtensions(); - var azureStorage = app.withExtension(AzureStorageExtension.class) - .addAzureStorage("storage"); - - var blobStorage = azureStorage.addBlobs("storage-explorer-blobs"); +// var azureStorage = app.withExtension(AzureStorageExtension.class) +// .addAzureStorage("storage"); +// +// var blobStorage = azureStorage.addBlobs("storage-explorer-blobs"); var eurekaServiceDiscovery = app.withExtension(SpringExtension.class) - .addEurekaServiceDiscovery("eureka"); - - var dateService = app.withExtension(SpringExtension.class) - .addSpringProject("date-service-spring") - .withPath("date-service") - .withExternalHttpEndpoints(); - - var storageExplorer = app.withExtension(SpringExtension.class) - .addSpringProject("storage-explorer-spring") - .withPath("storage-explorer") - .withExternalHttpEndpoints() - .withReference(blobStorage) - .withReference(dateService) - .withReference(eurekaServiceDiscovery); + .addEurekaServiceDiscovery("eureka"); +// +// var dateService = app.withExtension(SpringExtension.class) +// .addSpringProject("date-service-spring") +// .withPath("date-service") +// .withExternalHttpEndpoints(); +// +// var storageExplorer = app.withExtension(SpringExtension.class) +// .addSpringProject("storage-explorer-spring") +// .withPath("storage-explorer") +// .withExternalHttpEndpoints() +// .withReference(blobStorage) +// .withReference(dateService) +// .withReference(eurekaServiceDiscovery); // Old style, with direct reference to dockerfiles // var dateService2 = app.addDockerFile("dateservice", "samples/storage-explorer/date-service/Dockerfile", "date-service")