From 26836b1571fc5f74193e6578afee29df08f1b5ad Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Tue, 19 Sep 2023 16:52:49 +0800 Subject: [PATCH 1/6] add GraalVmConfig --- .../azure/autorest/mapper/ClientMapper.java | 3 ++ .../autorest/model/clientmodel/Client.java | 14 ++++- .../model/clientmodel/GraalVmConfig.java | 53 +++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java diff --git a/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java b/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java index 493783e702..9ff7e2c80d 100644 --- a/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java +++ b/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java @@ -35,6 +35,7 @@ import com.azure.autorest.model.clientmodel.ClientResponse; import com.azure.autorest.model.clientmodel.ConvenienceMethod; import com.azure.autorest.model.clientmodel.EnumType; +import com.azure.autorest.model.clientmodel.GraalVmConfig; import com.azure.autorest.model.clientmodel.IType; import com.azure.autorest.model.clientmodel.ModuleInfo; import com.azure.autorest.model.clientmodel.PackageInfo; @@ -317,6 +318,8 @@ public Client map(CodeModel codeModel) { builder.liveTests(LiveTestsMapper.getInstance().map(codeModel.getTestModel())); } + builder.graalVmConfig(GraalVmConfig.fromClient(clientModels, serviceClientsMap.keySet())); + return builder.build(); } diff --git a/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java b/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java index cce341af79..eb38cff81b 100644 --- a/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java +++ b/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java @@ -63,6 +63,7 @@ public class Client { private final List liveTests; private final List unionModels; private final List clientMethodExamples; + private final GraalVmConfig graalVmConfig; /** * Create a new Client with the provided values. @@ -88,7 +89,8 @@ private Client(String clientName, String clientDescription, List enums ServiceClient serviceClient, List serviceClients, ModuleInfo moduleInfo, List syncClients, List asyncClients, List clientBuilders, List protocolExamples, - List liveTests, List unionModels, List clientMethodExamples + List liveTests, List unionModels, List clientMethodExamples, + GraalVmConfig graalVmConfig ) { this.clientName = clientName; this.clientDescription = clientDescription; @@ -109,6 +111,7 @@ private Client(String clientName, String clientDescription, List enums this.liveTests = liveTests; this.unionModels = unionModels; this.clientMethodExamples = clientMethodExamples; + this.graalVmConfig = graalVmConfig; } public final String getClientName() { @@ -213,6 +216,7 @@ public static class Builder { private List liveTests = Collections.emptyList(); private List unionModels = Collections.emptyList(); private List clientMethodExamples = Collections.emptyList(); + private GraalVmConfig graalVmConfig; /** * Sets the name of this service client. @@ -394,6 +398,11 @@ public Builder liveTests(List liveTests) { return this; } + public Builder graalVmConfig(GraalVmConfig graalVmConfig) { + this.graalVmConfig = graalVmConfig; + return this; + } + public Client build() { if (serviceClient == null && !serviceClients.isEmpty()) { serviceClient = serviceClients.iterator().next(); @@ -416,7 +425,8 @@ public Client build() { protocolExamples, liveTests, unionModels, - clientMethodExamples + clientMethodExamples, + graalVmConfig ); } } diff --git a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java new file mode 100644 index 0000000000..3e1a06404f --- /dev/null +++ b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.autorest.model.clientmodel; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class GraalVmConfig { + + private List proxies = new ArrayList<>(); + private List reflects = new ArrayList<>(); + private List resources = new ArrayList<>(); + + private GraalVmConfig() { + + } + + public List getProxies() { + return proxies; + } + + public List getReflects() { + return reflects; + } + + public List getResources() { + return resources; + } + + // TODO: Builder + public static GraalVmConfig fromClient(Collection models, Collection serviceClients) { + GraalVmConfig result = new GraalVmConfig(); + result.reflects = models.stream() + .map(m -> m.getPackage() + "." + m.getName()) + .collect(Collectors.toList()); + // TODO: include Proxy from ServiceClient + result.proxies = serviceClients.stream() + .flatMap(sc -> { + if (sc.getMethodGroupClients() != null) { + return sc.getMethodGroupClients().stream(); + } else { + return Stream.empty(); + } + }) + .map(m -> m.getPackage() + "." + m.getClassName() + "$" + m.getProxy().getName()) + .collect(Collectors.toList()); + return result; + } +} From a128f2de123d211ebcc53928565927cfb44d09e4 Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Wed, 20 Sep 2023 13:35:34 +0800 Subject: [PATCH 2/6] handle proxy in ServiceClient --- .../autorest/model/clientmodel/GraalVmConfig.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java index 3e1a06404f..f33f64898e 100644 --- a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java +++ b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java @@ -34,10 +34,13 @@ public List getResources() { // TODO: Builder public static GraalVmConfig fromClient(Collection models, Collection serviceClients) { GraalVmConfig result = new GraalVmConfig(); + + // Reflect result.reflects = models.stream() .map(m -> m.getPackage() + "." + m.getName()) .collect(Collectors.toList()); - // TODO: include Proxy from ServiceClient + + // Proxy result.proxies = serviceClients.stream() .flatMap(sc -> { if (sc.getMethodGroupClients() != null) { @@ -46,8 +49,14 @@ public static GraalVmConfig fromClient(Collection models, Collectio return Stream.empty(); } }) + .filter(m -> m.getProxy() != null) .map(m -> m.getPackage() + "." + m.getClassName() + "$" + m.getProxy().getName()) .collect(Collectors.toList()); + result.proxies.addAll(serviceClients.stream() + .filter(sc -> sc.getProxy() != null) + .map(sc -> sc.getPackage() + "." + sc.getClassName() + "$" + sc.getProxy().getName()) + .collect(Collectors.toList())); + return result; } } From 4900766055ee9f4dd2555feae818be83d2040f05 Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Thu, 21 Sep 2023 13:21:33 +0800 Subject: [PATCH 3/6] output graalvmconfig --- .../com/azure/autorest/fluent/FluentGen.java | 3 ++ .../main/java/com/azure/autorest/Javagen.java | 3 ++ .../autorest/model/clientmodel/Client.java | 5 +++ .../model/clientmodel/GraalVmConfig.java | 42 +++++++++++++++++++ .../autorest/model/javamodel/JavaPackage.java | 10 +++++ 5 files changed, 63 insertions(+) diff --git a/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java b/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java index d10c7d506a..d3e8849553 100755 --- a/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java +++ b/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java @@ -272,6 +272,9 @@ FluentJavaPackage handleTemplate(Client client) { javaPackage.addPackageInfo(packageInfo.getPackage(), "package-info", packageInfo); } + // GraalVM config + javaPackage.addGraalVmConfig("com.azure.resourcemanager", FluentUtils.getArtifactId(), client.getGraalVmConfig()); + // Samples if (fluentPremiumExamples != null) { for (FluentExample example : fluentPremiumExamples) { diff --git a/javagen/src/main/java/com/azure/autorest/Javagen.java b/javagen/src/main/java/com/azure/autorest/Javagen.java index 55e307d9df..219f9e16d0 100644 --- a/javagen/src/main/java/com/azure/autorest/Javagen.java +++ b/javagen/src/main/java/com/azure/autorest/Javagen.java @@ -325,6 +325,9 @@ protected JavaPackage writeToTemplates(CodeModel codeModel, Client client, JavaS // Blank readme sample javaPackage.addProtocolExamplesBlank(); } + + // GraalVM config + javaPackage.addGraalVmConfig(project.getGroupId(), project.getArtifactId(), client.getGraalVmConfig()); } return javaPackage; } diff --git a/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java b/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java index eb38cff81b..a811bf30a5 100644 --- a/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java +++ b/javagen/src/main/java/com/azure/autorest/model/clientmodel/Client.java @@ -196,6 +196,11 @@ public List getClientMethodExamples() { return clientMethodExamples; } + /** @return the Graal VM config */ + public GraalVmConfig getGraalVmConfig() { + return graalVmConfig; + } + public static class Builder { private String clientName; private String clientDescription; diff --git a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java index f33f64898e..122b9f4696 100644 --- a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java +++ b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java @@ -3,8 +3,14 @@ package com.azure.autorest.model.clientmodel; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -59,4 +65,40 @@ public static GraalVmConfig fromClient(Collection models, Collectio return result; } + + private static class Reflect { + @JsonProperty("name") + private final String name; + @JsonProperty("allDeclaredConstructors") + private final boolean allDeclaredConstructors = true; + @JsonProperty("allDeclaredFields") + private final boolean allDeclaredFields = true; + @JsonProperty("allDeclaredMethods") + private final boolean allDeclaredMethods = true; + + private Reflect(String name) { + this.name = name; + } + } + + static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + + // TODO: Template + public String toProxyConfigJson() { + List> result = proxies.stream().map(Collections::singletonList).collect(Collectors.toList()); + try { + return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(result); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + public String toReflectConfigJson() { + List result = reflects.stream().map(Reflect::new).collect(Collectors.toList()); + try { + return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(result); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } } diff --git a/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java b/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java index 1f75a42513..2efc2bda94 100644 --- a/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java +++ b/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java @@ -13,6 +13,7 @@ import com.azure.autorest.model.clientmodel.ClientResponse; import com.azure.autorest.model.clientmodel.ClientMethodExample; import com.azure.autorest.model.clientmodel.EnumType; +import com.azure.autorest.model.clientmodel.GraalVmConfig; import com.azure.autorest.model.clientmodel.MethodGroupClient; import com.azure.autorest.model.clientmodel.ModuleInfo; import com.azure.autorest.model.clientmodel.PackageInfo; @@ -40,6 +41,7 @@ import com.azure.autorest.util.PossibleCredentialException; import org.slf4j.Logger; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -298,6 +300,14 @@ public void addTestProxyAssetsJson(Project project) { textFiles.add(textFile); } + public final void addGraalVmConfig(String groupId, String artifactId, GraalVmConfig graalVmConfig) { + String metaInfPath = Paths.get("src", "main", "resources", "META-INF", "native-image", groupId, artifactId).toString(); + TextFile proxyConfigFile = new TextFile(Paths.get(metaInfPath, "proxy-config.json").toString(), graalVmConfig.toProxyConfigJson()); + textFiles.add(proxyConfigFile); + TextFile reflectConfigFile = new TextFile(Paths.get(metaInfPath, "reflect-config.json").toString(), graalVmConfig.toReflectConfigJson()); + textFiles.add(reflectConfigFile); + } + protected void checkDuplicateFile(String filePath) { if (filePaths.contains(filePath)) { // throw new IllegalStateException(String.format("Name conflict for output file '%1$s'.", filePath)); From 17077a15c2f1146b8c52a42f23ab2fae5a741ddc Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Thu, 21 Sep 2023 14:24:54 +0800 Subject: [PATCH 4/6] enum and exception --- .../java/com/azure/autorest/mapper/ClientMapper.java | 8 +++++--- .../autorest/model/clientmodel/GraalVmConfig.java | 10 +++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java b/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java index 9ff7e2c80d..ea4f9c57d7 100644 --- a/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java +++ b/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java @@ -28,6 +28,7 @@ import com.azure.autorest.model.clientmodel.Client; import com.azure.autorest.model.clientmodel.ClientBuilder; import com.azure.autorest.model.clientmodel.ClientBuilderTrait; +import com.azure.autorest.model.clientmodel.ClientException; import com.azure.autorest.model.clientmodel.ClientMethod; import com.azure.autorest.model.clientmodel.ClientMethodExample; import com.azure.autorest.model.clientmodel.ClientMethodType; @@ -112,7 +113,7 @@ public Client map(CodeModel codeModel) { builder.enums(enumTypes); // exception - builder.exceptions(codeModel.getOperationGroups().stream() + List exceptions = codeModel.getOperationGroups().stream() .flatMap(og -> og.getOperations().stream()) .flatMap(o -> o.getExceptions().stream()) .map(Response::getSchema) @@ -121,7 +122,8 @@ public Client map(CodeModel codeModel) { .map(s -> Mappers.getExceptionMapper().map((ObjectSchema) s)) .filter(Objects::nonNull) .distinct() - .collect(Collectors.toList())); + .collect(Collectors.toList()); + builder.exceptions(exceptions); builder.xmlSequenceWrappers(parseXmlSequenceWrappers(codeModel, settings)); @@ -318,7 +320,7 @@ public Client map(CodeModel codeModel) { builder.liveTests(LiveTestsMapper.getInstance().map(codeModel.getTestModel())); } - builder.graalVmConfig(GraalVmConfig.fromClient(clientModels, serviceClientsMap.keySet())); + builder.graalVmConfig(GraalVmConfig.fromClient(clientModels, enumTypes, exceptions, serviceClientsMap.keySet())); return builder.build(); } diff --git a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java index 122b9f4696..9c95465801 100644 --- a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java +++ b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java @@ -38,13 +38,21 @@ public List getResources() { } // TODO: Builder - public static GraalVmConfig fromClient(Collection models, Collection serviceClients) { + public static GraalVmConfig fromClient(Collection models, Collection enums, + Collection exceptions, + Collection serviceClients) { GraalVmConfig result = new GraalVmConfig(); // Reflect result.reflects = models.stream() .map(m -> m.getPackage() + "." + m.getName()) .collect(Collectors.toList()); + result.reflects.addAll(enums.stream() + .map(e -> e.getPackage() + "." + e.getName()) + .collect(Collectors.toList())); + result.reflects.addAll(exceptions.stream() + .map(e -> e.getPackage() + "." + e.getName()) + .collect(Collectors.toList())); // Proxy result.proxies = serviceClients.stream() From f4e58964c7b9c21d8020f0c1752627f7be40adc9 Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Mon, 25 Sep 2023 10:30:25 +0800 Subject: [PATCH 5/6] extract TemplateUtil.prettyPrintToJson --- .../model/clientmodel/GraalVmConfig.java | 18 +++--------------- .../template/TestProxyAssetsTemplate.java | 11 ++--------- .../com/azure/autorest/util/TemplateUtil.java | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java index 9c95465801..2a825e561f 100644 --- a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java +++ b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java @@ -3,10 +3,8 @@ package com.azure.autorest.model.clientmodel; +import com.azure.autorest.util.TemplateUtil; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import java.util.ArrayList; import java.util.Collection; @@ -89,24 +87,14 @@ private Reflect(String name) { } } - static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); - // TODO: Template public String toProxyConfigJson() { List> result = proxies.stream().map(Collections::singletonList).collect(Collectors.toList()); - try { - return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(result); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + return TemplateUtil.prettyPrintToJson(result); } public String toReflectConfigJson() { List result = reflects.stream().map(Reflect::new).collect(Collectors.toList()); - try { - return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(result); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + return TemplateUtil.prettyPrintToJson(result); } } diff --git a/javagen/src/main/java/com/azure/autorest/template/TestProxyAssetsTemplate.java b/javagen/src/main/java/com/azure/autorest/template/TestProxyAssetsTemplate.java index 3b0e76bd70..b9e8e8b7e2 100644 --- a/javagen/src/main/java/com/azure/autorest/template/TestProxyAssetsTemplate.java +++ b/javagen/src/main/java/com/azure/autorest/template/TestProxyAssetsTemplate.java @@ -4,14 +4,11 @@ package com.azure.autorest.template; import com.azure.autorest.model.projectmodel.Project; +import com.azure.autorest.util.TemplateUtil; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; public class TestProxyAssetsTemplate { - static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - private static class Assets { @JsonProperty("AssetsRepo") private String assetsRepo = "Azure/azure-sdk-assets"; @@ -42,10 +39,6 @@ public String write(Project project) { group = segments[segments.length - 1]; } asserts.setTagPrefix(String.format("java/%1$s/%2$s", group, project.getArtifactId())); - try { - return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(asserts); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + return TemplateUtil.prettyPrintToJson(asserts); } } diff --git a/javagen/src/main/java/com/azure/autorest/util/TemplateUtil.java b/javagen/src/main/java/com/azure/autorest/util/TemplateUtil.java index cdf4af9b9a..fa217006b7 100644 --- a/javagen/src/main/java/com/azure/autorest/util/TemplateUtil.java +++ b/javagen/src/main/java/com/azure/autorest/util/TemplateUtil.java @@ -19,6 +19,9 @@ import com.azure.autorest.model.javamodel.JavaFileContents; import com.azure.autorest.model.javamodel.JavaType; import com.azure.autorest.template.Templates; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import org.slf4j.Logger; import java.io.BufferedReader; @@ -37,6 +40,8 @@ public class TemplateUtil { private static final Logger LOGGER = new PluginLogger(Javagen.getPluginInstance(), TemplateUtil.class); + private static final ObjectMapper PRETTY_PRINT_MAPPER = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + // begin of constant for template replacement, used in ResourceUtil.loadTextFromResource public static final String SERVICE_NAME = "service-name"; public static final String SERVICE_DESCRIPTION = "service-description"; @@ -54,6 +59,20 @@ public class TemplateUtil { public static final String DATE_UTC = "date-utc"; // end of constant for template replacement + /** + * Print object to JSON string with indent. + * + * @param jsonObject the Java object + * @return the JSON string + */ + public static String prettyPrintToJson(Object jsonObject) { + try { + return PRETTY_PRINT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + /** * Load text from resources, with string replacement. * From 7119b271e5dd454631c976b6bfa200cc113dbee2 Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Mon, 25 Sep 2023 14:51:59 +0800 Subject: [PATCH 6/6] refine graalvm config --- .../extension/base/plugin/JavaSettings.java | 14 ++- .../com/azure/autorest/fluent/FluentGen.java | 4 +- fluentnamer/readme.md | 1 + .../main/java/com/azure/autorest/Javagen.java | 8 +- .../azure/autorest/mapper/ClientMapper.java | 8 +- .../autorest/mapper/DefaultMapperFactory.java | 5 + .../autorest/mapper/GraalVmConfigMapper.java | 83 ++++++++++++++ .../azure/autorest/mapper/MapperFactory.java | 2 + .../com/azure/autorest/mapper/Mappers.java | 4 + .../model/clientmodel/GraalVmConfig.java | 108 ++++++++---------- .../autorest/model/javamodel/JavaPackage.java | 7 ++ .../autorest/model/projectmodel/Project.java | 4 +- .../TestProxyAssertsTemplateTests.java | 3 +- readme.md | 3 +- 14 files changed, 183 insertions(+), 71 deletions(-) create mode 100644 javagen/src/main/java/com/azure/autorest/mapper/GraalVmConfigMapper.java diff --git a/extension-base/src/main/java/com/azure/autorest/extension/base/plugin/JavaSettings.java b/extension-base/src/main/java/com/azure/autorest/extension/base/plugin/JavaSettings.java index f5232b185c..cfb2c0ab70 100644 --- a/extension-base/src/main/java/com/azure/autorest/extension/base/plugin/JavaSettings.java +++ b/extension-base/src/main/java/com/azure/autorest/extension/base/plugin/JavaSettings.java @@ -35,6 +35,7 @@ public class JavaSettings { private static Logger logger; private final boolean useKeyCredential; private boolean noCustomHeaders; + static void setHeader(String value) { if ("MICROSOFT_MIT".equals(value)) { header = MICROSOFT_MIT_LICENSE_HEADER + "\n" + String.format(DEFAULT_CODE_GENERATION_HEADER, VERSION); @@ -169,7 +170,8 @@ public static JavaSettings getInstance() { // were generated with required = true set in JsonProperty annotation getBooleanValue(host, "disable-required-property-annotation", false), getBooleanValue(host, "enable-page-size", false), - getBooleanValue(host, "use-key-credential", false) + getBooleanValue(host, "use-key-credential", false), + getBooleanValue(host, "graal-vm-config", false) ); } return instance; @@ -322,7 +324,8 @@ private JavaSettings(AutorestSettings autorestSettings, boolean urlAsString, boolean disableRequiredPropertyAnnotation, boolean pageSizeEnabled, - boolean useKeyCredential) { + boolean useKeyCredential, + boolean generateGraalVmConfig) { this.autorestSettings = autorestSettings; this.modelerSettings = new ModelerSettings(modelerSettings); @@ -420,6 +423,7 @@ private JavaSettings(AutorestSettings autorestSettings, this.disableRequiredJsonAnnotation = disableRequiredPropertyAnnotation; this.pageSizeEnabled = pageSizeEnabled; this.useKeyCredential = useKeyCredential; + this.generateGraalVmConfig = generateGraalVmConfig; } @@ -897,6 +901,12 @@ public boolean isPageSizeEnabled() { return pageSizeEnabled; } + private final boolean generateGraalVmConfig; + + public boolean isGenerateGraalVmConfig() { + return generateGraalVmConfig; + } + public static class PollingDetails { @JsonProperty("strategy") private String strategy; diff --git a/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java b/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java index d3e8849553..098172b5e0 100755 --- a/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java +++ b/fluentgen/src/main/java/com/azure/autorest/fluent/FluentGen.java @@ -273,7 +273,9 @@ FluentJavaPackage handleTemplate(Client client) { } // GraalVM config - javaPackage.addGraalVmConfig("com.azure.resourcemanager", FluentUtils.getArtifactId(), client.getGraalVmConfig()); + if (javaSettings.isGenerateGraalVmConfig()) { + javaPackage.addGraalVmConfig("com.azure.resourcemanager", FluentUtils.getArtifactId(), client.getGraalVmConfig()); + } // Samples if (fluentPremiumExamples != null) { diff --git a/fluentnamer/readme.md b/fluentnamer/readme.md index e0a9fba274..692075b9da 100644 --- a/fluentnamer/readme.md +++ b/fluentnamer/readme.md @@ -62,4 +62,5 @@ client-logger: true generate-client-interfaces: true required-parameter-client-methods: true client-flattened-annotation-target: none +graal-vm-config: true ``` diff --git a/javagen/src/main/java/com/azure/autorest/Javagen.java b/javagen/src/main/java/com/azure/autorest/Javagen.java index 219f9e16d0..1277596e57 100644 --- a/javagen/src/main/java/com/azure/autorest/Javagen.java +++ b/javagen/src/main/java/com/azure/autorest/Javagen.java @@ -241,6 +241,11 @@ protected JavaPackage writeToTemplates(CodeModel codeModel, Client client, JavaS } } + // GraalVM config + if (settings.isGenerateGraalVmConfig()) { + javaPackage.addGraalVmConfig(Project.AZURE_GROUP_ID, ClientModelUtil.getArtifactId(), client.getGraalVmConfig()); + } + // Service version if (settings.isDataPlaneClient()) { String packageName = settings.getPackage(); @@ -325,9 +330,6 @@ protected JavaPackage writeToTemplates(CodeModel codeModel, Client client, JavaS // Blank readme sample javaPackage.addProtocolExamplesBlank(); } - - // GraalVM config - javaPackage.addGraalVmConfig(project.getGroupId(), project.getArtifactId(), client.getGraalVmConfig()); } return javaPackage; } diff --git a/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java b/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java index ea4f9c57d7..5e0d32b35c 100644 --- a/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java +++ b/javagen/src/main/java/com/azure/autorest/mapper/ClientMapper.java @@ -36,7 +36,6 @@ import com.azure.autorest.model.clientmodel.ClientResponse; import com.azure.autorest.model.clientmodel.ConvenienceMethod; import com.azure.autorest.model.clientmodel.EnumType; -import com.azure.autorest.model.clientmodel.GraalVmConfig; import com.azure.autorest.model.clientmodel.IType; import com.azure.autorest.model.clientmodel.ModuleInfo; import com.azure.autorest.model.clientmodel.PackageInfo; @@ -320,7 +319,12 @@ public Client map(CodeModel codeModel) { builder.liveTests(LiveTestsMapper.getInstance().map(codeModel.getTestModel())); } - builder.graalVmConfig(GraalVmConfig.fromClient(clientModels, enumTypes, exceptions, serviceClientsMap.keySet())); + builder.graalVmConfig(Mappers.getGraalVmConfigMapper() + .map(new GraalVmConfigMapper.ServiceAndModel( + serviceClientsMap.keySet(), + exceptions, + clientModels, + enumTypes))); return builder.build(); } diff --git a/javagen/src/main/java/com/azure/autorest/mapper/DefaultMapperFactory.java b/javagen/src/main/java/com/azure/autorest/mapper/DefaultMapperFactory.java index 08a3a2e9cd..82cd709df4 100644 --- a/javagen/src/main/java/com/azure/autorest/mapper/DefaultMapperFactory.java +++ b/javagen/src/main/java/com/azure/autorest/mapper/DefaultMapperFactory.java @@ -118,4 +118,9 @@ public UnionMapper getUnionMapper() { public UnionModelMapper getUnionModelMapper() { return UnionModelMapper.getInstance(); } + + @Override + public GraalVmConfigMapper getGraalVmConfigMapper() { + return GraalVmConfigMapper.getInstance(); + } } diff --git a/javagen/src/main/java/com/azure/autorest/mapper/GraalVmConfigMapper.java b/javagen/src/main/java/com/azure/autorest/mapper/GraalVmConfigMapper.java new file mode 100644 index 0000000000..092b72a942 --- /dev/null +++ b/javagen/src/main/java/com/azure/autorest/mapper/GraalVmConfigMapper.java @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.autorest.mapper; + +import com.azure.autorest.extension.base.plugin.JavaSettings; +import com.azure.autorest.model.clientmodel.ClientException; +import com.azure.autorest.model.clientmodel.ClientModel; +import com.azure.autorest.model.clientmodel.EnumType; +import com.azure.autorest.model.clientmodel.GraalVmConfig; +import com.azure.autorest.model.clientmodel.ServiceClient; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class GraalVmConfigMapper implements IMapper { + + public static class ServiceAndModel { + private final Collection serviceClients; + private final Collection exceptions; + private final Collection models; + private final Collection enums; + + public ServiceAndModel(Collection serviceClients, + Collection exceptions, + Collection models, + Collection enums) { + this.serviceClients = serviceClients; + this.exceptions = exceptions; + this.models = models; + this.enums = enums; + } + } + + private static final GraalVmConfigMapper INSTANCE = new GraalVmConfigMapper(); + + protected GraalVmConfigMapper() { + } + + public static GraalVmConfigMapper getInstance() { + return INSTANCE; + } + + @Override + public GraalVmConfig map(ServiceAndModel data) { + List proxies; + List reflects; + + // Reflect + reflects = data.exceptions.stream() + .map(e -> e.getPackage() + "." + e.getName()) + .collect(Collectors.toList()); + if (!JavaSettings.getInstance().isStreamStyleSerialization()) { + reflects.addAll(data.models.stream() + .map(e -> e.getPackage() + "." + e.getName()) + .collect(Collectors.toList())); + reflects.addAll(data.enums.stream() + .map(m -> m.getPackage() + "." + m.getName()) + .collect(Collectors.toList())); + } + + // Proxy + proxies = data.serviceClients.stream() + .flatMap(sc -> { + if (sc.getMethodGroupClients() != null) { + return sc.getMethodGroupClients().stream(); + } else { + return Stream.empty(); + } + }) + .filter(m -> m.getProxy() != null) + .map(m -> m.getPackage() + "." + m.getClassName() + "$" + m.getProxy().getName()) + .collect(Collectors.toList()); + proxies.addAll(data.serviceClients.stream() + .filter(sc -> sc.getProxy() != null) + .map(sc -> sc.getPackage() + "." + sc.getClassName() + "$" + sc.getProxy().getName()) + .collect(Collectors.toList())); + + return new GraalVmConfig(proxies, reflects, JavaSettings.getInstance().isFluent()); + } +} diff --git a/javagen/src/main/java/com/azure/autorest/mapper/MapperFactory.java b/javagen/src/main/java/com/azure/autorest/mapper/MapperFactory.java index 99e1c832c8..08ec5d4f5c 100644 --- a/javagen/src/main/java/com/azure/autorest/mapper/MapperFactory.java +++ b/javagen/src/main/java/com/azure/autorest/mapper/MapperFactory.java @@ -50,4 +50,6 @@ public interface MapperFactory { UnionMapper getUnionMapper(); UnionModelMapper getUnionModelMapper(); + + GraalVmConfigMapper getGraalVmConfigMapper(); } diff --git a/javagen/src/main/java/com/azure/autorest/mapper/Mappers.java b/javagen/src/main/java/com/azure/autorest/mapper/Mappers.java index 86056eb040..ee41367600 100644 --- a/javagen/src/main/java/com/azure/autorest/mapper/Mappers.java +++ b/javagen/src/main/java/com/azure/autorest/mapper/Mappers.java @@ -102,4 +102,8 @@ public static UnionMapper getUnionMapper() { public static UnionModelMapper getUnionModelMapper() { return factory.getUnionModelMapper(); } + + public static GraalVmConfigMapper getGraalVmConfigMapper() { + return factory.getGraalVmConfigMapper(); + } } diff --git a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java index 2a825e561f..9ed87d6b2d 100644 --- a/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java +++ b/javagen/src/main/java/com/azure/autorest/model/clientmodel/GraalVmConfig.java @@ -6,73 +6,23 @@ import com.azure.autorest.util.TemplateUtil; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import java.util.stream.Stream; public class GraalVmConfig { - private List proxies = new ArrayList<>(); - private List reflects = new ArrayList<>(); - private List resources = new ArrayList<>(); + private final List proxies; + private final List reflects; + private final boolean fluent; - private GraalVmConfig() { - - } - - public List getProxies() { - return proxies; - } - - public List getReflects() { - return reflects; - } - - public List getResources() { - return resources; - } - - // TODO: Builder - public static GraalVmConfig fromClient(Collection models, Collection enums, - Collection exceptions, - Collection serviceClients) { - GraalVmConfig result = new GraalVmConfig(); - - // Reflect - result.reflects = models.stream() - .map(m -> m.getPackage() + "." + m.getName()) - .collect(Collectors.toList()); - result.reflects.addAll(enums.stream() - .map(e -> e.getPackage() + "." + e.getName()) - .collect(Collectors.toList())); - result.reflects.addAll(exceptions.stream() - .map(e -> e.getPackage() + "." + e.getName()) - .collect(Collectors.toList())); - - // Proxy - result.proxies = serviceClients.stream() - .flatMap(sc -> { - if (sc.getMethodGroupClients() != null) { - return sc.getMethodGroupClients().stream(); - } else { - return Stream.empty(); - } - }) - .filter(m -> m.getProxy() != null) - .map(m -> m.getPackage() + "." + m.getClassName() + "$" + m.getProxy().getName()) - .collect(Collectors.toList()); - result.proxies.addAll(serviceClients.stream() - .filter(sc -> sc.getProxy() != null) - .map(sc -> sc.getPackage() + "." + sc.getClassName() + "$" + sc.getProxy().getName()) - .collect(Collectors.toList())); - - return result; + public GraalVmConfig(List proxies, List reflects, boolean fluent) { + this.proxies = proxies; + this.reflects = reflects; + this.fluent = fluent; } - private static class Reflect { + private static class ReflectConfig { @JsonProperty("name") private final String name; @JsonProperty("allDeclaredConstructors") @@ -82,11 +32,45 @@ private static class Reflect { @JsonProperty("allDeclaredMethods") private final boolean allDeclaredMethods = true; - private Reflect(String name) { + private ReflectConfig(String name) { this.name = name; } } + private static class ResourceConfig { + + private static class Pattern { + @JsonProperty("pattern") + private final String pattern; + + private Pattern(String pattern) { + this.pattern = pattern; + } + } + + private static class Resource { + @JsonProperty("includes") + private final List includes; + + public Resource(List includes) { + this.includes = includes; + } + } + + @JsonProperty("resources") + private final Resource resources; + private final List bundles = Collections.emptyList(); + + private ResourceConfig(String artifactId) { + this.resources = new Resource(Collections.singletonList( + new Pattern("\\Q" + artifactId + ".properties" + "\\E"))); + } + } + + public boolean generateResourceConfig() { + return !this.fluent; + } + // TODO: Template public String toProxyConfigJson() { List> result = proxies.stream().map(Collections::singletonList).collect(Collectors.toList()); @@ -94,7 +78,11 @@ public String toProxyConfigJson() { } public String toReflectConfigJson() { - List result = reflects.stream().map(Reflect::new).collect(Collectors.toList()); + List result = reflects.stream().map(ReflectConfig::new).collect(Collectors.toList()); return TemplateUtil.prettyPrintToJson(result); } + + public String toResourceConfigJson(String artifactId) { + return TemplateUtil.prettyPrintToJson(new ResourceConfig(artifactId)); + } } diff --git a/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java b/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java index 2efc2bda94..15f3aa9e17 100644 --- a/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java +++ b/javagen/src/main/java/com/azure/autorest/model/javamodel/JavaPackage.java @@ -302,10 +302,17 @@ public void addTestProxyAssetsJson(Project project) { public final void addGraalVmConfig(String groupId, String artifactId, GraalVmConfig graalVmConfig) { String metaInfPath = Paths.get("src", "main", "resources", "META-INF", "native-image", groupId, artifactId).toString(); + TextFile proxyConfigFile = new TextFile(Paths.get(metaInfPath, "proxy-config.json").toString(), graalVmConfig.toProxyConfigJson()); textFiles.add(proxyConfigFile); + TextFile reflectConfigFile = new TextFile(Paths.get(metaInfPath, "reflect-config.json").toString(), graalVmConfig.toReflectConfigJson()); textFiles.add(reflectConfigFile); + + if (graalVmConfig.generateResourceConfig()) { + TextFile resourceConfigFile = new TextFile(Paths.get(metaInfPath, "resource-config.json").toString(), graalVmConfig.toResourceConfigJson(artifactId)); + textFiles.add(resourceConfigFile); + } } protected void checkDuplicateFile(String filePath) { diff --git a/javagen/src/main/java/com/azure/autorest/model/projectmodel/Project.java b/javagen/src/main/java/com/azure/autorest/model/projectmodel/Project.java index d7c4905490..5412eba97d 100644 --- a/javagen/src/main/java/com/azure/autorest/model/projectmodel/Project.java +++ b/javagen/src/main/java/com/azure/autorest/model/projectmodel/Project.java @@ -40,10 +40,12 @@ public class Project { private static final Logger LOGGER = new PluginLogger(Javagen.getPluginInstance(), Project.class); + public static final String AZURE_GROUP_ID = "com.azure"; + protected String serviceName; protected String serviceDescription; protected String namespace; - protected String groupId = "com.azure"; + protected String groupId = AZURE_GROUP_ID; protected String artifactId; protected String version = "1.0.0-beta.1"; protected final List pomDependencyIdentifiers = new ArrayList<>(); diff --git a/javagen/src/test/java/com/azure/autorest/template/TestProxyAssertsTemplateTests.java b/javagen/src/test/java/com/azure/autorest/template/TestProxyAssertsTemplateTests.java index 08f5072c13..bd91b4e9eb 100644 --- a/javagen/src/test/java/com/azure/autorest/template/TestProxyAssertsTemplateTests.java +++ b/javagen/src/test/java/com/azure/autorest/template/TestProxyAssertsTemplateTests.java @@ -7,6 +7,7 @@ import com.azure.autorest.model.projectmodel.Project; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Assert; import org.junit.Test; @@ -30,7 +31,7 @@ public void testAssertsTemplateWrite() throws JsonProcessingException { String output = new TestProxyAssetsTemplate().write(project); - JsonNode jsonNode = TestProxyAssetsTemplate.OBJECT_MAPPER.readTree(output); + JsonNode jsonNode = new ObjectMapper().readTree(output); Assert.assertEquals("Azure/azure-sdk-assets", jsonNode.get("AssetsRepo").asText()); Assert.assertEquals("java", jsonNode.get("AssetsRepoPrefixPath").asText()); Assert.assertEquals("java/openai/azure-ai-openai", jsonNode.get("TagPrefix").asText()); diff --git a/readme.md b/readme.md index 560de39687..2cac2cea51 100644 --- a/readme.md +++ b/readme.md @@ -71,7 +71,7 @@ Settings can be provided on the command line through `--name:value` or in a READ |`--generate-client-as-impl`|Append "Impl" to the names of service clients and method groups and place them in the `implementation` sub-package. Default is false.| |`--generate-client-interfaces`|Implies `--generate-client-as-impl` and generates interfaces for all the "Impl"s. Default is false.| |`--generate-sync-async-clients`|Implies `--generate-client-as-impl` and generates sync and async convenience layer clients for all the "Impl"s. Default is false.| -|`--generate-builder-per-client`| Requires `--generate-sync-async-clients`, and generates one ClientBuilder for each Client. Default is false.| +|`--generate-builder-per-client`|Requires `--generate-sync-async-clients`, and generates one ClientBuilder for each Client. Default is false.| |`--implementation-subpackage=STRING`|The sub-package that the Service client and Method Group client implementation classes will be put into. Default is `implementation`.| |`--models-subpackage=STRING`|The sub-package that Enums, Exceptions, and Model types will be put into. Default is `models`.| |`--sync-methods=all\|essential\|none`|Specifies mode for generating sync wrappers. Supported value are
  `essential` - generates only one sync returning body or header (default)
  `all` - generates one sync method for each async method
  `none` - does not generate any sync methods| @@ -98,6 +98,7 @@ Settings can be provided on the command line through `--name:value` or in a READ |`--use-input-stream-for-binary`|Indicates that `InputStream` is used for binary response body. By default, `BinaryData` is used.| |`--enable-page-size`|Indicates that `maxpagesize` query parameter be supplied via `byPage` API in `PagedFlux` or `PagedIterable`, instead of via client method parameter.| |`--use-key-credential`|Indicates that builder uses `KeyCredential` for API key.| +|`--graal-vm-config`|Generates GraalVM config under `resources/META-INF/native-image`.| ## Settings for minimal data-plane clients