├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md └── SECURITY.md /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this repository 2 | 3 | We welcome your contributions! There are multiple ways to contribute. 4 | 5 | ## Opening issues 6 | 7 | For bugs or enhancement requests, please file a GitHub issue unless it's 8 | security related. When filing a bug remember that the better written the bug is, 9 | the more likely it is to be fixed. If you think you've found a security 10 | vulnerability, do not raise a GitHub issue and follow the instructions in our 11 | [security policy](./SECURITY.md). 12 | 13 | ## Contributing code 14 | 15 | We welcome your code contributions. Before submitting code via a pull request, 16 | you will need to have signed the [Oracle Contributor Agreement][OCA] (OCA) and 17 | your commits need to include the following line using the name and e-mail 18 | address you used to sign the OCA: 19 | 20 | ```text 21 | Signed-off-by: Your Name 22 | ``` 23 | 24 | This can be automatically added to pull requests by committing with `--sign-off` 25 | or `-s`, e.g. 26 | 27 | ```text 28 | git commit --signoff 29 | ``` 30 | 31 | Only pull requests from committers that can be verified as having signed the OCA 32 | can be accepted. 33 | 34 | ## Pull request process 35 | 36 | 1. Ensure there is an issue created to track and discuss the fix or enhancement 37 | you intend to submit. 38 | 1. Fork this repository. 39 | 1. Create a branch in your fork to implement the changes. We recommend using 40 | the issue number as part of your branch name, e.g. `1234-fixes`. 41 | 1. Ensure that any documentation is updated with the changes that are required 42 | by your change. 43 | 1. Ensure that any samples are updated if the base image has been changed. 44 | 1. Submit the pull request. *Do not leave the pull request blank*. Explain exactly 45 | what your changes are meant to do and provide simple steps on how to validate. 46 | your changes. Ensure that you reference the issue you created as well. 47 | 1. We will assign the pull request to 2-3 people for review before it is merged. 48 | 49 | ## Code of conduct 50 | 51 | Follow the [Golden Rule](https://en.wikipedia.org/wiki/Golden_Rule). If you'd 52 | like more specific guidelines, see the [Contributor Covenant Code of Conduct][COC]. 53 | 54 | [OCA]: https://oca.opensource.oracle.com 55 | [COC]: https://www.contributor-covenant.org/version/1/4/code-of-conduct/ 56 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Oracle and/or its affiliates. 2 | 3 | The Universal Permissive License (UPL), Version 1.0 4 | 5 | Subject to the condition set forth below, permission is hereby granted to any 6 | person obtaining a copy of this software, associated documentation and/or data 7 | (collectively the "Software"), free of charge and under any and all copyright 8 | rights in the Software, and any and all patent rights owned or freely 9 | licensable by each licensor hereunder covering either (i) the unmodified 10 | Software as contributed to or provided by such licensor, or (ii) the Larger 11 | Works (as defined below), to deal in both 12 | 13 | (a) the Software, and 14 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 15 | one is included with the Software (each a "Larger Work" to which the Software 16 | is contributed by such licensors), 17 | 18 | without restriction, including without limitation the rights to copy, create 19 | derivative works of, display, perform, and distribute the Software and make, 20 | use, sell, offer for sale, import, export, have made, and have sold the 21 | Software and the Larger Work(s), and to sublicense the foregoing rights on 22 | either these or other terms. 23 | 24 | This license is subject to the following condition: 25 | The above copyright notice and either this complete permission notice or at 26 | a minimum a reference to the UPL must be included in all copies or 27 | substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 | SOFTWARE. 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Oracle Autonomous Database Free Container Image Documentation 2 | 3 | Oracle Autonomous Database Free Container image supports 2 types of database workload types; `ADW` and `ATP`. These are similar to Transaction Processing and Data Warehouse workload type databases in Autonomous Database Serverless Cloud service. 4 | 5 | Following key features are supported: 6 | 7 | - Oracle Rest Data Services (ORDS) 8 | - APEX 9 | - Database Actions 10 | - Mongo API 11 | - Oracle Estate Explorer (OEE) 12 | 13 | The storage size is limited to 20 GB for each Database 14 | 15 | ## Using this image 16 | 17 | ### Database versions 18 | 19 | From the [released images](https://github.com/oracle/adb-free/pkgs/container/adb-free), choose the database version and corresponding image to work with. 20 | 21 | We use the following naming convention: 22 | 23 | | Database version | Latest image tag | Specific release image tag | 24 | |------------------|------------------|----------------------------| 25 | | 23ai | latest-23ai | 24.11.4.2-23ai | 26 | | 19c | latest | 24.12.1.2 | 27 | 28 | ### Container CPU/memory requirements 29 | 30 | Oracle Autonomous Database Free container needs 4 CPUs and 8 GiB memory 31 | 32 | ### Install podman 33 | 34 | Please refer the official documentation to install podman on [Linux](https://podman.io/docs/installation#installing-on-linux), [Windows](https://podman.io/docs/installation#windows) or [Mac](https://podman.io/docs/installation#macos) 35 | 36 | 37 | ### Start podman machine on MacOS (x86_64) or Windows (x86_64) 38 | 39 | Containers need the Linux kernel. Run following commands to start a podman virtual machine 40 | 41 | ```bash 42 | podman machine init 43 | podman machine set --cpus 4 --memory 8192 44 | podman machine start 45 | ``` 46 | 47 | Refer the [FAQ](#faq) to configure virtual machine on ARM machine (M1/M2 chips) 48 | 49 | ### Starting an ADB Free container 50 | 51 | > Note: Although the instructions use `podman`, the image format is compliant with both Open Container Initiative (OCI) and Docker. 52 | > ADB container works seamlessly with both OCI and Docker container runtimes. You can also use `docker` to start the container. 53 | 54 | To start an Oracle Autonomous Database Free container for **ATP** workload, run the following command 55 | 56 | ```bash 57 | podman run -d \ 58 | -p 1521:1522 \ 59 | -p 1522:1522 \ 60 | -p 8443:8443 \ 61 | -p 27017:27017 \ 62 | -e WORKLOAD_TYPE=ATP \ 63 | -e WALLET_PASSWORD=*** \ 64 | -e ADMIN_PASSWORD=*** \ 65 | --cap-add SYS_ADMIN \ 66 | --device /dev/fuse \ 67 | --name adb-free \ 68 | ghcr.io/oracle/adb-free:latest-23ai 69 | ``` 70 | 71 | > Note: Use `ghcr.io/oracle/adb-free:latest` for 19c 72 | 73 | #### On first startup of the container: 74 | 75 | - User mandatorily has to change the admin passwords. Please specify the password using the environment variable 76 | `ADMIN_PASSWORD` 77 | 78 | - Wallet is generated using the wallet password `WALLET_PASSWORD` 79 | 80 | 81 | Following table explains the environment variables passed to the container 82 | 83 | | Environment variable | Description | 84 | |----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 85 | | WORKLOAD_TYPE | Can be either `ATP` or `ADW`. Default value is `ATP` | 86 | | DATABASE_NAME | Database name should contain only alphanumeric characters. if not provided, the Database will be called either `MYATP` or `MYADW` depending on the passed workload type | 87 | | ADMIN_PASSWORD | Admin user password must be between 12 and 30 characters long and must include at least one uppercase letter, one lowercase letter, and one numeric. The password cannot contain username | 88 | | WALLET_PASSWORD | Wallet password must have a minimum length of eight characters and contain alphabetic characters combined with numbers or special characters. | 89 | | ENABLE_ARCHIVE_LOG | To enable archive logging in the database. Default value is True. To turn off archive logging set the value to False | 90 | 91 | 92 | > **_Note_**: For OFS mount, container should start with `SYS_ADMIN` capability. Also, virtual device `/dev/fuse` should be accessible 93 | 94 | #### Ports 95 | 96 | Note the following ports which are forwarded to the container process 97 | 98 | | Port | Description | 99 | |------|--------------------------------------| 100 | | 1521 | TLS | 101 | | 1522 | mTLS | 102 | | 8443 | HTTPS port for ORDS / APEX and Database Actions | 103 | | 27017 | Mongo API | 104 | 105 | #### HTTP proxy 106 | If you are behind a corporate proxy, there are 2 ways to configure the database 107 | to use the proxy settings 108 | 109 | 1. Set the `HTTP_PROXY` database property. This is used by packages like `DBMS_CLOUD` 110 | 111 | ```sql 112 | exec DBMS_CLOUD_CONTAINER_ADMIN.set_database_property('HTTP_PROXY', 'www-my-corp-proxy.com:80/'); 113 | ``` 114 | 115 | 2. Use `UTL_HTTP.set_proxy` to set proxy for HTTP requests sent using UTL_HTTP 116 | 117 | ```sql 118 | exec UTL_HTTP.SET_PROXY('www-my-corp-proxy.com'); 119 | ``` 120 | 121 | 122 | ### adb-cli 123 | 124 | `adb-cli` can be used to perform database operations after container is up and running 125 | 126 | To use adb-cli, you can define the following alias for convenience 127 | ```bash 128 | alias adb-cli="podman exec adb-cli" 129 | ``` 130 | 131 | #### Available commands 132 | 133 | ```bash 134 | >> adb-cli --help 135 | 136 | Usage: adb-cli [OPTIONS] COMMAND [ARGS]... 137 | 138 | ADB-S Command Line Interface (CLI) to perform container-runtime database 139 | operations 140 | 141 | Options: 142 | -v, --version Show the version and exit. 143 | --help Show this message and exit. 144 | 145 | Commands: 146 | add-database 147 | change-password 148 | ``` 149 | 150 | #### Add Database 151 | 152 | You can add a database using the `add-database` command 153 | 154 | ```bash 155 | adb-cli add-database --workload-type "ADW" --admin-password "Welcome_1234" 156 | ``` 157 | 158 | #### Change Password 159 | 160 | To change password for Admin user, use the following command 161 | 162 | ```bash 163 | adb-cli change-password --database-name "MYADW" --old-password "Welcome_1234" --new-password "Welcome_12345" 164 | ``` 165 | 166 | 167 | ### Migrating data across containers 168 | 169 | #### Mount Volume 170 | To persist data across container restarts and removals, you should mount a volume at `/u01/data` and follow the steps mentioned in the [documentation to migrate PDB data across containers](https://docs.oracle.com/en-us/iaas/autonomous-database-serverless/doc/autonomous-docker-container.html#GUID-03B5601E-E15B-4ECC-9929-D06ACF576857) 171 | 172 | ```bash 173 | podman run -d \ 174 | -p 1521:1522 \ 175 | -p 1522:1522 \ 176 | -p 8443:8443 \ 177 | -p 27017:27017 \ 178 | -e WORKLOAD_TYPE=ATP \ 179 | -e WALLET_PASSWORD=*** \ 180 | -e ADMIN_PASSWORD=*** \ 181 | --cap-add SYS_ADMIN \ 182 | --device /dev/fuse \ 183 | --name adb-free \ 184 | --volume adb_container_volume:/u01/data \ 185 | ghcr.io/oracle/adb-free:latest-23ai 186 | ``` 187 | 188 | 189 | ### Connecting to Oracle Autonomous Database Free container 190 | 191 | #### ORDS/APEX/Database Actions 192 | 193 | Container hostname is used to generate self-signed SSL certs to serve HTTPS traffic on port 8443. APEX and Database Actions can be accessed using the container host (or simply localhost) 194 | 195 | | Application | URL | 196 | |------------------|------------------------------------------------------------------------------| 197 | | APEX | https://localhost:8443/ords/apex | 198 | | Database Actions | https://localhost:8443/ords/sql-developer | 199 | 200 | > **_Note:_** For additional databases plugged in using `adb-cli add-database` command, please use the URL formats `https://localhost:8443/ords/{database_name}/apex` and `https://localhost:8443/ords/{database_name}/sql-developer` to access APEX and Database Actions respectively. 201 | 202 | #### Wallet Setup 203 | 204 | In the container, TLS wallet is generated at location `/u01/app/oracle/wallets/tls_wallet` 205 | 206 | Copy wallet to your host. 207 | 208 | ```bash 209 | podman cp adb-free:/u01/app/oracle/wallets/tls_wallet /scratch/tls_wallet 210 | ``` 211 | In this example, wallet is copied to `/scratch/tls_wallet` folder 212 | 213 | Point `TNS_ADMIN` environment variable to the wallet directory 214 | ```bash 215 | export TNS_ADMIN=/scratch/tls_wallet 216 | ``` 217 | 218 | If you want to connect to a remote host where the ADB free container is running, replace `localhost` in `$TNS_ADMIN/tnsnames.ora` with the remote host FQDN 219 | 220 | ```bash 221 | sed -i 's/localhost/my.host.com/g' $TNS_ADMIN/tnsnames.ora 222 | ``` 223 | 224 | #### Available TNS aliases 225 | 226 | Similar to Autonomous Database Serverless Cloud service, use any one of the following aliases to connect to ADB free container. 227 | 228 | ##### MYATP TNS aliases 229 | 230 | For mTLS use the following 231 | - myatp_medium 232 | - myatp_high 233 | - myatp_low 234 | - myatp_tp 235 | - myatp_tpurgent 236 | 237 | For TLS use the following 238 | 239 | - myatp_medium_tls 240 | - myatp_high_tls 241 | - myatp_low_tls 242 | - myatp_tp_tls 243 | - myatp_tpurgent_tls 244 | 245 | ##### MYADW TNS aliases 246 | 247 | For mTLS use the following 248 | - myadw_medium 249 | - myadw_high 250 | - myadw_low 251 | 252 | For TLS use the following 253 | - myadw_medium_tls 254 | - myadw_high_tls 255 | - myadw_low_tls 256 | 257 | TNS alias mappings to their connect string can be found in` $TNS_ADMIN/tnsnames.ora` file. 258 | 259 | #### TLS walletless connection 260 | 261 | To connect without a wallet, you need to update your client's truststore with the self-signed certificate generated at container start 262 | 263 | ##### Linux system truststore 264 | 265 | Copy `/u01/app/oracle/wallets/tls_wallet/adb_container.cert` from container and update your system truststore 266 | 267 | ```bash 268 | podman cp adb-free:/u01/app/oracle/wallets/tls_wallet/adb_container.cert adb_container.cert 269 | sudo cp adb_container.cert /etc/pki/ca-trust/source/anchors 270 | sudo update-ca-trust 271 | ``` 272 | 273 | ##### MacOS system trustsore 274 | 275 | For MacOS, please refer the [support guide](https://support.apple.com/guide/keychain-access/add-certificates-to-a-keychain-kyca2431/mac) to add certificate to keychain 276 | 277 | ##### JDK truststore 278 | 279 | For JDK truststore update, you can use `keytool` 280 | 281 | Linux example: 282 | 283 | ```bash 284 | sudo keytool -import -alias adb_container_certificate -keystore $JAVA_HOME/lib/security/cacerts -file adb_container.cert 285 | ``` 286 | 287 | MacOS example: 288 | ```bash 289 | sudo keytool -import -alias adb_container_certificate -file adb_container.cert -keystore /Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home/lib/security/cacerts 290 | ``` 291 | 292 | #### SQL Developer Desktop application 293 | 294 | Copy the wallet from the container and zip it 295 | 296 | ```bash 297 | podman cp adb-free:/u01/app/oracle/wallets/tls_wallet /scratch/tls_wallet 298 | 299 | zip -j /scratch/tls_wallet.zip /scratch/tls_wallet/* 300 | 301 | ``` 302 | 303 | Once you zip the Wallet, open SQLDeveloper and follow the below steps: 304 | 305 | 1. Click on File -> New -> Database Connection 306 | 307 | 2. Enter username / password 308 | 309 | 3. From "Connection Type" dropdown choose "Cloud Wallet" 310 | 311 | 4. Under "Configuration file" browse path to your wallet.zip 312 | 313 | 5. Select Service from the dropdown 314 | 315 | 6. Click on Connect 316 | 317 | 318 | 319 | #### SQL*Plus 320 | 321 | In this example, we connect using the alias `myatp_low` 322 | ```text 323 | sqlplus admin/@myatp_low 324 | 325 | SQL*Plus: Release 21.0.0.0.0 - Production on Wed Jul 26 22:38:27 2023 326 | Version 21.9.0.0.0 327 | 328 | Copyright (c) 1982, 2022, Oracle. All rights reserved. 329 | 330 | Last Successful login time: Wed Jul 26 2023 16:36:16 +00:00 331 | 332 | Connected to: 333 | Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production 334 | Version 19.20.0.1.0 335 | 336 | SQL> 337 | ``` 338 | 339 | #### Python 340 | 341 | Install the python-oracledb driver for Oracle Database 342 | ```bash 343 | python3 -m pip install oracledb 344 | ``` 345 | 346 | ```python 347 | import oracledb 348 | conn = oracledb.connect(user="admin", password="", dsn="myadw_medium", config_dir="/scratch/tls_wallet", wallet_location="/scratch/tls_wallet", wallet_password="***") 349 | cr = conn.cursor() 350 | r = cr.execute("SELECT 1 FROM DUAL") 351 | print(r.fetchall()) 352 | 353 | >> [(1,)] 354 | 355 | ``` 356 | 357 | 358 | ### Create an app user 359 | 360 | Connect as Admin 361 | ```bash 362 | sqlplus admin/@myatp_medium 363 | ``` 364 | Create user as shown below: 365 | ```sql 366 | CREATE USER APP_USER IDENTIFIED BY "" QUOTA UNLIMITED ON DATA; 367 | 368 | -- ADD ROLES 369 | GRANT CONNECT TO APP_USER; 370 | GRANT CONSOLE_DEVELOPER TO APP_USER; 371 | GRANT DWROLE TO APP_USER; 372 | GRANT RESOURCE TO APP_USER; 373 | 374 | 375 | -- ENABLE REST 376 | BEGIN 377 | ORDS.ENABLE_SCHEMA( 378 | p_enabled => TRUE, 379 | p_schema => 'APP_USER', 380 | p_url_mapping_type => 'BASE_PATH', 381 | p_url_mapping_pattern => 'app_user', 382 | p_auto_rest_auth=> TRUE 383 | ); 384 | commit; 385 | END; 386 | / 387 | 388 | -- QUOTA 389 | ALTER USER APP_USER QUOTA UNLIMITED ON DATA; 390 | 391 | ``` 392 | 393 | ### Oracle Estate Explorer (OEE) 394 | 395 | [Oracle Estate Explorer](https://www.oracle.com/database/cloud-migration/estate-explorer/) is a tool that enables customers to 396 | programmatically evaluate groups of Oracle databases for migration readiness to Oracle’s Autonomous Database (ADB). The output from OEE 397 | provides a high-level estate overview of the tested group of databases, ranks them according to their alignment with ADB pre-requisites and 398 | delivers a graded relative effort of any remediation required. 399 | 400 | The OEE APEX app is installed in the adb-free images and is available to use out-of-the-box 401 | 402 | Following steps are required to launch the OEE app: 403 | 404 | 1. Login as Database admin and set a password for the `MPACK_OEE` user 405 | 406 | ```sql 407 | ALTER USER MPACK_OEE IDENTIFIED BY 408 | ``` 409 | 410 | 2. Visit the APEX URL using https://localhost:8443/ords/apex 411 | 412 | 3. Login to the `MPACK_OEE` APEX workspace using the password set in Step 1 413 | 414 | 4. Change the MPACK_OEE’s APEX account password. A warning page will be displayed after changing the MPACK_OEE’s APEX account password, please ignore it and click on Application Builder to launch the OEE application. 415 | 416 | 5. On the application home page, click "Run Application" to open the OEE app in a new browser tab. 417 | 418 | ## F.A.Q 419 | 420 | ### How can I run Oracle Autonomous Database Free container on ARM64 arch i.e. machines with M1/M2 chips ? 421 | Use colima + docker to emulate x86_64 arch. Replace podman with docker in all commands. This is only until we have a native ARM 64 image. 422 | 423 | ### How can I install colima and docker on machines with M1/M2 chips ? 424 | ```bash 425 | brew install docker 426 | brew install docker-compose 427 | brew install colima 428 | brew reinstall qemu 429 | ``` 430 | 431 | ### How can I start Colima x86_64 Virtual Machine with minimum memory/cpu requirements ? 432 | 433 | > Note: Running x86_64 arch containers can have issues translating instructions for ARM. We give higher memory to the VM to avoid such issues 434 | 435 | ```bash 436 | colima start --cpu 4 --memory 10 --arch x86_64 437 | ``` 438 | 439 | ### How can I start Colima x86_64 Virtual Machine using Apple's new virtualization framework - Rosetta ? 440 | 441 | > Note: Running x86_64 arch containers can have issues translating instructions for ARM. We give higher memory to the VM to avoid such issues 442 | 443 | 444 | ```bash 445 | softwareupdate --install-rosetta 446 | colima stop 447 | colima delete 448 | colima start --cpu 4 --memory 10 --arch x86_64 --vm-type vz --vz-rosetta 449 | 450 | # Verify if Colima is using the new profile 451 | docker context ls 452 | colima status 453 | ``` 454 | 455 | ### How can I start podman VM on x86_64 Mac with minimum memory/cpu requirements ? 456 | ```bash 457 | podman machine init 458 | podman machine set --cpus 4 --memory 8192 459 | podman machine start 460 | ``` 461 | 462 | ## Contributing 463 | 464 | This project welcomes contributions from the community. Before submitting a pull request, please [review our contribution guide](./CONTRIBUTING.md) 465 | 466 | ## Security 467 | 468 | Please consult the [security guide](./SECURITY.md) for our responsible security vulnerability disclosure process 469 | 470 | ## License 471 | 472 | Copyright (c) 2024 Oracle and/or its affiliates. 473 | 474 | Released under the Universal Permissive License v1.0 as shown at 475 | . 476 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting security vulnerabilities 2 | 3 | Oracle values the independent security research community and believes that 4 | responsible disclosure of security vulnerabilities helps us ensure the security 5 | and privacy of all our users. 6 | 7 | Please do NOT raise a GitHub Issue to report a security vulnerability. If you 8 | believe you have found a security vulnerability, please submit a report to 9 | [secalert_us@oracle.com][1] preferably with a proof of concept. Please review 10 | some additional information on [how to report security vulnerabilities to Oracle][2]. 11 | We encourage people who contact Oracle Security to use email encryption using 12 | [our encryption key][3]. 13 | 14 | We ask that you do not use other channels or contact the project maintainers 15 | directly. 16 | 17 | Non-vulnerability related security issues including ideas for new or improved 18 | security features are welcome on GitHub Issues. 19 | 20 | ## Security updates, alerts and bulletins 21 | 22 | Security updates will be released on a regular cadence. Many of our projects 23 | will typically release security fixes in conjunction with the 24 | Oracle Critical Patch Update program. Additional 25 | information, including past advisories, is available on our [security alerts][4] 26 | page. 27 | 28 | ## Security-related information 29 | 30 | We will provide security related information such as a threat model, considerations 31 | for secure use, or any known security issues in our documentation. Please note 32 | that labs and sample code are intended to demonstrate a concept and may not be 33 | sufficiently hardened for production use. 34 | 35 | [1]: mailto:secalert_us@oracle.com 36 | [2]: https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html 37 | [3]: https://www.oracle.com/security-alerts/encryptionkey.html 38 | [4]: https://www.oracle.com/security-alerts/ 39 | --------------------------------------------------------------------------------