diff --git a/docs/includes/oci.adoc b/docs/includes/oci.adoc new file mode 100644 index 00000000000..a3f831e84c3 --- /dev/null +++ b/docs/includes/oci.adoc @@ -0,0 +1,70 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2022 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. + +/////////////////////////////////////////////////////////////////////////////// + +ifndef::rootdir[:rootdir: {docdir}/..] + +== Resolving javax and jakarta package compatibility issue with OCI SDK + +With Helidon 3, we are now implementing the MicroProfile 5 Platform and selected Jakarta EE 9.1 specifications. We are also going away from javax.* packages and fully embracing jakarta.* package. + +However, the current release 2.35.0 of OCI Java SDK is still using javax.* packages which created compatibility issues e.g. Helidon 3 uses JAX-RS 3.0.0 (jakarta package names) and the corresponding Jersey implementation. OCI SDK 2.35.0 uses JAX-RS Client 2.1.6 (javax package names) and the corresponding Jersey implementation. Therefore, the OCI SDK is incompatible with Helidon 3 applications and any application that uses JAX-RS 3. We have filed an issue with OCI SDK team, see https://github.com/oracle/oci-java-sdk/issues/371 for details on this. + +OCI SDK team has provided us with `shaded` jar as workaround as mentioned in the issue. However, this jar is not available in maven-central as of now. See issue https://github.com/oracle/oci-java-sdk/issues/410 for details on that, so user will have to do manual setup/install of this `shaded` jar. You only have to do this once per version of SDK. + +* Download OCI SDK from https://github.com/oracle/oci-java-sdk/releases/download/v2.35.0/oci-java-sdk-2.35.0.zip +* Unzip the SDK +[source,bash] +---- +unzip -j -p oci-java-sdk-2.35.0.zip shaded/lib/oci-java-sdk-full-shaded-2.35.0.jar > oci-java-sdk-shaded-full-2.35.0.jar +---- +* Install `shaded` jar in your local maven repo, see https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html +[source,bash] +---- +mvn -N org.apache.maven.plugins:maven-install-plugin:install-file -Dfile=oci-java-sdk-shaded-full-2.35.0.jar -DlocalRepositoryPath="~/.m2/repository" -DgroupId=com.oracle.oci.sdk -DartifactId=oci-java-sdk-shaded-full -Dversion=2.35.0 -Dpackaging=jar +---- + +Now, when you want to use modules from OCI SDK in your application, instead of using individual modules as defined in our OCI integration documentation, you need to use `full shaded` jar. + +[source,xml] +---- + + com.oracle.oci.sdk + oci-java-sdk-shaded-full + 2.35.0 + +---- + +Since the `full shaded` jar doesn't bring in its transitive dependencies, you will also need to define following dependencies in your application so that it works at runtime. + +[source,xml] +---- + + org.bouncycastle + bcpkix-jdk15on + 1.70 + runtime + + + org.slf4j + slf4j-jdk14 + 1.7.32 + runtime + +---- + +Please refer to our link:{helidon-github-tree-url}/examples/integrations/oci[OCI SDK Usage Examples] to see this in action. \ No newline at end of file diff --git a/docs/mp/vault.adoc b/docs/mp/integrations/hcv.adoc similarity index 86% rename from docs/mp/vault.adoc rename to docs/mp/integrations/hcv.adoc index 5c0c297f493..d59aecda93e 100644 --- a/docs/mp/vault.adoc +++ b/docs/mp/integrations/hcv.adoc @@ -16,153 +16,140 @@ /////////////////////////////////////////////////////////////////////////////// -= Vault -:description: Helidon Vault integration -:keywords: vault -:feature-name: Vault -:rootdir: {docdir}/.. += HashiCorp Vault +:description: Helidon HashiCorp Vault integration +:keywords: vault, hashicorp +:feature-name: HashiCorp Vault +:rootdir: {docdir}/../.. include::{rootdir}/includes/mp.adoc[] -HashiCorp Vault is a commonly used Vault in many microservices. The APIs are REST-based and Helidon implements them using reactive client. - -Vault integration supports the following: - -* *Secret Engines*: Key/Value version 2, Key/Value version 1, Cubbyhole, PKI, Transit, Database -* *Authentication Methods*: Token, Kubernetes (k8s), AppRole -* *Other Sys Operations and Configurations* - -== Experimental - -WARNING: Helidon Vault support is still experimental and not intended for production use. APIs and features have not yet been fully tested and are subject to change. - -== Sys Operations - -Each of these features is implemented as a separate module, with the Vault class binding them together. In Helidon MP, with injection, this binding is done automatically, and you can simply inject your favorite secret engine. - -In addition to these features, Vault itself can be authenticated as follows: +== ToC -* Token authentication - token is configured when connecting to Vault -* AppRole authentication - AppRole ID and secret ID are configured, integration exchanges these for a temporary token that is used to connect to Vault -* K8s authentication - the k8s JWT token is discovered on current node and used to obtain a temporary token that is used to connect to Vault - -== Extensibility +- <> +- <> +- <> +- <> +- <> +- <> -New secret engines and authentication methods can be implemented quite easily, as the integration is based on service providers (using ServiceLoader). This gives us (or you, as the users) the option to add new secret engines and/or authentication methods without adding a plethora of methods to the Vault class. - -See the following SPIs: +== Overview -[source,listing] ----- -io.helidon.integrations.vault.spi.AuthMethodProvider -io.helidon.integrations.vault.spi.SecretsEngineProvider -io.helidon.integrations.vault.spi.SysProvider -io.helidon.integrations.vault.spi.VaultAuth -io.helidon.integrations.vault.spi.InjectionProvider ----- - -== Modules +HashiCorp Vault is a commonly used Vault in many microservices. The APIs are REST-based and Helidon implements them using reactive client. -The following is a list of maven coordinates of all Vault modules available: +include::{rootdir}/includes/dependencies.adoc[] [source,xml] ---- - - - io.helidon.integrations.vault - helidon-integrations-vault - - - io.helidon.integrations.vault.auths - helidon-integrations-vault-auths-token - - - io.helidon.integrations.vault.auths - helidon-integrations-vault-auths-approle - - - io.helidon.integrations.vault.auths - helidon-integrations-vault-auths-k8s - - - io.helidon.integrations.vault.secrets - helidon-integrations-vault-secrets-kv1 - - - io.helidon.integrations.vault.secrets - helidon-integrations-vault-secrets-kv2 - - - io.helidon.integrations.vault.secrets - helidon-integrations-vault-secrets-cubbyhole - - - io.helidon.integrations.vault.secrets - helidon-integrations-vault-secrets-transit - - - io.helidon.integrations.vault.secrets - helidon-integrations-vault-secrets-database - - - io.helidon.integrations.vault.sys - helidon-integrations-vault-sys - - + + io.helidon.integrations.vault + helidon-integrations-vault-cdi + ---- -To use Vault integration in MP, the following module must be added, as it enables injection of all features: +The following is a list of maven coordinates of all Vault modules available: [source,xml] ---- - io.helidon.integrations.vault - helidon-integrations-vault-cdi + io.helidon.integrations.vault.auths + helidon-integrations-vault-auths-token + + + io.helidon.integrations.vault.auths + helidon-integrations-vault-auths-approle + + + io.helidon.integrations.vault.auths + helidon-integrations-vault-auths-k8s + + + io.helidon.integrations.vault.secrets + helidon-integrations-vault-secrets-kv1 + + + io.helidon.integrations.vault.secrets + helidon-integrations-vault-secrets-kv2 + + + io.helidon.integrations.vault.secrets + helidon-integrations-vault-secrets-cubbyhole + + + io.helidon.integrations.vault.secrets + helidon-integrations-vault-secrets-transit + + + io.helidon.integrations.vault.secrets + helidon-integrations-vault-secrets-database + + + io.helidon.integrations.vault.sys + helidon-integrations-vault-sys ---- -Configuration to connect to Vault. +== Usage + +Vault integration supports the following: + +* *Secret Engines*: Key/Value version 2, Key/Value version 1, Cubbyhole, PKI, Transit, Database +* *Authentication Methods*: Token, Kubernetes (k8s), AppRole +* *Other Sys Operations and Configurations* -. Authenticating using Token: -+ +Each of these features is implemented as a separate module, with the Vault class binding them together. In Helidon MP, with injection, this binding is done automatically, and you can simply inject your favorite secret engine. + +The following classes can be injected into any CDI bean (if appropriate module is on the classpath): + +* Kv2Secrets - Key/Value Version 2 Secrets (versioned secrets, default) +* Kv1Secrets - Key/Value Version 1 Secrets (un-versioned secrets, legacy) +* CubbyholeSecrets - Cubbyhole secrets (token bound secrets) +* DbSecrets - Database secrets (for generating temporary DB credentials) +* PkiSecrets - PKI secrets (for generating keys and X.509 certificates) +* TransitSecrets - Transit operations (encryption, signatures, HMAC) +* AppRoleAuth - AppRole authentication method (management operations) +* K8sAuth - Kubernetes authentication method (management operations) +* TokenAuth - Token authentication method (management operations) +* Sys - System operations (management of Vault - enabling/disabling secret engines and authentication methods) +* *Rx - reactive counterparts to the classes defined above, usually not recommended in CDI, as it is a blocking environment + +In addition to these features, Vault itself can be authenticated as follows: + +* Token authentication - token is configured when connecting to Vault [source,properties] ---- vault.address=http://localhost:8200 vault.token=my-token ---- -+ -. Authenticating using AppRole: -+ +* AppRole authentication - AppRole ID and secret ID are configured, integration exchanges these for a temporary token that is used to connect to Vault [source,properties] ---- vault.auth.app-role.role-id=app-role-id vault.auth.app-role.secret-id=app-role-secret-id ---- -+ -. Authenticating using Kubernetes: -+ +* K8s authentication - the k8s JWT token is discovered on current node and used to obtain a temporary token that is used to connect to Vault [source,properties] ---- vault.auth.k8s.token-role=my-role <1> ---- <1> The token role must be configured in Vault -The following classes can be injected into any CDI bean (if appropriate module is on the classpath): +=== Extensibility -* Kv2Secrets - Key/Value Version 2 Secrets (versioned secrets, default) -* Kv1Secrets - Key/Value Version 1 Secrets (un-versioned secrets, legacy) -* CubbyholeSecrets - Cubbyhole secrets (token bound secrets) -* DbSecrets - Database secrets (for generating temporary DB credentials) -* PkiSecrets - PKI secrets (for generating keys and X.509 certificates) -* TransitSecrets - Transit operations (encryption, signatures, HMAC) -* AppRoleAuth - AppRole authentication method (management operations) -* K8sAuth - Kubernetes authentication method (management operations) -* TokenAuth - Token authentication method (management operations) -* Sys - System operations (management of Vault - enabling/disabling secret engines and authentication methods) -* *Rx - reactive counterparts to the classes defined above, usually not recommended in CDI, as it is a blocking environment +New secret engines and authentication methods can be implemented quite easily, as the integration is based on service providers (using ServiceLoader). This gives us (or you, as the users) the option to add new secret engines and/or authentication methods without adding a plethora of methods to the Vault class. +See the following SPIs: -== Usage +[source,listing] +---- +io.helidon.integrations.vault.spi.AuthMethodProvider +io.helidon.integrations.vault.spi.SecretsEngineProvider +io.helidon.integrations.vault.spi.SysProvider +io.helidon.integrations.vault.spi.VaultAuth +io.helidon.integrations.vault.spi.InjectionProvider +---- + +== Examples The following example shows usage of Vault to encrypt a secret using the default Vault configuration (in a JAX-RS resource): @@ -529,7 +516,7 @@ public class TransitResource { <9> Verify HMAC. <10> Verify signature. -== Local testing +== Local Testing [[Local-Testing]] Vault is available as a docker image, so to test locally, you can simply: @@ -538,4 +525,8 @@ Vault is available as a docker image, so to test locally, you can simply: docker run -e VAULT_DEV_ROOT_TOKEN_ID=my-token -d --name=vault -p8200:8200 vault ---- -This will create a Vault docker image, run it in background and open it on localhost:8200 with a custom root token my-token, using name vault. This is of course only suitable for local testing, as the root token has too many rights, but it can be easily used with the examples below. +This will create a Vault docker image, run it in background and open it on `localhost:8200` with a custom root token my-token, using name vault. This is of course only suitable for local testing, as the root token has too many rights, but it can be easily used with the examples below. + +== References + +* link:{helidon-github-tree-url}/examples/integrations/vault[Hashicorp Vault Usage Examples] \ No newline at end of file diff --git a/docs/mp/oci/oci.adoc b/docs/mp/integrations/oci.adoc similarity index 57% rename from docs/mp/oci/oci.adoc rename to docs/mp/integrations/oci.adoc index 8cf48bd7261..eb3869693f2 100644 --- a/docs/mp/oci/oci.adoc +++ b/docs/mp/integrations/oci.adoc @@ -16,6 +16,7 @@ /////////////////////////////////////////////////////////////////////////////// + = Oracle Cloud Infrastructure Integration :description: Helidon OCI Integration :keywords: oci, cdi @@ -24,8 +25,20 @@ include::{rootdir}/includes/mp.adoc[] +== ToC + +- <> +- <> +- <> +- <> +- <> + +== Overview + Helidon MP OCI Integration provides easy access to Oracle Cloud Infrastructure using the OCI Java SDK. +NOTE: OCI SDK uses JAX-RS Client 2.1.6 (javax package names), which makes it incompatible with Helidon 3 applications and any application that uses JAX-RS 3 (jakarta package naming). Please see our link:{rootdir}/includes/oci.adoc[Guide] for detailed information on how to work around this issue. + include::{rootdir}/includes/dependencies.adoc[] [source,xml] @@ -36,24 +49,24 @@ include::{rootdir}/includes/dependencies.adoc[] ---- -== The Helidon OCI SDK Extension +== Usage -When added to your application this link:{jakarta-cdi-spec-url}#spi[CDI portable extension] provides support for +When added to your application Helidon OCI SDK link:{jakarta-cdi-spec-url}#spi[CDI portable extension] provides support for injecting link:{oci-javasdk-url}[Oracle Cloud Infrastructure SDK Clients] in your Helidon MicroProfile application. The extension also handles authenticating with OCI by automatically picking up OCI credentials from your environment. -== Configuring the Helidon OCI SDK Extension +=== Configuring the Helidon OCI SDK Extension When you inject an OCI SDK Client object, the Helidon OCI SDK extension configures and constructs the object for you. The configuration primarily -consists of initializing an OCI `AuthenticationDetailsProvider`. By default +consists of initializing an OCI `AuthenticationDetailsProvider`. By default, the extension will examine your environment and select the best `AuthenticationDetailsProvider` and configure it for you. This means if your environment is already set up to work with the OCI SDK or the OCI command line, then it is very likely you do not need to do any additional -configuration of the extension. Just add it as a dependency and it will self-configure. +configuration of the extension. Just add it as a dependency, and it will self-configure. If for some reason you require full control over the OCI configuration you have that as well. For more information concerning the extension and its configuration @@ -62,7 +75,7 @@ link:{integration-oci-sdk-cdi-javadoc-base-url}/io/helidon/integrations/oci/sdk/ javadocs. In particular the `oci.auth-strategies` property lets you control which `AuthenticationDetailsProvider` will be used. -== Accessing OCI Services +=== Accessing OCI Services Since the Helidon OCI SDK extension supports injecting any OCI client from the OCI SDK, you can use it to access any OCI service supported by the @@ -74,9 +87,57 @@ You will also need to configure your environment to authenticate with OCI. It is recommended that you do this first, and verify your configuration by using the link:{oci-javasdk-url}[OCI CLI] to access the service. -The following documentation will help you get started with some -common OCI Services: +== Examples + +This example describes how to use Helidon OCI SDK Extension to access OCI Object Storage. + +As mentioned above in xref:#_accessing_oci_services[], you need to add a dependency on the OCI SDK +Object Storage API: + +[source,xml] +---- + + com.oracle.oci.sdk + oci-java-sdk-objectstorage + +---- + +=== Injecting an Object Storage Client + +Now you can inject OCI SDK Clients. + +[source,java] +.Field-injection example +---- +@Inject +private ObjectStorage client; +---- + +[source,java] +.Constructor-injection example +---- +public class MyClass { + + private final ObjectStorage client; + + @Inject + public YourConstructor(@Named("orders") ObjectStorage client) { + this.client = client; + } +} +---- + +The extension implements this injection point by creating an Object Storage client +object in the link:{jakarta-inject-javadoc-url}/jakarta/inject/Singleton.html[singleton scope]. + +=== Using the Object Storage client + +Once you have injected an ObjectStorage client you can use it as described in: + +* link:{oci-javasdk-objstore-javadoc-base-url}/package-summary.html[OCI SDK Object Storage Javadocs] +* link:{oci-objstore-url}[OCI Object Storage Overview] + +== References -- xref:object-storage.adoc[OCI Object Storage] -- xref:vault.adoc[OCI Vault] -- xref:atp.adoc[OCI ATP] +* link:{integration-oci-sdk-cdi-javadoc-base-url}/io/helidon/integrations/oci/sdk/cdi/OciExtension.html[OciExtension] Javadocs +* link:{helidon-github-tree-url}/examples/integrations/oci[OCI SDK Usage Examples] \ No newline at end of file diff --git a/docs/mp/oci/atp.adoc b/docs/mp/oci/atp.adoc deleted file mode 100644 index df84b9d9e5a..00000000000 --- a/docs/mp/oci/atp.adoc +++ /dev/null @@ -1,81 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2021, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= OCI ATP -:description: Helidon OCI ATP integration -:keywords: oci, atp -:feature-name: OCI Autonomous Transaction Processing -:rootdir: {docdir}/../.. - -include::{rootdir}/includes/mp.adoc[] - -You can use Helidon's xref:oci.adoc[OCI SDK Extension] to access OCI Services. -This document describes how to use it to access the OCI Database Service. - -include::{rootdir}/includes/dependencies.adoc[] - -[source,xml] ----- - - io.helidon.integrations.oci.sdk - helidon-integrations-oci-sdk-cdi - ----- - -Then add dependencies on the OCI SDK's Database API. Your specific -dependencies may differ depending on the OCI SDK features you use. - -[source,xml] ----- - - com.oracle.oci.sdk - oci-java-sdk-database - ----- - -== Injecting a Database client - -Once you have Helidon's OCI extension added to your application you can inject -OCI SDK Clients. - -[source,java] -.Field-injection example ----- -@Inject -private Database database; ----- - -The extension implements these injection points by creating -objects in the link:{jakarta-inject-javadoc-url}/jakarta/inject/Singleton.html[singleton scope]. - -== Configuring the Helidon OCI SDK Extension - -By default the extension will select and configure an appropriate -OCI Authentication Details Provider for you based on your environment. -For this reason it is recommended that you configure your environment -first and get it working with the link:{oci-javasdk-url}[OCI CLI] -before using the Helidon OCI SDK Extension. - -For more information see xref:oci.adoc[Helidon OCI Extension]. - -== Using the Database client - -Once you have injected OCI Database objects you can use them as described in: - -* link:{oci-javasdk-database-javadoc-base-url}/package-summary.html[OCI SDK Database Javadocs] -* link:{oci-database-url}[OCI Database Overview] diff --git a/docs/mp/oci/object-storage.adoc b/docs/mp/oci/object-storage.adoc deleted file mode 100644 index c14e7cc65db..00000000000 --- a/docs/mp/oci/object-storage.adoc +++ /dev/null @@ -1,92 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2021, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= OCI Object Storage -:description: Helidon OCI Object Storage integration -:keywords: oci, objectstorage -:feature-name: OCI Object Storage -:rootdir: {docdir}/../.. - -include::{rootdir}/includes/mp.adoc[] - -You can use Helidon's xref:oci.adoc[OCI SDK Extension] to access OCI Services. -This document describes how to use it to access OCI Object Storage. - -include::{rootdir}/includes/dependencies.adoc[] - -[source,xml] ----- - - io.helidon.integrations.oci.sdk - helidon-integrations-oci-sdk-cdi - ----- - -Then add a dependency on the OCI SDK's Object Storage API: - -[source,xml] ----- - - com.oracle.oci.sdk - oci-java-sdk-objectstorage - ----- - -== Injecting an Object Storage client - -Once you have Helidon's OCI extension added to your application you can inject OCI SDK Clients. - -[source,java] -.Field-injection example ----- -@Inject -private ObjectStorage client; ----- - -[source,java] -.Constructor-injection example ----- -public class MyClass { - - private final ObjectStorage client; - - @Inject - public YourConstructor(@Named("orders") ObjectStorage client) { - this.client = client; - } -} ----- - -The extension implements this injection point by creating an Object Storage client -object in the link:{jakarta-inject-javadoc-url}/jakarta/inject/Singleton.html[singleton scope]. - -== Configuring the Helidon OCI SDK Extension - -By default the extension will select and configure an appropriate -OCI Authentication Details Provider for you based on your environment. -For this reason it is recommended that you configure your environment first and get it working with the -link:{oci-javasdk-url}[OCI CLI] before using the Helidon OCI SDK Extension. - -For more information see xref:oci.adoc[Helidon OCI Extension]. - -== Using the Object Storage client - -Once you have injected an ObjectStorage client you can use it as described in: - -* link:{oci-javasdk-objstore-javadoc-base-url}/package-summary.html[OCI SDK Object Storage Javadocs] -* link:{oci-objstore-url}[OCI Object Storage Overview] diff --git a/docs/mp/oci/vault.adoc b/docs/mp/oci/vault.adoc deleted file mode 100644 index 7f7dffd0592..00000000000 --- a/docs/mp/oci/vault.adoc +++ /dev/null @@ -1,103 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2021, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= OCI Vault -:description: Helidon OCI Vault integration -:keywords: oci, vault -:feature-name: OCI Vault -:rootdir: {docdir}/../.. - -include::{rootdir}/includes/mp.adoc[] - -You can use Helidon's xref:oci.adoc[OCI SDK Extension] to access OCI Services. -This document describes how to use it to access OCI Vault. - -include::{rootdir}/includes/dependencies.adoc[] - -[source,xml] ----- - - io.helidon.integrations.oci.sdk - helidon-integrations-oci-sdk-cdi - ----- - -Then add dependencies on the OCI SDK's Vault API. -Your specific dependencies may differ depending on the OCI SDK features you use. - -[source,xml] ----- - - - com.oracle.oci.sdk - oci-java-sdk-vault - - - com.oracle.oci.sdk - oci-java-sdk-keymanagement - - - com.oracle.oci.sdk - oci-java-sdk-secrets - - ----- - -== Injecting a Vault client - -Once you have Helidon's OCI extension added to your application you can inject OCI SDK Clients. - -[source,java] -.Field-injection example ----- -@Inject -private Vaults vaults; ----- - -[source,java] -.Constructor-injection example ----- -class VaultResource { - @Inject - VaultResource(Secrets secrets, KmsCrypto crypto, Vaults vaults) { - this.secrets = secrets; - this.crypto = crypto; - this.vaults = vaults; - } -} ----- - -The extension implements these injection points by creating objects in the - link:{jakarta-inject-javadoc-url}/jakarta/inject/Singleton.html[singleton scope]. - -== Configuring the Helidon OCI SDK Extension - -By default the extension will select and configure an appropriate OCI Authentication Details Provider for you based - on your environment. - -For this reason it is recommended that you configure your environment first and get it working with the - link:{oci-javasdk-url}[OCI CLI] before using the Helidon OCI SDK Extension. - -For more information see xref:oci.adoc[Helidon OCI Extension]. - -== Using the Vault client - -Once you have injected OCI Vault objects you can use them as described in: - -* link:{oci-javasdk-vault-javadoc-base-url}/package-summary.html[OCI SDK Vault Javadocs] -* link:{oci-vault-url}[OCI Vault Overview] diff --git a/docs/se/vault.adoc b/docs/se/integrations/hcv.adoc similarity index 94% rename from docs/se/vault.adoc rename to docs/se/integrations/hcv.adoc index 5a913d6f80b..db7cd5aecc5 100644 --- a/docs/se/vault.adoc +++ b/docs/se/integrations/hcv.adoc @@ -16,60 +16,41 @@ /////////////////////////////////////////////////////////////////////////////// -= Vault -:description: Helidon Vault integration -:keywords: vault -:feature-name: Vault -:rootdir: {docdir}/.. += HashiCorp Vault +:description: Helidon HashiCorp Vault integration +:keywords: vault, hashicorp +:feature-name: HashiCorp Vault +:rootdir: {docdir}/../.. include::{rootdir}/includes/se.adoc[] -HashiCorp Vault is a commonly used Vault in many microservices. The APIs are REST-based and Helidon implements them using reactive client. - -Vault integration supports the following: - -* *Secret Engines*: Key/Value version 2, Key/Value version 1, Cubbyhole, PKI, Transit, Database -* *Authentication Methods*: Token, Kubernetes (k8s), AppRole -* *Other Sys Operations and Configurations* +== ToC -== Experimental +- <> +- <> +- <> +- <> +- <> +- <> -WARNING: Helidon Vault support is still experimental and not intended for production use. APIs and features have not yet been fully tested and are subject to change. - -== Sys Operations - -Each of these features is implemented as a separate module, with the Vault class binding them together. In Helidon MP, with injection, this binding is done automatically, and you can simply inject your favorite secret engine. - -In addition to these features, Vault itself can be authenticated as follows: - -* Token authentication - token is configured when connecting to Vault -* AppRole authentication - AppRole ID and secret ID are configured, integration exchanges these for a temporary token that is used to connect to Vault -* K8s authentication - the k8s JWT token is discovered on current node and used to obtain a temporary token that is used to connect to Vault +== Overview -== Extensibility +HashiCorp Vault is a commonly used Vault in many microservices. The APIs are REST-based and Helidon implements them using reactive client. -New secret engines and authentication methods can be implemented quite easily, as the integration is based on service providers (using ServiceLoader). This gives us (or you, as the users) the option to add new secret engines and/or authentication methods without adding a plethora of methods to the Vault class. +include::{rootdir}/includes/dependencies.adoc[] -See the following SPIs: -[source,properties] +[source,xml] ---- -io.helidon.integrations.vault.spi.AuthMethodProvider -io.helidon.integrations.vault.spi.SecretsEngineProvider -io.helidon.integrations.vault.spi.SysProvider -io.helidon.integrations.vault.spi.VaultAuth -io.helidon.integrations.vault.spi.InjectionProvider + + io.helidon.integrations.vault + helidon-integrations-vault + ---- -== Modules - The following is a list of maven coordinates of all Vault modules available: [source,xml] ---- - - io.helidon.integrations.vault - helidon-integrations-vault - io.helidon.integrations.vault.auths helidon-integrations-vault-auths-token @@ -108,19 +89,43 @@ The following is a list of maven coordinates of all Vault modules available: ---- -Configuration to connect to Vault. +== Usage + +Vault integration supports the following: + +* *Secret Engines*: Key/Value version 2, Key/Value version 1, Cubbyhole, PKI, Transit, Database +* *Authentication Methods*: Token, Kubernetes (k8s), AppRole +* *Other Sys Operations and Configurations* + +Each of these features is implemented as a separate module, with the Vault class binding them together. Code to set up Vault and obtain a specific secret engine: + +[source,java] +---- +Vault vault = Vault.builder() + .config(config.get("vault")) + .build(); +Kv2SecretsRx secrets = vault.secrets(Kv2SecretsRx.ENGINE); +---- + +Similar code can be used for any secret engine available: + +* Kv2SecretsRx - Key/Value Version 2 Secrets (versioned secrets, default) +* Kv1SecretsRx - Key/Value Version 1 Secrets (unversioned secrets, legacy) +* CubbyholeSecretsRx - Cubbyhole secrets (token bound secrets) +* DbSecretsRx - Database secrets (for generating temporary DB credentials) +* PkiSecretsRx - PKI secrets (for generating keys and X.509 certificates) +* TransitSecretsRx - Transit operations (encryption, signatures, HMAC) -. Authenticating using Token: -+ +In addition to these features, Vault itself can be authenticated as follows: + +* Token authentication - token is configured when connecting to Vault [source,yaml] ---- vault: address: "http://localhost:8200" token: "my-token" ---- -+ -. Authenticating using AppRole: -+ +* AppRole authentication - AppRole ID and secret ID are configured, integration exchanges these for a temporary token that is used to connect to Vault [source,yaml] ---- vault: @@ -129,9 +134,7 @@ vault: role-id: "app-role-id" secret-id: app-role-secret-id ---- -+ -. Authenticating using Kubernetes: -+ +* K8s authentication - the k8s JWT token is discovered on current node and used to obtain a temporary token that is used to connect to Vault [source,yaml] ---- vault: @@ -142,53 +145,32 @@ vault: <1> The token role must be configured in Vault Minimal configuration to connect to Vault: -[source,yaml] ----- -vault: - token: "my-token" - address: "http://localhost:8200" ----- - -Code to set up Vault and obtain a specific secret engine: +Code to get the Sys operations of Vault: [source,java] ---- -Vault vault = Vault.builder() - .config(config.get("vault")) - .build(); -Kv2SecretsRx secrets = vault.secrets(Kv2SecretsRx.ENGINE); +SysRx sys = vault.sys(SysRx.API); ---- -Similar code can be used for any secret engine available: +=== Extensibility -* Kv2SecretsRx - Key/Value Version 2 Secrets (versioned secrets, default) -* Kv1SecretsRx - Key/Value Version 1 Secrets (unversioned secrets, legacy) -* CubbyholeSecretsRx - Cubbyhole secrets (token bound secrets) -* DbSecretsRx - Database secrets (for generating temporary DB credentials) -* PkiSecretsRx - PKI secrets (for generating keys and X.509 certificates) -* TransitSecretsRx - Transit operations (encryption, signatures, HMAC) - -Code to obtain a specific authentication method: +New secret engines and authentication methods can be implemented quite easily, as the integration is based on service providers (using ServiceLoader). This gives us (or you, as the users) the option to add new secret engines and/or authentication methods without adding a plethora of methods to the Vault class. -[source,java] +See the following SPIs: +[source,properties] ---- -K8sAuthRx auth = vault.auth(K8sAuthRx.AUTH_METHOD) +io.helidon.integrations.vault.spi.AuthMethodProvider +io.helidon.integrations.vault.spi.SecretsEngineProvider +io.helidon.integrations.vault.spi.SysProvider +io.helidon.integrations.vault.spi.VaultAuth +io.helidon.integrations.vault.spi.InjectionProvider ---- -Similar code can be used for any authentication method available: - -* AppRoleAuthRx - AppRole authentication method (management operations) -* K8sAuthRx - Kubernetes authentication method (management operations) -* TokenAuthRx - Token authentication method (management operations) - -Code to get the Sys operations of Vault: +== Examples -[source,java] ----- -SysRx sys = vault.sys(SysRx.API); ----- +The following example shows usage of Vault to encrypt a secret. -== Usage with WebServer +=== Usage with WebServer Configure the `Vault` object using token base configuration: @@ -580,7 +562,7 @@ class K8sExample { <3> Disable Kubernetes authentication if needed. <4> Function used to enable Kubernetes authentication. -== Local testing +== Local testing [[Local-Testing]] Vault is available as a docker image, so to test locally, you can simply: @@ -590,3 +572,7 @@ docker run -e VAULT_DEV_ROOT_TOKEN_ID=my-token -d --name=vault -p8200:8200 vault ---- This will create a Vault docker image, run it in background and open it on localhost:8200 with a custom root token my-token, using name vault. This is of course only suitable for local testing, as the root token has too many rights, but it can be easily used with the examples below. + +== References + +* link:{helidon-github-tree-url}/examples/integrations/vault[Hashicorp Vault Usage Examples] \ No newline at end of file diff --git a/docs/se/integrations/oci.adoc b/docs/se/integrations/oci.adoc new file mode 100644 index 00000000000..87d67c3fe9d --- /dev/null +++ b/docs/se/integrations/oci.adoc @@ -0,0 +1,114 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2021, 2022 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. + +/////////////////////////////////////////////////////////////////////////////// + += Oracle Cloud Infrastructure Integration +:description: Helidon OCI Integration +:keywords: oci +:feature-name: OCI Integration +:rootdir: {docdir}/../.. + +include::{rootdir}/includes/se.adoc[] + +== ToC + +- <> +- <> +- <> +- <> + +== Overview + +Helidon SE OCI Integration provides easy access to Oracle Cloud Infrastructure using the OCI Java SDK. + +NOTE: OCI SDK uses JAX-RS Client 2.1.6 (javax package names), which makes it incompatible with Helidon 3 applications and any application that uses JAX-RS 3 (jakarta package naming). Please see our link:{rootdir}/includes/oci.adoc[Guide] for detailed information on how to work around this issue. + +== Usage + +It is recommended that you use the OCI Java SDK directly, in particular the Async clients. All you need to do is configure and create an OCI SDK Client object. The configuration primarily +consists of setting up authenticate with OCI. + +=== Configuring the OCI SDK Client + +Authentication with OCI is abstracted through `AuthenticationDetailsProvider`. + +If your environment is already set up to work with the OCI SDK or +the OCI command line, then it is very likely you do not need to do any additional +configuration. It is recommended that you do this first, and verify your configuration +by using the link:{oci-javasdk-url}[OCI CLI] to access the service. + +[source,java] +---- +ConfigFile config += ConfigFileReader.parse("~/.oci/config", "DEFAULT"); +AuthenticationDetailsProvider authProvider = new ConfigFileAuthenticationDetailsProvider(config); +---- + +You also need to add the following dependency to your application for this + +[source,xml] +---- + + com.oracle.oci.sdk + oci-java-sdk-common + +---- + +=== Accessing OCI Services + +Once you have authentication with OCI configured, you can use it to access any OCI service +supported by the OCI SDK. You will need to add dependencies for the specific +ODI SDK clients you will use. + +== Examples + +This example describes how to access OCI Object Storage. + +As mentioned above in xref:#_accessing_oci_services[], you need to add a dependency on the OCI SDK +Object Storage API: + +[source,xml] +---- + + com.oracle.oci.sdk + oci-java-sdk-objectstorage + +---- + +=== Creating an Object Storage Client + +Now you can create OCI SDK Clients. + +[source,java] +---- +ConfigFile config += ConfigFileReader.parse("~/.oci/config", "DEFAULT"); +AuthenticationDetailsProvider authProvider = new ConfigFileAuthenticationDetailsProvider(config); +ObjectStorageAsync objectStorageAsyncClient = new ObjectStorageAsyncClient(authProvider); +---- + +=== Using the Object Storage client + +Once you have created an ObjectStorage client you can use it as described in: + +* link:{oci-javasdk-objstore-javadoc-base-url}/package-summary.html[OCI SDK Object Storage Javadocs] +* link:{oci-objstore-url}[OCI Object Storage Overview] + +== References + +* link:{helidon-github-tree-url}/examples/integrations/oci[OCI SDK Usage Examples] +* link:https://docs.oracle.com/en-us/iaas/Content/home.htm[OCI Documentation] \ No newline at end of file diff --git a/docs/se/oci/atp.adoc b/docs/se/oci/atp.adoc deleted file mode 100644 index 50725711e20..00000000000 --- a/docs/se/oci/atp.adoc +++ /dev/null @@ -1,129 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2021, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= OCI Autonomous Transaction Processing -:description: Helidon OCI Autonomous Transaction Processing integration -:keywords: oci, atp -:feature-name: OCI Autonomous Transaction Processing -:rootdir: {docdir}/../.. - -include::{rootdir}/includes/se.adoc[] - -The Helidon SE OCI Autonomous Transaction Processing integration provides a reactive API to ATP database in Oracle cloud. - -== Deprecated - -The custom Helidon SE OCI clients documented here are deprecated. It is recommended that you -use the OCI Java SDK directly, in particular the Async clients. For more information see: - -* link:{oci-database-url}[OCI Database Documentation ] -* link:{oci-javasdk-database-javadoc-base-url}/package-summary.html[OCI Database Javadoc ] -* link:{helidon-github-tree-url}/examples/integrations/oci/atp-reactive/[Helidon SE OCI ATP Example] - -== Experimental - -Helidon integration with Oracle Cloud Infrastructure is still experimental and not intended for production use. - APIs and features have not yet been fully tested and are subject to change. - -include::{rootdir}/includes/dependencies.adoc[] - -[source,xml] ----- - - io.helidon.integrations.oci - helidon-integrations-oci-atp - ----- - -== Setting up the Autonomous Transaction Processing - -In order to use the OCI Autonomous Transaction Processing integration, the following setup should be made: - -[source,java] ----- -Config ociConfig = config.get("oci"); -OciAutonomousDbRx ociAutonomousDb = OciAutonomousDbRx.create(ociConfig); ----- - -Current configuration requires `~/.oci/config` to be available in the home folder. This configuration file can be - downloaded from OCI. - -`Routing` should be added to the `WebServer`, in our case pointing to `/atp`: - -[source,java] ----- -WebServer.builder() - .config(config.get("server")) - .routing(Routing.builder() - .register("/atp", new AtpService(autonomousDbRx, config))) - .build(); ----- - -Additionally, in `application.yaml` OCI properties should be specified: - -[source,yaml] ----- -oci: - atp: - ocid: "" - walletPassword: "" ----- - -The exact values are available from OCI console. - -image::oci/atpocid.png[OCI ATP, align="center"] - -== Using the Autonomous Transaction Processing - -In the Service we must specify the mapping for operations with the database and their handlers: - -[source,java] ----- -@Override -public void update(Routing.Rules rules) { - rules.get("/wallet", this::generateWallet); -} ----- - -=== Generate Wallet - -To generate wallet file for OCI Autonomous Transaction Processing: - -[source,java] ----- -private void generateWallet(ServerRequest req, ServerResponse res) { - autonomousDbRx.generateWallet(GenerateAutonomousDatabaseWallet.Request.builder()) <1> - .flatMapOptional(ApiOptionalResponse::entity) - .map(GenerateAutonomousDatabaseWallet.Response::walletArchive) <2> - .ifEmpty(() -> LOGGER.severe("Unable to obtain wallet!")) - .flatMapSingle(this::createDbClient) <3> - .flatMap(dbClient -> dbClient.execute(exec -> exec.query("SELECT 'Hello world!!' FROM DUAL"))) - .first() - .map(dbRow -> dbRow.column(1).as(String.class)) <4> - .ifEmpty(() -> res.status(404).send()) - .onError(res::send) - .forSingle(res::send); -} ----- -<1> Create the `Request` using `GenerateAutonomousDatabaseWallet.Request.builder()` -<2> Retrieve 'walletArchive' from the response. -<3> Create DBClient using info from 'walletArchive' -<4> Read the first column from first row of result. - -For complete code, about how to create DBClient using wallet info, please see - link:{helidon-github-tree-url}/examples/integrations/oci/atp-reactive[ATP Reactive Example] diff --git a/docs/se/oci/object-storage.adoc b/docs/se/oci/object-storage.adoc deleted file mode 100644 index 7082cf5d029..00000000000 --- a/docs/se/oci/object-storage.adoc +++ /dev/null @@ -1,258 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2021, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= OCI Object Storage -:description: Helidon OCI Object Storage integration -:keywords: oci, objectstorage -:feature-name: OCI Object Storage -:rootdir: {docdir}/../.. - -include::{rootdir}/includes/se.adoc[] - -The Helidon SE OCI Object Storage integration provides a reactive API to files stored in Oracle cloud. - -== Deprecated - -The custom Helidon SE OCI clients documented here are deprecated. It is recommended that you -use the OCI Java SDK directly, in particular the Async clients. For more information see: - -* link:{oci-objstore-url}[OCI Object Storage Documentation ] -* link:{oci-javasdk-objstore-javadoc-base-url}/package-summary.html[OCI Object Storage Javadoc ] -* link:{helidon-github-tree-url}/examples/integrations/oci/objectstorage-reactive/[Helidon SE OCI Object Storage Example] - -== Experimental - -Helidon integration with Oracle Cloud Infrastructure is still experimental and not intended for production use. APIs and features have not yet been fully tested and are subject to change. - -include::{rootdir}/includes/dependencies.adoc[] - -[source,xml] ----- - - io.helidon.integrations.oci - helidon-integrations-oci-objectstorage - ----- - -== Setting up the Object Storage - -In order to use the OCI Object Storage integration, the following setup should be made: - -[source,java] ----- -Config ociConfig = config.get("oci"); -OciObjectStorageRx ociObjectStorage = OciObjectStorageRx.create(ociConfig); ----- - -Current configuration requires `~/.oci/config` to be available in the home folder. - This configuration file can be downloaded from OCI. - -`Routing` should be added to the `WebServer`, in our case pointing to `/file`: - -[source,java] ----- -String bucketName = ociConfig.get("objectstorage").get("bucket").asString().get(); - -WebServer.builder() - .config(config.get("server")) - .routing(Routing.builder() - .register("/files", new ObjectStorageService(ociObjectStorage, bucketName))) - .build() - .start() - .await() ----- - -Additionally, in `application.yaml` OCI properties should be specified: - -[source,yaml] ----- -oci: - properties: - compartment-ocid: "ocid<1>tenancy.oc<1>.<..>" - objectstorage-namespace: "<...>" - objectstorage-bucket: "<...>" ----- - -The exact values are available in OCI object storage and bucket properties. - -image::oci/ocibucket.png[OCI Bucket, align="center"] - -== Using the Object Storage - -In the Service we must specify the mapping for CRUD operations with the files and their handlers: - -[source,java] ----- -@Override -public void update(Routing.Rules rules) { - rules.get("/file/{file-name}", this::download) - .post("/file/{file-name}", this::upload) - .delete("/file/{file-name}", this::delete) - .get("/rename/{old-name}/{new-name}", this::rename); -} ----- - -=== Upload file - -To upload a file to OCI Object Storage using the `PUT` method: - -[source,java] ----- -private void upload(ServerRequest req, ServerResponse res) { - OptionalLong contentLength = req.headers().contentLength(); - if (contentLength.isEmpty()) { - req.content().forEach(DataChunk::release); - res.status(Http.Status.BAD_REQUEST_400).send("Content length must be defined"); - return; - } - - String objectName = req.path().param("file-name"); - - PutObject.Request request = PutObject.Request.builder() // <1> - .objectName(objectName) - .bucket(bucketName) - .contentLength(contentLength.getAsLong()); - - req.headers().contentType().ifPresent(request::requestMediaType); // <2> - - objectStorage.putObject(request, - req.content()) - .forSingle(response -> res.send(response.requestId())) // <3> - .exceptionally(res::send); -} ----- -<1> Create the `Request` using `PutObject.Request.builder()` -<2> Define `MediaType` -<3> Execute the request to OCI in asynchronous way and put the result in `response` object - -=== Download file - -To download a file from OCI Object Storage using the `GET` method: - -[source,java] ----- -private void download(ServerRequest req, ServerResponse res) { - String objectName = req.path().param("file-name"); - - objectStorage.getObject(GetObject.Request.builder() - .bucket(bucketName) - .objectName(objectName)) // <1> - .forSingle(apiResponse -> { - Optional entity = apiResponse.entity(); // <2> - if (entity.isEmpty()) { - res.status(Http.Status.NOT_FOUND_404).send(); // <3> - } else { - GetObjectRx.Response response = entity.get(); - // copy the content length header to response - apiResponse.headers() - .first(Http.Header.CONTENT_LENGTH) - .ifPresent(res.headers()::add); - res.send(response.publisher()); // <4> - } - }) - .exceptionally(res::send); -} ----- -<1> Use `getObject` function to make asynchronous request to OCI Object Storage -<2> The result is of type `Optional` -<3> Whenever the result is empty, return status `404` -<4> Get the response, set headers and return the result as a `Publisher` - -=== Rename file - -To rename an existing file in the OCI bucket, submit a `GET` method with two parameters: - -[source,java] ----- -private void rename(ServerRequest req, ServerResponse res) { - String oldName = req.path().param("old-name"); - String newName = req.path().param("new-name"); - - objectStorage.renameObject(RenameObject.Request.builder() - .bucket(bucketName) - .objectName(oldName) - .newObjectName(newName)) // <1> - .forSingle(it -> res.send("Renamed to " + newName)) // <2> - .exceptionally(res::send); -} ----- -<1> Use `renameObject` function and configure a `RenameObject.Request.builder()` to submit the rename request -<2> The request is made in asynchronous way; a `Single` is returned - - -=== Delete file - -Finally, to delete a file, `DELETE` request should be used: - -[source,java] ----- -private void delete(ServerRequest req, ServerResponse res) { - String objectName = req.path().param("file-name"); - - objectStorage.deleteObject(DeleteObject.Request.builder() - .bucket(bucketName) - .objectName(objectName)) // <1> - .forSingle(response -> res.status(response.status()).send()) // <2> - .exceptionally(res::send); -} ----- -<1> Use `deleteObject` function and configure a `DeleteObject.Request.builder()` to submit the delete request -<2> The request is made in asynchronous way; a `Single` is returned - -== Object Storage Health Check - -If your Helidon application depends on Object Storage accessibility, you may consider setting -up a health check to verify connectivity with an OCI bucket. To do so, first add the following -dependency in your pom file: - -[source,xml] ----- - - io.helidon.integrations.oci - helidon-integrations-oci-objectstorage-health - ----- - -In order to register the new health check in Helidon SE, create an instance of `HealthSupport` -and configure it as shown next: - -[source,java] ----- -HealthSupport health = HealthSupport.builder() - .addLiveness(OciObjectStorageHealthCheck.builder() - .ociObjectStorage(ociObjectStorage) - .bucket(bucketName) - .namespace(namespace) - .build()) - .build(); ----- - -where `ociObjectStorage`, `bucketName` and `namespace` are as required for any other -Object Storage access. Finally, include your newly created `HealthSupport` object -as part of your application's routing: - -[source,java] ----- -Routing routing = Routing.builder() - .register(health) - // other routes here - .build(); ----- - -When executed, this health check will _ping_ the bucket to make sure it is accessible in your -environment. For more information about health checks see xref:../health.adoc[Health Checks]. diff --git a/docs/se/oci/oci.adoc b/docs/se/oci/oci.adoc deleted file mode 100644 index 139258e8f26..00000000000 --- a/docs/se/oci/oci.adoc +++ /dev/null @@ -1,84 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2021, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= Oracle Cloud Infrastructure Integration -:description: Helidon OCI Integration -:keywords: oci -:feature-name: OCI Integration -:rootdir: {docdir}/../.. - -include::{rootdir}/includes/se.adoc[] - -Helidon SE OCI Integration provides easy access to Oracle Cloud Infrastructure. - -== Deprecated - -The custom Helidon SE OCI clients documented here are deprecated. -It is recommended that you use the OCI Java SDK directly, in particular the Async clients. -For more information see: - -* link:https://docs.oracle.com/en-us/iaas/Content/home.htm[OCI Documentation ] -* link:{helidon-tag}/examples/integrations/oci/atp-reactive/[Helidon SE OCI ATP Example] -* link:{helidon-tag}/examples/integrations/oci/objectstorage-reactive/[Helidon SE OCI Object Storage Example] -* link:{helidon-tag}/examples/integrations/oci/metrics-reactive/[Helidon SE OCI Metrics Example] -* link:{helidon-github-tree-url}/examples/integrations/oci/vault-reactive/[Helidon SE OCI Vault Example] - -== Experimental - -Helidon integration with Oracle Cloud Infrastructure is still experimental and not intended for production use. - APIs and features have not yet been fully tested and are subject to change. - -== General Configuration - -NOTE: If you follow these instructions on how to -https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#two[Generate an API Signing Key], -be advised that Helidon does not currently support passphrase-protected private keys in PKCS#1 format. -If generating a private key using those instructions, use the _no passphrase_ option. - -=== Using Helidon SE Properties Configuration - -The first option to configure connection to OCI is to directly specify properties in `application.yaml` file: - -[source,yaml] ----- -oci: - config: - oci-profile: - user: ocid1.user.... - fingerprint: 1c:6c:.... - tenancy: ocid1.tenancy.oc1.. - region: us-... - key-pem: ----- - -=== Using OCI Configuration - -The second option is via OCI configuration file. -For authentication in OCI a special configuration file should be set up. The file is usually located at `~/.oci/config` - -[source,listing] ----- -[DEFAULT] -user=ocid1.user.... -fingerprint=1c:6c:.... -tenancy=ocid1.tenancy.oc1.. -region=us-... -key_file= ----- - -More information how to set up on your environment: link:{oci-sdk-config-url}[Official website] diff --git a/docs/se/oci/vault.adoc b/docs/se/oci/vault.adoc deleted file mode 100644 index a3953fda19c..00000000000 --- a/docs/se/oci/vault.adoc +++ /dev/null @@ -1,260 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2021, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= OCI Vault -:description: Helidon OCI Vault integration -:keywords: oci, vault -:feature-name: OCI Vault -:rootdir: {docdir}/../.. - -include::{rootdir}/includes/se.adoc[] - -The Helidon SE OCI Vault integration provides a reactive API for the Oracle Cloud Vault service. - -== Deprecated - -The custom Helidon SE OCI clients documented here are deprecated. It is recommended that you -use the OCI Java SDK directly, in particular the Async clients. For more information see: - -* link:{oci-vault-url}[OCI Vault Storage Documentation ] -* link:{oci-javasdk-vault-javadoc-base-url}/package-summary.html[OCI Vault Storage Javadoc ] -* link:{helidon-github-tree-url}/examples/integrations/oci/vault-reactive/[Helidon SE OCI Vault Example] - -== Experimental - -Helidon integration with Oracle Cloud Infrastructure is still experimental and not intended for production use. -APIs and features have not yet been fully tested and are subject to change. - -include::{rootdir}/includes/dependencies.adoc[] - -[source,xml] ----- - - io.helidon.integrations.oci - helidon-integrations-oci-vault - ----- - - -== Setting up the OCI Vault - -In order to use the OCI Vault integration, the following setup should be made. - -* The configuration required for Vault integration includes: -* Vault OCID - to use the correct Vault, as more than one can be configured -* Compartment OCID - OCI-specific compartment -* Encryption Key OCID - required when doing encryption/decryption -* Signature Key OCID - required when doing signatures/verification -* Cryptographic endpoint - required for all except secrets - -First specify OCIDs and URLs of Vault items in `application.yaml`: - -[source,yaml] ----- -oci: - vault: - vault-ocid: "<...>" - compartment-ocid: "<...>" - encryption-key-ocid: "<...>" - signature-key-ocid: "<...>" - cryptographic-endpoint: "<...>" ----- -Current configuration requires `~/.oci/config` to be available in the home folder. -This configuration file can be downloaded from OCI. - -The OCIDs can be set up and found in OCI under Security tab. - -image::oci/vaultkey.png[OCI Vault, align="center"] - -Next, these values should be read and provided to `VaultService`: - -[source,java] ----- -Config vaultConfig = config.get("oci.vault"); -// the following three parameters are required -String vaultOcid = vaultConfig.get("vault-ocid").asString().get(); -String compartmentOcid = vaultConfig.get("compartment-ocid").asString().get(); -String encryptionKey = vaultConfig.get("encryption-key-ocid").asString().get(); -String signatureKey = vaultConfig.get("signature-key-ocid").asString().get(); - -// this requires OCI configuration in the usual place -// ~/.oci/config -OciVaultRx ociVault = OciVaultRx.create(config.get("oci")); - -WebServer.builder() - .config(config.get("server")) - .routing(Routing.builder() - .register("/vault", new VaultService(ociVault, - vaultOcid, - compartmentOcid, - encryptionKey, - signatureKey))) - .build() - .start() - .await(); ----- - -The `VaultService` should define an `update` method to map paths to handler methods: - -[source,java] ----- -@Override -public void update(Routing.Rules rules) { - rules.get("/encrypt/{text:.*}", this::encrypt) - .get("/decrypt/{text:.*}", this::decrypt) - .get("/sign/{text}", this::sign) - .get("/verify/{text}/{signature:.*}", this::verify) - .get("/secret/{id}", this::getSecret) - .post("/secret/{name}", Handler.create(String.class, this::createSecret)) - .delete("/secret/{id}", this::deleteSecret); -} ----- - -== OCI Vault usage - -=== Encryption - -To encrypt a text, submit a `GET` request to the `/encrypt` endpoint: - -[source,java] ----- -private void encrypt(ServerRequest req, ServerResponse res) { - vault.encrypt(Encrypt.Request.builder() - .keyId(encryptionKeyOcid) - .data(Base64Value.create(req.path().param("text")))) - .map(Encrypt.Response::cipherText) - .forSingle(res::send) - .exceptionally(res::send); -} ----- - -=== Decryption - -To decrypt a text, submit a `GET` request to `/decrypt` endpoint: - -[source,java] ----- -private void decrypt(ServerRequest req, ServerResponse res) { - vault.decrypt(Decrypt.Request.builder() - .keyId(encryptionKeyOcid) - .cipherText(req.path().param("text"))) - .map(Decrypt.Response::decrypted) - .map(Base64Value::toDecodedString) - .forSingle(res::send) - .exceptionally(res::send); -} ----- - -=== Signature - -To retrieve a signature, submit a `GET` request to `/sign` endpoint: - -[source,java] ----- -private void sign(ServerRequest req, ServerResponse res) { - vault.sign(Sign.Request.builder() - .keyId(signatureKeyOcid) - .algorithm(Sign.Request.ALGORITHM_SHA_224_RSA_PKCS_PSS) - .message(Base64Value.create(req.path().param("text")))) - .map(Sign.Response::signature) - .map(Base64Value::toBase64) - .forSingle(res::send) - .exceptionally(res::send); -} ----- - -==== Verification of a Signature - -To verify the correctness of the signature, submit a `GET` request to `/verify` endpoint: - -[source,java] ----- -private void verify(ServerRequest req, ServerResponse res) { - String text = req.path().param("text"); - String signature = req.path().param("signature"); - - vault.verify(Verify.Request.builder() - .keyId(signatureKeyOcid) - .algorithm(Sign.Request.ALGORITHM_SHA_224_RSA_PKCS_PSS) - .message(Base64Value.create(text)) - .signature(Base64Value.createFromEncoded(signature))) - .map(Verify.Response::isValid) - .map(it -> it ? "Signature Valid" : "Signature Invalid") - .forSingle(res::send) - .exceptionally(res::send); -} ----- - -==== Creating a Signature - -To create a secret with a provided name, submit a `GET` request to `/secret`: - -[source,java] ----- -private void createSecret(ServerRequest req, ServerResponse res, String secretText) { - vault.createSecret(CreateSecret.Request.builder() - .secretContent(CreateSecret.SecretContent.create(secretText)) - .vaultId(vaultOcid) - .compartmentId(compartmentOcid) - .encryptionKeyId(encryptionKeyOcid) - .secretName(req.path().param("name"))) - .map(CreateSecret.Response::secret) - .map(Secret::id) - .forSingle(res::send) - .exceptionally(res::send); -} ----- - -==== Getting a Signature - -To get a secret by its OCID, submit a `GET` request to `/secret`: - -[source,java] ----- -private void getSecret(ServerRequest req, ServerResponse res) { - vault.getSecretBundle(GetSecretBundle.Request.create(req.path().param("id"))) - .forSingle(apiResponse -> { - Optional entity = apiResponse.entity(); - if (entity.isEmpty()) { - res.status(Http.Status.NOT_FOUND_404).send(); - } else { - GetSecretBundle.Response response = entity.get(); - res.send(response.secretString().orElse("")); - } - }) - .exceptionally(res::send); -} ----- - -==== Deleting a Signature - -To delete a secret, a `DELETE` request to `/secret` should be used: - -[source, java] ----- -private void deleteSecret(ServerRequest req, ServerResponse res) { - Instant deleteTime = Instant.now().plus(30, ChronoUnit.DAYS); - - vault.deleteSecret(DeleteSecret.Request.builder() - .secretId(req.path().param("id")) - .timeOfDeletion(deleteTime)) - .forSingle(it -> res.status(it.status()).send()) - .exceptionally(res::send); - -} ----- diff --git a/docs/sitegen.yaml b/docs/sitegen.yaml index 48fd3894b6b..567d1d9463c 100644 --- a/docs/sitegen.yaml +++ b/docs/sitegen.yaml @@ -180,16 +180,14 @@ backend: type: "icon" value: "donut_large" - type: "MENU" - title: "OCI" - dir: "oci" + title: "Integrations" + dir: "integrations" glyph: type: "icon" value: "filter_drama" sources: - "oci.adoc" - - "object-storage.adoc" - - "vault.adoc" - - "atp.adoc" + - "hcv.adoc" - type: "MENU" title: "Reactive Streams" dir: "reactivestreams" @@ -241,12 +239,6 @@ backend: glyph: type: "icon" value: "timeline" - - type: "PAGE" - title: "Vault" - source: "vault.adoc" - glyph: - type: "icon" - value: "lock" - type: "MENU" title: "Web Client" dir: "webclient" @@ -424,16 +416,14 @@ backend: type: "icon" value: "donut_large" - type: "MENU" - title: "OCI" - dir: "oci" + title: "Integrations" + dir: "integrations" glyph: type: "icon" value: "filter_drama" sources: - "oci.adoc" - - "object-storage.adoc" - - "vault.adoc" - - "atp.adoc" + - "hcv.adoc" - type: "MENU" title: "Reactive Streams" dir: "reactivestreams" @@ -483,12 +473,6 @@ backend: glyph: type: "icon" value: "timeline" - - type: "PAGE" - title: "Vault" - source: "vault.adoc" - glyph: - type: "icon" - value: "lock" - type: "PAGE" title: "Websocket" source: "websocket.adoc" diff --git a/examples/integrations/oci/README.md b/examples/integrations/oci/README.md new file mode 100644 index 00000000000..cfa76cf3d60 --- /dev/null +++ b/examples/integrations/oci/README.md @@ -0,0 +1,11 @@ +# OCI SDK setup for Examples Build + +OCI SDK uses JAX-RS Client 2.1.6 (javax package names), which makes it incompatible with Helidon 3 applications and any application that uses JAX-RS 3 (jakarta package naming). + +Please see our [Guide](https://github.com/oracle/helidon/tree/master/docs/includes/oci.adoc) for detailed information on how to work around this issue. + +Once you have this setup, you can build examples in this repository directory. + +Please make sure you supply -Poci-sdk-cdi to your mvn invocation. + +If you do not supply that profile, then the examples will not be built. \ No newline at end of file