-
Notifications
You must be signed in to change notification settings - Fork 567
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Daniel Kec <[email protected]>
- Loading branch information
Showing
17 changed files
with
678 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
255 changes: 255 additions & 0 deletions
255
integrations/crac/src/main/java/io/helidon/integrations/crac/CracImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} | ||
|
||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
integrations/crac/src/main/java/io/helidon/integrations/crac/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.