# Migrate to Servoy Cloud

## Overview

To migrate your existing workspace to Servoy Cloud we should set up some things to get everything working. This guide will explain how to migrate your repository and set up folder structure and properties file contents to have a successful migration.

### Key Points Covered

* **Repository migration** to Servoy Cloud
* **jenkins-custom** folder
* **servoy.properties.template** file

## Migrate Existing GIT Repository

To migrate your existing GIT repository to Servoy Cloud, you must first have a namespace. If you do not have a namespace, follow [these steps](https://docs.servoy.com/reference/servoy-cloud/cloud-control-center/home/setup-namespace) to create one.

### Step 1: Get clone URL of Servoy Cloud Repository

* Log into Cloud Control Center and navigate to Repositories.
* Click on the Clone button to get the clone URL of the Servoy Cloud Repository

### Step 2: Migrate GIT Repository

To migrate a repository with the name `origin` to the Servoy Cloud repository, open a command line and run the following:

Add the new repo location with the clone URL from Servoy Cloud

```
git remote add SCM cloud_clone_url
```

Then push the workspace content to the new location. This will prompt a credentials dialog, please use the Servoy Cloud login credentials.

```
git push SCM master
```

{% hint style="warning" %}
Run this command for each branch of the repository you are migrating to Servoy Cloud.
{% endhint %}

Finally remove the old one

```
git remote rm origin
```

{% hint style="success" %}
Your Servoy Cloud Repository is now set up and you can proceed with setting up your folder and file structure.
{% endhint %}

## jenkins-custom folder

### Folder definition

When first migrating to Servoy Cloud, it is required to have a folder named `jenkins-custom`

This folder is where you place and define the custom settings needed to build your project on Servoy Cloud. It can contain your custom plugins/beans/driver etc. and your `servoy.properties.template` file. It will also contain your TiNG test scripts (E2E) that are needed to run for this build.

### Folder location

The **jenkins-custom** folder can be located anywhere in your workspace, most logic location would be in the root of your workspace.

```
//Example of workspace folder structure

workspace
├── helloWorld
├── jenkins-custom
    ├── servoy.properties.template
    ├── ...
├── ...
```

{% hint style="info" %}
When having multiple jenkins-custom folders, the first one will always be selected.
{% endhint %}

### Folder structure

The `jenkins-custom` folder should have the following structure:

```bash
jenkins-custom
├── servoy.properties.template
├── web.xml
├── context.xml 
├── log4j.xml
├── rewrite.config
├── custom-jars
│   ├── beans
│   |   ├── jpedal.jar
|   ├── drivers
|   |   ├── jt400.jar
|   ├── plugins
|   |   ├── web_client_utils.jar
|   |── server
|       ├── webapps
|           ├── ROOT
|               ├── MyCustomPage.html
|               ├── favicon.ico
|               ├── favicon32x32.png
|               ├── favicon192x192.png
|── e2e-test-scripts
    ├── cypress.config.json
    ├── cypress
        ├── e2e
            ├── loginFlow.cy.js
```

#### Structure notes

| File / Folder                        | Notes                                                                                                                                                   |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| servoy.properties.template           | File containing all params from `servoy.properties` file. This file can be found in the `application_server` folder in your Servoy installation folder. |
| custom-jars                          | Structure will be copied to the Servoy application server on build time. Please note files that exist will be overwritten.                              |
| e2e-test-scripts/cypress.config.json | File containing custom settings that are used when running the E2E tests.                                                                               |
| web.xml                              | Custom web.xml that can be used for generating the war file                                                                                             |
| context.xml                          | Custom context.xml that can be used for generating the war file                                                                                         |
| log4j.xml                            | Custom log4j.xml that can be used for generating the war file                                                                                           |
| rewrite.config                       | Custom rewrite.config file to apply [Tomcat url rewriting](https://tomcat.apache.org/tomcat-9.0-doc/rewrite.html)                                       |

## servoy.properties.template file

### File definition

The `servoy.properties.template` file is the template file used to create a `servoy.properties` file. This template file contains all the properties needed to build your project on Servoy Cloud.

### Database setup

Servoy Cloud will auto create the databases based on the properties and params defined in the servoy.properties.template file.

Therefore, the file should contain server properties with some corresponding params for the DB urls.

| PARAM                  |   |
| ---------------------- | - |
| DB\_POSTGRES\_SERVER   |   |
| DB\_POSTGRES\_USERNAME |   |
| DB\_POSTGRES\_PASSWORD |   |
| DB\_POSTGRES\_PORT     |   |
| DB\_MSSQL\_SERVER      |   |
| DB\_MSSQL\_USERNAME    |   |
| DB\_MSSQL\_PASSWORD    |   |
| DB\_MSSQL\_PORT        |   |
| DB\_MYSQL\_SERVER      |   |
| DB\_MYSQL\_USERNAME    |   |
| DB\_MYSQL\_PASSWORD    |   |
| DB\_MYSQL\_PORT        |   |
| DB\_NAME\_SUFFIX       |   |

This translates to the following jenkins.properties.template sample.

<pre><code><strong>server.1.URL=jdbc\:postgresql\://##DB_POSTGRES_SERVER##\:##DB_POSTGRES_PORT##/svy_security##DB_NAME_SUFFIX##
</strong>server.1.catalog=&#x3C;none>
server.1.connectionValidationType=0
server.1.driver=org.postgresql.Driver
server.1.enabled=true
server.1.maxConnectionsActive=10
server.1.maxConnectionsIdle=10
server.1.maxPreparedStatementsIdle=100
server.1.password=##DB_POSTGRES_PASSWORD##
server.1.schema=&#x3C;none>
server.1.serverName=svy_security
server.1.skipSysTables=false
server.1.userName=##DB_POSTGRES_USERNAME##
</code></pre>

If you have defined several database servers in your Servoy Developer, the file must contain the set of properties for each database server.

You must also include the property `ServerManager.numberOfServers` specifying the number of servers defined.

### Template file basic sample

The sample below has 2 database servers defined: repository\_server and example\_data.

Please note there is a difference in `serverName` and `URL` for each set of properties.

```
ServerManager.numberOfServers=3
server.0.URL=jdbc\:hsqldb\:mem\:repository_server
server.0.catalog=<none>
server.0.connectionValidationType=3
server.0.driver=org.hsqldb.jdbcDriver
server.0.enabled=true
server.0.maxConnectionsActive=30
server.0.maxConnectionsIdle=10
server.0.maxPreparedStatementsIdle=100
server.0.schema=<none>
server.0.password=
server.0.serverName=repository_server
server.0.skipSysTables=false
server.0.userName=##DB_POSTGRES_USERNAME##
server.0.validationQuery=
server.1.URL=jdbc\:postgresql\://##DB_POSTGRES_URL##\:##DB_POSTGRES_PORT##/example_data##dbNameSuffix##
server.1.catalog=<none>
server.1.connectionValidationType=2
server.1.validationQuery=SELECT 1
server.1.driver=org.postgresql.Driver
server.1.enabled=true
server.1.maxConnectionsActive=10
server.1.maxConnectionsIdle=10
server.1.maxPreparedStatementsIdle=100
server.1.password=##DB_POSTGRES_PASSWORD##
server.1.schema=<none>
server.1.serverName=example_data
server.1.skipSysTables=false
server.1.userName=##DB_POSTGRES_USERNAME##
```

### Special handling properties

Some properties in the `servoy.properties.template` are handled differently:

{% hint style="warning" %}
Normally you would not want to set any of these properties.
{% endhint %}

| Servoy Property name                   | Handled in servoy cloud                                                                                                                                  |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| servoy.FileServerService.defaultFolder | When not in the servoy.properties.template the value will be set to: servoy.FileServerService.defaultFolder=${SERVOY\_DEFAULT\_UPLOAD\_LOCATION}/uploads |
| directory.jasper.report                | When not in the servoy.properties.template the value will be set to: directory.jasper.report=${SERVOY\_DEFAULT\_UPLOAD\_LOCATION}/reports                |
| directories.jasper.extra               | When not in the servoy.properties.template the value will be set to: directory.jasper.extra=${SERVOY\_DEFAULT\_UPLOAD\_LOCATION}/reports                 |
| servoy.server.start.rmi=true           | When this is set in the property file smartclient properties will be set in to match Servoy Cloud Configuration                                          |
| servoy.log.clientstats                 | When not in the servoy.properites.template the value will be set to: servoy.log.clientstats=false                                                        |
| server.x.connectionValidationType=1    | All DB Server connectionValidationTypes will be updated to connectionValidationType=3                                                                    |
| servoy.ngclient.testingMode            | This property will be overwritten to false and can only be used in combination with E2E                                                                  |
| servoy.jnlpCodebaseOverride            | This property will be overwritten to servoy.jnlpCodebaseOverride=${SERVOY\_JNLP\_CODEBASE}                                                               |
| amqpbroadcaster.virtualhost            | This property will be overwritten to amqpbroadcaster.virtualhost=${AMQP\_VHOST}                                                                          |
| amqpbroadcaster.tlsprotocols           | This property will be overwritten to amqpbroadcaster.tlsprotocols=${AMQP\_TLSPROTOCOLS}                                                                  |
| amqpbroadcaster.port                   | This property will be overwritten to amqpbroadcaster.port=${AMQP\_PORT}                                                                                  |
| amqpbroadcaster.password               | This property will be overwritten to amqpbroadcaster.password=${AMQP\_PASSWORD}                                                                          |
| amqpbroadcaster.username               | This property will be overwritten to amqpbroadcaster.username=${AMQP\_USERNAME}                                                                          |
| amqpbroadcaster.hostname               | This property will be overwritten to amqpbroadcaster.hostname=${AMQP\_HOSTNAME}                                                                          |

{% hint style="info" %}
Note: `SERVOY_DEFAULT_UPLOAD_LOCATION` will resolve to a persistent storage in Servoy Cloud. This folder is the sole persistent storage.
{% endhint %}

In the servoy.properties.template file you can also use CUSTOM\_ properties.

To create custom properties:

* Create the [custom property](https://docs.servoy.com/reference/cloud-control-center/application-overview/applications/pipelines/jobs/job-configuration/build-and-deploy-or-build#customization) in [Cloud Control Center](https://admin.servoy-cloud.eu/)
* Place the full key in the `servoy.properties.template` like ${CUSTOM\_MY\_PROP}.

To ensure dynamic value resolution within the `servoy.properties.template`, use placeholders in the format of `##key##` or `${key}`. These placeholders are automatically resolved with their corresponding values when generating the WAR file, providing a flexible way to incorporate variable data into your application configuration.
