Development Procedure - Confluence Splice
Basic Overview of a Connector Framework - Functional
IDHub Connectors Framework Overview shows the different modules that make up the Connector Framework.
Requirements for Target System
Be clear with the requirements of the Splice. Basic naming conventions and other requirements will be mentioned here. IDHUB-2613
Know the different Resources that are applicable to the Target System. Resources of IDHub are of two types - Accounts and Entitlements.
Different Target Systems may have different Entitlement Resources. For example, Confluence has two types of Entitlements - Groups and Spaces.
Familiarise with the Target System to see the way Accounts and Entitlements are displayed/added/updated/deleted.
Analysis and Design for Target System
A design document shows how the Accounts and Entitlements of a Target System are mapped to the Accounts and Entitlements of IDHub, functionalities of Splice that are developed and also the pseudo code for Splice development.
Search for Target System documentations that provide APIs that enable users to fetch/create/modify/delete Accounts and Entitlements in the Target System.
Call the APIs from Postman to verify functionality in the Target System. An account in the Target System may be required for this.
Identify the fields of each Resource of the Target System - mandatory and optional (as per IDHub requirements) .
Decide the Schema of the Target System Resources - If the Target System does not provide an API representing the Resource Schema, then the Schema needs to be built manually based on Resource fields.
Create the design document with all the necessary information and pseudo code.
Confluence Splice is the design document for Confluence which contains all necessary information to develop the Splice.
Splice development
Basic Requirements
The Splice needs to implement idhub-connector-spi and idhub-connector-application.
A sample build.gradle file is attached
plugins {
id 'maven-publish'
id 'idea'
id 'java'
id 'org.sonarqube' version '3.3'
id 'com.palantir.docker' version '0.31.0'
id 'com.palantir.docker-run' version '0.31.0'
id 'com.palantir.git-version' version '0.12.3'
id 'org.springframework.boot' version '2.6.1'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.palantir.docker'
apply plugin: 'idea'
project.description = 'Confluence Splice'
project.version = '22.0.0'
project.group = 'com.sath.idhub'
String CONNECTOR_VERSION = '2.1.6'
String CONNECTOR_SPI_VERSION = '3.2.1'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-configuration-processor'
implementation 'com.google.code.findbugs:jsr305:3.0.2'
implementation 'com.fasterxml.jackson.core:jackson-core:2.13.2'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.2'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.1'
implementation 'org.apache.commons:commons-lang3:3.12.0'
implementation 'com.atlassian.confluence:confluence:7.12.2'
implementation 'com.googlecode.json-simple:json-simple:1.1.1'
implementation "com.sath.idhub:idhub-connector-spi:${CONNECTOR_SPI_VERSION}"
implementation "com.sath.idhub:idhub-connector-application:${CONNECTOR_VERSION}"
compileOnly 'org.projectlombok:lombok'
testImplementation 'org.springframework.security:spring-security-test:5.6.2'
testImplementation 'org.springframework.boot:spring-boot-starter-test:2.6.4'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}
// Intellij Idea Configurations for Javadocs and Sources
idea {
module {
downloadJavadoc = true
downloadSources = true
}
}
// Docker
String dockerAndMavenRepoUsername = System.env['IDHUB_DOCKER_USER']
String dockerAndMavenRepoPassword = System.env['IDHUB_DOCKER_PASSWORD']
// Settings to pull from maven central and sath repositories
repositories {
mavenCentral()
maven {
url = uri('https://maven.atlassian.com/repository/public')
}
maven {
url "https://repo.sath.com/repository/maven-snapshots/"
credentials {
username dockerAndMavenRepoUsername
password dockerAndMavenRepoPassword
}
}
maven {
url "https://repo.sath.com/repository/maven-releases/"
credentials {
username dockerAndMavenRepoUsername
password dockerAndMavenRepoPassword
}
}
}
java.sourceCompatibility = JavaVersion.VERSION_17
java {
withSourcesJar()
withJavadocJar()
}
jar {
// Spring set this to plain so their springboot jar can be unclassified
// Unclassified is going to be uploaded to maven repo
archiveClassifier = ''
}
bootJar {
// The rebuilt fat springboot jar get classified as with-connector
// This is the jar that gets is used in the Dockerfile
archiveClassifier = "with-connector-${CONNECTOR_VERSION}"
manifest {
attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher'
}
mainClass = 'com.sath.idhub.connector.application.ConnectorApplication'
}
test {
//enabled=false
// This is for JUnit 5
useJUnitPlatform()
}
// Link publish to building
tasks.publish.dependsOn(tasks.build)
publishing {
repositories {
maven {
url version.endsWith('SNAPSHOT')
? "https://repo.sath.com/repository/maven-snapshots/"
: "https://repo.sath.com/repository/maven-releases/"
credentials {
username dockerAndMavenRepoUsername
password dockerAndMavenRepoPassword
}
}
}
publications {
myPublication(MavenPublication) {
from components.java
pom {
name = project.name
description = project.description
developers {
developer {
name = System.properties.get('user.name')
}
}
}
}
}
}
def gitVersion = versionDetails()
String dockerName = 'docker.sath.com/confluence-idhub-connector:' + gitVersion.branchName.split('/').last()
tasks.dockerPrepare.dependsOn(tasks.bootJar)
tasks.docker.dependsOn(tasks.build)
tasks.dockerPush.dependsOn(tasks.dockerTag)
tasks.dockerPrepare.dependsOn(tasks.jar)
tasks.dockerPrepare.dependsOn(tasks.javadocJar)
tasks.dockerPrepare.dependsOn(tasks.sourcesJar)
docker {
name = dockerName
copySpec.from('src/main/docker').into('.')
.from('build/libs').into('.')
tag 'Nexus', "$dockerName"
buildArgs([
SPLICE_VERSION: project.version,
CONNECTOR_VERSION : CONNECTOR_VERSION
])
labels([
'build-time' : new Date(),
'user.name' : System.properties.get('user.name'),
'java.vm.version' : System.properties.get('java.vm.version'),
'java.runtime.name' : System.properties.get('java.runtime.name'),
'git-commit-hash' : gitVersion.gitHash,
'git-branch' : gitVersion.branchName,
'git-last-tag' : gitVersion.lastTag,
'git-commit-distance': gitVersion.commitDistance,
'git-clean' : gitVersion.isCleanTag,
])
}
dockerRun {
name project.name
image dockerName
ports '8086:8086'
daemonize true
command 'sleep', '100'
arguments '--hostname=custom', '-P'
}
tasks.register("getDockerImageName") {
println dockerName
}
tasks.register("info") {
System.out.println 'Building Project :' + project.name
System.out.println 'Description :' + project.description
System.out.println 'Last Tag :' + gitVersion.lastTag
System.out.println 'Git Commit Distance : ' + gitVersion.commitDistance
System.out.println 'Git Hash : ' + gitVersion.gitHash
System.out.println 'Branch : ' + gitVersion.branchName
System.out.println 'Git isClean : ' + gitVersion.isCleanTag
System.out.println 'Docker Image Name : ' + dockerName
System.out.println 'Current Timestamp : ' + new Date()
System.out.println 'User : ' + System.properties.get('user.name')
}
Splice Development
Splice development consists of :
CommonConnectorService implementation
public class ConnectorService implements CommonConnectorService {}
ScimResourceService implementation for the different Target System Resources
public class AccountResourceService implements ScimResourceService {}
Resource models that contain the different fields to define Resource Schema
public class Account extends IdhubObject {}
Unit Testing
Unit Testing tests the proper functioning of all endpoints that will be used by IDHub
Create sample Resources to test GET, POST, PUT, PATCH, DELETE and Search functionalities.
Scenarios to cover
Functionality of the connector for Accounts :
Create (with/without entitlements)
Get account by ID
Update - via patch add/remove Entitlements, replace attributes. (PATCH operation)
Replace account with/without Entitlements via put (PUT operation)
Delete
List accounts
Provide account schema
Functionality of the connector for Entitlements :
Provide entitlement schema
Get entitlement by ID
List entitlements
Create entitlement (Not mandatory for this version, may/may not be added)
Replace entitlement via Put operation (Not mandatory for this version, may/may not be added)
Delete (Not mandatory for this version, may/may not be added)
Deployment Document
This contains the steps necessary for a user to :
setup the Splice as a runnable JAR
setup the Admin Account in Target System that will interact with IDHub
End to End Testing and Integration Testing
Once deployed, the Splice can be tested using IDHub by provisioning and reconciling Accounts and Entitlements
The same steps can be made into Integration Tests.