Internal architecture

The Project is based on Spring Boot, using several technologies which can be seen in the build.gradle.

The provision app is merely an orchestrator that does HTTP REST calls to Atlassian Crowd, Jira, Confluence, Bitbucket and Rundeck (for openshift interaction).

The APIs exposed for direct usage, and also for the UI are in the controller package. The connectors to the various tools to create resources are in the services package

How to develop locally

  1. Make sure that you have installed GIT and JAVA ( >= 8 ).

  2. Clone the project out of Github

$ git clone
  1. Change directory into ods-provisioning-app

$ cd ods-provisioning-app
  1. If you want to build / run locally - create in the project’s root to configure connectivity to OpenDevStack NEXUS

nexus_url=<NEXUS HOST>
nexus_user=<NEXUS USER>

If you want to build / run locally without NEXUS, you can disable NEXUS by adding the following property to


Alternatively, you can also configure the build using environment variables:

Gradle property Environment variable









  1. You can start the application with the following command:

# to run the server execute
./gradlew bootRun

To overwrite the provided a configmap is created out of them and injected into /config/ within the container. The base configuration map as well as the deployment yamls can be found in ocp-config, and overwrite parameters from application.

  1. After started the server it can be reached in the browser under


Frontend Code

The frontend is based on jquery and thymeleaf. All posting to the API happens out of java script (client.js)

Backend Code

The backend is based on Spring Boot, authenticates against Atlassian Crowd (Using property provision.auth.provider=crowd) or OAUTH2/OpenID Connect provider (Using property provision.auth.provider=oauth2) and exposes consumable APIs (api/v2/project). Storage of created projects happens on the filesystem thru the StorageAdapter. Both frontend (html) and backend are tested thru Junit & Mockito

Authentication Implementation

By using the property provision.auth.provider=crowd or provision.auth.provider=oauth2, the application uses eigher CROWD or OAUTH2 authentication. Dependent of the property used, different spring beans are used for configuration. The switch between the two options is implemented via Spring’s ConditionalOnProperty annotation.

CROWD - specific configuration classes are located in the java package org.opendevstack.provision.authentication.crowd.

@ConditionalOnProperty(name = "provision.auth.provider", havingValue = "crowd")
public class CrowdSecurityConfiguration extends WebSecurityConfigurerAdapter {

OAUTH2 - specific configuration classes are located in the java package org.opendevstack.provision.authentication.oauth2.

@ConditionalOnProperty(name = "provision.auth.provider", havingValue = "oauth2")
public class Oauth2SecurityConfiguration extends WebSecurityConfigurerAdapter {

Consuming REST APIs in Java

Generally this is a pain. To ease development, a few tools are in use:

  • Jackson (see link below)

  • OKTTP3 Client (see link below)

  • jsonschema2pojo generator (see link below)

The process for new operations to be called is:

  1. Look up the API call that you intend to make

  2. see if there is a JSON Schema available

  3. Generate (a) Pojo('s) for the Endpoint

  4. Use the pojo to build your request, convert it to JSON with Jackson and send it via OKHTTP3, and the Provision Application’s RestClient