Skip to content

Commit

Permalink
4.7.3.2 release (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
burtbeckwith authored Feb 24, 2025
1 parent 832f7dd commit 4fc6a54
Show file tree
Hide file tree
Showing 23 changed files with 241 additions and 95 deletions.
11 changes: 11 additions & 0 deletions gdk-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ dependencies {
exclude group: 'org.eclipse.jgit', module: 'org.eclipse.jgit'
}
implementation(mnLibs.micronaut.http.client)
implementation(libs.netty.buffer)
implementation(libs.netty.codec)
implementation(libs.netty.codec.http)
implementation(libs.netty.codec.http2)
implementation(libs.netty.codec.socks)
implementation(libs.netty.common)
implementation(libs.netty.handler)
implementation(libs.netty.handler.proxy)
implementation(libs.netty.resolver)
implementation(libs.netty.transport)
implementation(libs.netty.transport.native.unix.common)
}

def writeVersions = tasks.register('writeVersions', cloud.graal.gdk.util.WriteVersionsTask) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ private JdkVersion jdkVersion(Integer majorVersion) {
return JdkVersion.valueOf(majorVersion);
}

private List<String> derivedFeatures(List<GdkCloud> clouds,
public List<String> derivedFeatures(List<GdkCloud> clouds,
List<GdkService> services,
List<String> features,
GdkProjectType projectType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,12 @@ abstract class EnforceBomDependencies implements ComponentMetadataRule {
constraints.each { constraint ->
String key = "${constraint.group}:${constraint.module}"
if (gdkBomConstraints.containsKey(key)) {
String version = constraint.versionConstraint.requiredVersion
String gdkVersionWithoutSuffix = gdkBomConstraints.get(key).replaceAll(/-oracle-\d+$/, '')
if (version == gdkVersionWithoutSuffix) {
constraint.version {
strictly(gdkBomConstraints[key])
}
constraint.version {
strictly(gdkBomConstraints[key])
}
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,9 @@ open class EnforceBomDependencies : ComponentMetadataRule {
forEach { constraint ->
val key = "${constraint.group}:${constraint.module}"
if (gdkBomConstraints.containsKey(key)) {
val version = constraint.versionConstraint.requiredVersion
val gdkVersionWithoutSuffix = gdkBomConstraints[key]?.replace(Regex("-oracle-\\d+$"), "")

if (version == gdkVersionWithoutSuffix) {
constraint.version {
gdkBomConstraints[key]?.let { newVersion ->
strictly(newVersion)
}
constraint.version {
gdkBomConstraints[key]?.let { newVersion ->
strictly(newVersion)
}
}
}
Expand All @@ -50,4 +45,4 @@ open class EnforceBomDependencies : ComponentMetadataRule {
}

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2025 Oracle and/or its affiliates
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cloud.graal.gdk.feature.misc;

import cloud.graal.gdk.GdkGeneratorContext;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.starter.application.ApplicationType;
import io.micronaut.starter.application.generator.GeneratorContext;
import io.micronaut.starter.feature.Feature;
import io.micronaut.starter.feature.graalvm.GraalVM;
import io.micronaut.starter.options.BuildTool;
import jakarta.inject.Singleton;

@Singleton
public class CycloneDXPlugin implements Feature {

/**
* The feature name.
*/
public static final String NAME = "cyclone-dx-plugin";

private static final CycloneDXPluginPostProcessor CYCLONE_DX_POST_PROCESSOR = new CycloneDXPluginPostProcessor(BuildTool.GRADLE);

private final GraalVM graalvm;

public CycloneDXPlugin(GraalVM graalvm) {
this.graalvm = graalvm;
}

@Override
public void apply(GeneratorContext ctx) {
if (ctx.getBuildTool().isGradle()) {
String template = "build";
if (!((GdkGeneratorContext) ctx).getCloud().getModuleName().isBlank()) {
template = template + "-" + ((GdkGeneratorContext) ctx).getCloud().getModuleName();
}
((GdkGeneratorContext) ctx).addPostProcessor(template, CYCLONE_DX_POST_PROCESSOR);
}
}

@NonNull
@Override
public String getName() {
return NAME;
}

@Override
public boolean supports(ApplicationType applicationType) {
return true;
}

@Override
public boolean isVisible() {
return false;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2025 Oracle and/or its affiliates
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cloud.graal.gdk.feature.misc;

import cloud.graal.gdk.template.TemplatePostProcessor;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.starter.options.BuildTool;

public class CycloneDXPluginPostProcessor implements TemplatePostProcessor {

private static final String PLUGIN_START = "plugins {";
private static final String CYCLONE_DX_PLUGIN = "\n\tid 'org.cyclonedx.bom' version '2.1.0'";

private static final String CYCLONE_DX_CONFIG = """
cyclonedxBom {
includeConfigs = ["compileClasspath", "runtimeClasspath"]
}
""";

private final BuildTool buildTool;

public CycloneDXPluginPostProcessor(BuildTool buildTool) {
this.buildTool = buildTool;
}

@NonNull
@Override
public String process(@NonNull String input) {
String result = input;
if (buildTool.isGradle()) {
int start = input.indexOf(PLUGIN_START);
if (start >= 0) {
start += PLUGIN_START.length();
String top = input.substring(0, start);
String bottom = input.substring(start);
result = top + CYCLONE_DX_PLUGIN + bottom + CYCLONE_DX_CONFIG;
}
}
return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,35 @@ import java.util.Optional;
import static io.micronaut.http.HttpHeaders.LOCATION;
import static io.micronaut.http.HttpStatus.NO_CONTENT;

@@ExecuteOn(TaskExecutors.IO)
@@Controller("/genres")
@@ExecuteOn(TaskExecutors.IO) // <1>
@@Controller("/genres") // <2>
class GenreController {

private final GenreService genreService;

GenreController(GenreService genreService) {
GenreController(GenreService genreService) { // <3>
this.genreService = genreService;
}

@@Get("/{id}")
@@Get("/{id}") // <4>
public Optional<Genre> show(Long id) {
return genreService.findById(id);
}

@@Put("/{id}/{name}")
@@Put("/{id}/{name}") // <5>
public HttpResponse<?> update(long id, String name) {
genreService.update(id, name);
return HttpResponse
.noContent()
.header(LOCATION, URI.create("/genres/" + id).getPath());
}

@@Get("/list")
@@Get("/list") // <6>
public List<Genre> list(@@Valid Pageable pageable) {
return genreService.list(pageable);
}

@@Post
@@Post // <7>
public HttpResponse<Genre> save(@@Body("name") @@NotBlank String name) {
Genre genre = genreService.save(name);

Expand All @@ -65,7 +65,7 @@ class GenreController {
.headers(headers -> headers.location(URI.create("/genres/" + genre.getId())));
}

@@Delete("/{id}")
@@Delete("/{id}") // <8>
@@Status(NO_CONTENT)
public void delete(Long id) {
genreService.delete(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import jakarta.validation.constraints.NotBlank;

import static io.micronaut.data.model.query.builder.sql.Dialect.@(dialect);

@@JdbcRepository(dialect = @(dialect))
public interface GenreRepository extends PageableRepository<Genre, Long> {
@@JdbcRepository(dialect = @(dialect)) // <1>
public interface GenreRepository extends PageableRepository<Genre, Long> { // <2>

Genre save(@@NonNull @@NotBlank String name);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

@@Requires(property = "spec.name", value = "MailControllerTest")
@@Requires(property = "spec.name", value = "MailControllerTest") // <1>
@@Singleton
@@Replaces(AsyncSesEmailSender.class)
@@Named(AsyncSesEmailSender.NAME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ import software.amazon.awssdk.services.ses.model.SesResponse;
import static io.micronaut.email.BodyType.HTML;
import static io.micronaut.http.HttpStatus.UNPROCESSABLE_ENTITY;

@@Controller("/mail")
@@Controller("/mail") // <1>
class MailController {

private static final Logger LOG = LoggerFactory.getLogger(MailController.class);

private final AsyncEmailSender<SesRequest, SesResponse> emailSender;

MailController(AsyncEmailSender<SesRequest, SesResponse> emailSender) {
MailController(AsyncEmailSender<SesRequest, SesResponse> emailSender) { // <2>
this.emailSender = emailSender;
}

@@Post("/send")
public Publisher<HttpResponse<?>> send(@@Body("to") String to) {
@@Post("/send") // <3>
public Publisher<HttpResponse<?>> send(@@Body("to") String to) { // <4>
return Mono.from(emailSender.sendAsync(Email.builder()
.to(to)
.subject("Sending email with Amazon SES is Fun")
Expand All @@ -46,6 +46,6 @@ class MailController {
LOG.info("message id: {}", ((SendEmailResponse) rsp).messageId());
}
}).onErrorMap(EmailException.class, t -> new HttpStatusException(UNPROCESSABLE_ENTITY, "Email could not be sent"))
.map(rsp -> HttpResponse.accepted());
.map(rsp -> HttpResponse.accepted()); // <5>
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

@@Property(name = "spec.name", value = "MailControllerTest")
@@Property(name = "spec.name", value = "MailControllerTest") // <1>
@@Property(name = "micronaut.email.from.email", value = "mo@@gdk.example")
@@MicronautTest
@@MicronautTest // <2>
class MailControllerTest {

@@Inject
@@Client("/")
HttpClient httpClient;
HttpClient httpClient; // <3>

@@Inject
BeanContext beanContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,28 @@ import io.micronaut.scheduling.annotation.ExecuteOn;

import static io.micronaut.email.BodyType.HTML;

@@ExecuteOn(TaskExecutors.IO)
@@Controller("/email")
@@ExecuteOn(TaskExecutors.IO) // <1>
@@Controller("/email") // <2>
public class EmailController {

private final EmailSender<?, ?> emailSender;

EmailController(EmailSender<?, ?> emailSender) {
EmailController(EmailSender<?, ?> emailSender) { // <3>
this.emailSender = emailSender;
}

@@Post("/send")
public HttpResponse<?> send(@@Body("to") String to) {
@@Post("/send") // <4>
public HttpResponse<?> send(@@Body("to") String to) { // <5>

try {
emailSender.send(Email.builder()
.to(to)
.subject("Sending email with JavaMail is Fun")
.body("and <em>easy</em> to do anywhere with <strong>Micronaut Email</strong>", HTML));
.body("and <em>easy</em> to do anywhere with <strong>Micronaut Email</strong>", HTML)); // <6>
} catch (EmailException ignored) {
return HttpResponse.unprocessableEntity();
return HttpResponse.unprocessableEntity(); // <7>
}

return HttpResponse.accepted();
return HttpResponse.accepted(); // <8>
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,22 @@ import static io.micronaut.http.HttpStatus.ACCEPTED;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@@Property(name = "FROM_EMAIL", value = "bob@@gdk.example")
@@Property(name = "FROM_EMAIL", value = "bob@@gdk.example") // <1>
@@Property(name = "FROM_PASSWORD", value = "example-password")
@@MicronautTest
@@MicronautTest // <2>
public class EmailControllerTest {

@@Inject
@@Client("/")
HttpClient client;
HttpClient client; // <3>

Email sentEmail;

@@Test
void testSend() {
var response = client.toBlocking().exchange(
HttpRequest.POST("/email/send",
Map.of("to", "alice@@gdk.example")));
Map.of("to", "alice@@gdk.example"))); // <4>

assertEquals(ACCEPTED, response.status());

Expand All @@ -57,7 +57,7 @@ public class EmailControllerTest {

}

@@MockBean(TransactionalEmailSender.class)
@@MockBean(TransactionalEmailSender.class) // <5>
@@Named("mock")
TransactionalEmailSender<Message, Void> mockSender() {
return new TransactionalEmailSender<>() {
Expand Down
Loading

0 comments on commit 4fc6a54

Please sign in to comment.