Skip to content

Commit

Permalink
Separated crac dep
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Kec <[email protected]>
  • Loading branch information
danielkec committed Jan 24, 2025
1 parent 83029f5 commit 58ea364
Show file tree
Hide file tree
Showing 17 changed files with 678 additions and 66 deletions.
5 changes: 5 additions & 0 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,11 @@
<artifactId>helidon-mp-graal-native-image-extension</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.integrations.crac</groupId>
<artifactId>helidon-integrations-crac</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.integrations.common</groupId>
<artifactId>helidon-integrations-common-rest</artifactId>
Expand Down
6 changes: 6 additions & 0 deletions dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
<version.lib.zipkin.sender-urlconnection>2.16.4</version.lib.zipkin.sender-urlconnection>
<version.lib.zipkin>2.12.5</version.lib.zipkin>
<version.lib.zookeeper>3.5.7</version.lib.zookeeper>
<version.lib.crac>1.4.0</version.lib.crac>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -1092,6 +1093,11 @@
<artifactId>reactive-streams-tck</artifactId>
<version>${version.lib.reactivestreams}</version>
</dependency>
<dependency>
<groupId>org.crac</groupId>
<artifactId>crac</artifactId>
<version>${version.lib.crac}</version>
</dependency>
<!-- END OF Section 1: direct third party dependencies -->

<!-- Section 2: third party dependencies used by examples -->
Expand Down
45 changes: 45 additions & 0 deletions integrations/crac/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 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
http://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.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>io.helidon.integrations</groupId>
<artifactId>helidon-integrations-project</artifactId>
<version>4.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<groupId>io.helidon.integrations.crac</groupId>
<artifactId>helidon-integrations-crac</artifactId>
<name>Helidon CRaC support</name>

<dependencies>
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver</artifactId>
</dependency>
<dependency>
<groupId>org.crac</groupId>
<artifactId>crac</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
/*
* Copyright (c) 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
*
* http://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 io.helidon.integrations.crac;

import java.util.HashSet;
import java.util.Set;

import io.helidon.webserver.crac.spi.Crac;

import org.crac.management.CRaCMXBean;

/**
* Helidon abstraction over CRaC API, replaces no-op implementation when this module is present on classpath.
*/
public class CracImpl implements Crac {

private static final System.Logger LOGGER = System.getLogger(CracImpl.class.getName());
private static final Set<Object> STRONG_REFERENCES = new HashSet<>();

@Override
public io.helidon.webserver.crac.spi.Crac.Context<Resource> getGlobalContext() {
return new HelidonContext(org.crac.Core.getGlobalContext());
}

@Override
public long getUptimeSinceRestore() {
return CRaCMXBean.getCRaCMXBean().getUptimeSinceRestore();
}

@Override
public long getRestoreTime() {
return CRaCMXBean.getCRaCMXBean().getRestoreTime();
}

@Override
public void checkpointRestore() throws RestoreException, CheckpointException {
try {
org.crac.Core.checkpointRestore();
} catch (org.crac.RestoreException e) {
throw new HelidonRestoreException(e);
} catch (org.crac.CheckpointException e) {
throw new HelidonCheckpointException(e);
}
}

@Override
public void checkpointRestoreOnStartup() {
if ("onStart".equalsIgnoreCase(System.getProperty("io.helidon.crac.checkpoint"))) {
try {
org.crac.Core.checkpointRestore();
} catch (UnsupportedOperationException e) {
LOGGER.log(System.Logger.Level.DEBUG, "CRaC feature is not available", e);
} catch (org.crac.RestoreException e) {
LOGGER.log(System.Logger.Level.ERROR, "CRaC restore wasn't successful!", e);
} catch (org.crac.CheckpointException e) {
LOGGER.log(System.Logger.Level.ERROR, "CRaC checkpoint creation wasn't successful!", e);
}
}
}

private static class HelidonContext extends io.helidon.webserver.crac.spi.Crac.Context<Resource> {

private final org.crac.Context<org.crac.Resource> delegate;

HelidonContext(org.crac.Context<org.crac.Resource> delegate) {
this.delegate = delegate;
}

@SuppressWarnings("unchecked")
@Override
public void beforeCheckpoint(
io.helidon.webserver.crac.spi.Crac.Context<? extends io.helidon.webserver.crac.spi.Crac.Resource> context)
throws io.helidon.webserver.crac.spi.Crac.CheckpointException {
try {
delegate.beforeCheckpoint(new CracContext((Context<Resource>) context));
} catch (org.crac.CheckpointException e) {
throw new HelidonCheckpointException(e);
}
}

@SuppressWarnings("unchecked")
@Override
public void afterRestore(Context<? extends Resource> context) throws io.helidon.webserver.crac.spi.Crac.RestoreException {
try {
delegate.afterRestore(new CracContext((Context<Resource>) context));
} catch (org.crac.RestoreException e) {
throw new HelidonRestoreException(e);
}
}

@Override
public void register(Resource resource) {
CracResource resourceRef = new CracResource(resource);
// CRaC API keeps resources as weak refs, we don't want our wrappers being GCed
CracImpl.STRONG_REFERENCES.add(resourceRef);
delegate.register(resourceRef);
}

}

private static class HelidonCheckpointException extends io.helidon.webserver.crac.spi.Crac.CheckpointException {
private final org.crac.CheckpointException delegate;

HelidonCheckpointException(org.crac.CheckpointException delegate) {
this.delegate = delegate;
this.setStackTrace(delegate.getStackTrace());
}

@Override
public String getMessage() {
return delegate.getMessage();
}

}

private static class CracCheckpointException extends org.crac.CheckpointException {
private final io.helidon.webserver.crac.spi.Crac.CheckpointException delegate;

CracCheckpointException(io.helidon.webserver.crac.spi.Crac.CheckpointException delegate) {
this.delegate = delegate;
this.setStackTrace(delegate.getStackTrace());
}

@Override
public String getMessage() {
return delegate.getMessage();
}

}

private static class HelidonRestoreException extends io.helidon.webserver.crac.spi.Crac.RestoreException {
private final org.crac.RestoreException delegate;

HelidonRestoreException(org.crac.RestoreException delegate) {
this.delegate = delegate;
this.setStackTrace(delegate.getStackTrace());
}

@Override
public String getMessage() {
return delegate.getMessage();
}
}

private static class CracRestoreException extends org.crac.RestoreException {
private final io.helidon.webserver.crac.spi.Crac.RestoreException delegate;

CracRestoreException(io.helidon.webserver.crac.spi.Crac.RestoreException delegate) {
this.delegate = delegate;
this.setStackTrace(delegate.getStackTrace());
}

@Override
public String getMessage() {
return delegate.getMessage();
}
}

private static class CracContext extends org.crac.Context<org.crac.Resource> {

private final io.helidon.webserver.crac.spi.Crac.Context<io.helidon.webserver.crac.spi.Crac.Resource> delegate;

CracContext(io.helidon.webserver.crac.spi.Crac.Context<io.helidon.webserver.crac.spi.Crac.Resource> delegate) {
this.delegate = delegate;
}

@SuppressWarnings("unchecked")
@Override
public void beforeCheckpoint(org.crac.Context<? extends org.crac.Resource> context) throws org.crac.CheckpointException {
try {
delegate.beforeCheckpoint(new HelidonContext((org.crac.Context<org.crac.Resource>) context));
} catch (CheckpointException e) {
throw new CracCheckpointException(e);
}
}

@SuppressWarnings("unchecked")
@Override
public void afterRestore(org.crac.Context<? extends org.crac.Resource> context) throws org.crac.RestoreException {
try {
delegate.afterRestore(new HelidonContext((org.crac.Context<org.crac.Resource>) context));
} catch (RestoreException e) {
throw new CracRestoreException(e);
}
}

@Override
public void register(org.crac.Resource resource) {
delegate.register(new HelidonResource(resource));
}

}

private static class CracResource implements org.crac.Resource {

private final Resource delegate;

CracResource(Resource delegate) {
this.delegate = delegate;
}

@SuppressWarnings("unchecked")
@Override
public void beforeCheckpoint(org.crac.Context<? extends org.crac.Resource> context) throws Exception {
delegate.beforeCheckpoint(new HelidonContext((org.crac.Context<org.crac.Resource>) context));
}

@SuppressWarnings("unchecked")
@Override
public void afterRestore(org.crac.Context<? extends org.crac.Resource> context) throws Exception {
delegate.afterRestore(new HelidonContext((org.crac.Context<org.crac.Resource>) context));
}

}

private static class HelidonResource implements io.helidon.webserver.crac.spi.Crac.Resource {

private final org.crac.Resource delegate;

HelidonResource(org.crac.Resource delegate) {
this.delegate = delegate;
}

@SuppressWarnings("unchecked")
@Override
public void beforeCheckpoint(
io.helidon.webserver.crac.spi.Crac.Context<? extends io.helidon.webserver.crac.spi.Crac.Resource> context)
throws Exception {
delegate.beforeCheckpoint(new CracContext((Context<Resource>) context));
}

@SuppressWarnings("unchecked")
@Override
public void afterRestore(
io.helidon.webserver.crac.spi.Crac.Context<? extends io.helidon.webserver.crac.spi.Crac.Resource> context)
throws Exception {
delegate.afterRestore(new CracContext((Context<Resource>) context));
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) 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
*
* http://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.
*/

/**
* Helidon abstraction over CRaC API, replaces no-op implementation when this module is present on classpath.
*/
package io.helidon.integrations.crac;
22 changes: 22 additions & 0 deletions integrations/crac/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 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
*
* http://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.
*/

module io.helidon.integrations.crac {
requires crac;
requires io.helidon.webserver;
exports io.helidon.integrations.crac to io.helidon.webserver;
provides io.helidon.webserver.crac.spi.Crac with io.helidon.integrations.crac.CracImpl;
}
1 change: 1 addition & 0 deletions integrations/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<modules>
<module>common</module>
<module>cdi</module>
<module>crac</module>
<module>graal</module>
<module>db</module>
<module>jdbc</module>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ static List<Tag> createTags(String pairs) {
* @return true to include meters related to virtual threads
*/
@Option.Configured("virtual-threads.enabled")
@Option.DefaultBoolean(true)
@Option.DefaultBoolean(false)
boolean virtualThreadsEnabled();

/**
Expand Down
Loading

0 comments on commit 58ea364

Please sign in to comment.