---
title: "Deploy a local DataSHIELD server with Opal"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Deploy a local DataSHIELD server with Opal}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
# nothing in this vignette is run: it needs Docker and a local server
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  cache = FALSE,
  eval = FALSE
)
```

This tutorial starts a local [DataSHIELD](https://datashield.org) server with
[Docker](https://www.docker.com), so you can try `{dsROCrate}` (or anything else
that talks to DataSHIELD) without touching a production system. It uses
[Opal](https://www.obiba.org/pages/products/opal/), the data repository
developed by [OBiBa](https://www.obiba.org/) and the reference implementation
of the DataSHIELD infrastructure.

**Local testing only:** the accounts and passwords below are public defaults.
Never expose this deployment to a network, and change them if you reuse it for
anything else.

## 1. Start the containers

We assume Docker is installed and configured on your computer; if not, see
[Get started with Docker](https://www.docker.com/get-started/).

The easiest option is to clone
[FederatedMethods/datashield_dev_install](https://github.com/FederatedMethods/datashield_dev_install),
which has a step by step guide and a ready to use
[`docker-compose.yml`](https://github.com/FederatedMethods/datashield_dev_install/blob/main/docker/docker-compose.yml).
On Linux or macOS:

```sh
git clone https://github.com/FederatedMethods/datashield_dev_install
cd datashield_dev_install/docker
docker compose up -d
```

In the Docker GUI you should see something like the following:

<img src="../man/figures/ds_docker_compose.png" alt="Docker containers started by docker-compose" height=200px/>

## 2. The accounts

The `docker-compose.yml` file defines two accounts (you can change them by
editing the variables `OPAL_DEMO_USER_NAME` and `OPAL_DEMO_USER_PASSWORD`):

| Account         | Password   | Used for                                              |
|-----------------|------------|-------------------------------------------------------|
| `administrator` | `password` | Logging in to the Opal web interface; auditing with `{dsROCrate}` |
| `dsuser`        | `P@ssw0rd` | Running DataSHIELD analyses (the user whose activity is audited) |

## 3. Test the deployment

1. In a web browser, go to `http://localhost:8880` <!-- @URLok -->
   and log in as `administrator`.

2. In RStudio (or your preferred IDE), connect to the server from R:

   ```r
   con <- opalr::opal.login(
     username = "administrator",
     password = "password",
     url = "http://localhost:8880"
   )
   print(con)
   ```

   You should see something like:

   ```bash
   url: http://localhost:8880
   name: localhost
   version: X.Y.Z
   username: administrator
   ```

   `{dsROCrate}` requires Opal 5.7.2 or later (6.0 or later to capture
   `RESOLVE` operations in the outputs). If the version shown is older, update
   the Opal image in `docker-compose.yml`.

   The containers also expose HTTPS on port 8843. That endpoint usually uses a
   self-signed certificate, which R clients may reject unless certificate
   verification is relaxed, so we use plain HTTP on port 8880 for local testing.

3. (Optional) Run some commands as `dsuser` with `{dsBaseClient}`. This also
   creates activity in the server logs, which the audit in the next section
   will find:

   ```r
   # registers the OpalDriver class in the current session
   DSOpal::Opal()

   # create the login object
   builder <- DSI::newDSLoginBuilder()
   builder$append(
     server = "study1",
     url = "http://localhost:8880",
     user = "dsuser",
     password = "P@ssw0rd",
     driver = "OpalDriver"
   )
   conns <- DSI::datashield.login(logins = builder$build())

   # assign a table to the symbol `test`
   DSI::datashield.assign.table(
     conns["study1"],
     symbol = "test",
     table = "CNSIM.CNSIM1",
     errors.print = TRUE
   )

   dsBaseClient::ds.ls(datasources = conns["study1"])
   dsBaseClient::ds.summary("test", datasources = conns["study1"])

   DSI::datashield.logout(conns)
   ```

## 4. Audit your local server

With the connection `con` from step 3.2:

```r
dsROCrate::check_permissions(con, verbose = TRUE)

crate <- dsROCrate::audit(
  con,
  project = "CNSIM",
  tables = "CNSIM1",
  user = "dsuser"
)

dsROCrate::report(crate, title = "Local DataSHIELD audit")

opalr::opal.logout(con)
```

See `vignette("getting-started", package = "dsROCrate")` for what these
functions do, and `vignette("audit-permissions", package = "dsROCrate")` to
create a dedicated auditor account instead of using `administrator`.

## 5. Stop the server

From the same `docker` directory:

```sh
docker compose down
```
