SlideShare a Scribd company logo
VINCENT KOK • DEVELOPMENT MANAGER • ATLASSIAN • @VINCENTKOK
Connecting Connect
with Spring Boot
Atlassian Supported
Community Frameworks
go.atlassian.com/connectframeworks
STARTERS
SPRING BOOT
CONNECT STARTER
INCEPTION
Agenda
SPRING BOOT
http://geek-and-poke.com/geekandpoke/2014/1/2/games-for-the-real-geeks-part-2
A “vanilla” Spring web app
A “vanilla” Spring web app
1. Dependencies
Setup the right Maven dependencies
A “vanilla” Spring web app
1. Dependencies
Setup the right Maven dependencies
web.xml
Setup your web.xml
A “vanilla” Spring web app
1. Dependencies
Setup the right Maven dependencies
application-context.xml
Enable component scanning and mvc
annotation driven
web.xml
Setup your web.xml
A “vanilla” Spring web app
1. Dependencies
Setup the right Maven dependencies
4. The actual controller
What you actually care about
application-context.xml
Enable component scanning and mvc
annotation driven
web.xml
Setup your web.xml
A “vanilla” Spring web app
5. Install Tomcat
And configure it as well
1. Dependencies
Setup the right Maven dependencies
4. The actual controller
What you actually care about
application-context.xml
Enable component scanning and mvc
annotation driven
web.xml
Setup your web.xml
A “vanilla” Spring web app
5. Install Tomcat
And configure it as well
6. It might work
You probably made a typo

1. Dependencies
Setup the right Maven dependencies
4. The actual controller
What you actually care about
application-context.xml
Enable component scanning and mvc
annotation driven
web.xml
Setup your web.xml
• Big cool statistic
• 2,56
9
• Add-Ons in Marketplace
Repeatable pattern
https://flic.kr/p/8ykpkW
Spring Boot
Repeatable patterns for services
Fast Opinionated Auto Configured No code generation
Example: Hello world
e
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atlassian.connect.lighthing</groupId>
<artifactId>lightingdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
Example: Hello world
e
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atlassian.connect.lighthing</groupId>
<artifactId>lightingdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
</parent>
Example: Hello world
e
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atlassian.connect.lighthing</groupId>
<artifactId>lightingdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Example: Hello world
e
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
Example: Hello world
e
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
@SpringBootApplication
public class HelloApplication {
Example: Hello world
e
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
Example: Hello world
e
package hello;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
@RestController
public class HelloController {
@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
}
Example: Hello world
e
package hello;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
@RestController
public class HelloController {
@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
}
@RestController
public class HelloController {
Example: Hello world
e
package hello;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
@RestController
public class HelloController {
@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
}
@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
Example: Hello world
e
$> mvn spring-boot:run
Example: Hello world
e
$> mvn spring-boot:run
$> curl http://localhost:8080/
Greetings from Spring Boot!
Provides production ready
features
Think health checks, metrics, security
and externalised configuration
STARTERS
SPRING BOOT
CONNECT STARTER
INCEPTION
Agenda
STARTERS
Spring Boot Starters
Building blocks Out of the box Build your own
Building blocks for your service
Example: Consume a starter
e
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependencies>
Example: Consume a starter
e
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Example: Consume a starter
e
$> mvn spring-boot:run
Example: Consume a starter
e
$> mvn spring-boot:run
$> curl http://localhost:8080/health
{”status”:”UP”}
Available Starters
Out of the box
63*
* as counted by myself at midnight
STARTERS
SPRING BOOT
CONNECT STARTER
INCEPTION
Agenda
CONNECT STARTER
Three things every add-on requires
Lifecycle Descriptor JWT
Connecting Connect with Spring Boot
1: /atlassian-connect.json
1: /atlassian-connect.json
2: Descriptor JSON
1: /atlassian-connect.json
2: Descriptor JSON
3: /install
1: /atlassian-connect.json
2: Descriptor JSON
3: /install
4. Store tenant data
1: /atlassian-connect.json
2: Descriptor JSON
3: /install
5: Install OK / not OK
4. Store tenant data
Descriptor
e
{
"name": "Inception",
"description": “A page in a page",
"key": “com.atlassian.connect.atlascamp.inception”,
"baseUrl": “http://localhost:8080”,
"vendor": {
"name": "Atlassian",
"url": "http://www.atlassian.com"
},
"authentication": {
"type": "jwt"
},
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled",
"enabled": "/enabled",
"disabled": "/disabled"
},
"apiVersion": 1,
"scopes": [
"read"
],
"modules": {
}
}
Descriptor
e
{
"name": "Inception",
"description": “A page in a page",
"key": “com.atlassian.connect.atlascamp.inception”,
"baseUrl": “http://localhost:8080”,
"vendor": {
"name": "Atlassian",
"url": "http://www.atlassian.com"
},
"authentication": {
"type": "jwt"
},
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled",
"enabled": "/enabled",
"disabled": "/disabled"
},
"apiVersion": 1,
"scopes": [
"read"
],
"modules": {
}
}
"name": "Inception",
"description": “A page in a page",
"key": “com.atlassian.connect.atlascamp.inception”,
"baseUrl": “http://localhost:8080”,
"vendor": {
"name": "Atlassian",
"url": "http://www.atlassian.com"
},
Descriptor
e
{
"name": "Inception",
"description": “A page in a page",
"key": “com.atlassian.connect.atlascamp.inception”,
"baseUrl": “http://localhost:8080”,
"vendor": {
"name": "Atlassian",
"url": "http://www.atlassian.com"
},
"authentication": {
"type": "jwt"
},
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled",
"enabled": "/enabled",
"disabled": "/disabled"
},
"apiVersion": 1,
"scopes": [
"read"
],
"modules": {
}
}
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled",
"enabled": "/enabled",
"disabled": "/disabled"
}
Descriptor
e
{
"name": "Inception",
"description": “A page in a page",
"key": “com.atlassian.connect.atlascamp.inception”,
"baseUrl": “http://localhost:8080”,
"vendor": {
"name": "Atlassian",
"url": "http://www.atlassian.com"
},
"authentication": {
"type": "jwt"
},
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled",
"enabled": "/enabled",
"disabled": "/disabled"
},
"apiVersion": 1,
"scopes": [
"read"
],
"modules": {
}
}
"modules": {
}
Lifecycle
e
{
"key": “com.atlassian.connect.atlascamp.inception”,
"clientKey": "Confluence:5358671948",
"publicKey": "MIGf....ZRWzwIDAQAB",
"sharedSecret": "fda9e230-ba1b-4e8d-a76e-c9e4e6c28ea8",
"serverVersion": "6437",
"pluginsVersion": "1.1.81",
"baseUrl": “http://vincentkok.atlassian.net",
"productType": "confluence",
"description": "Atlassian Confluene at https://example.atlassian.net",
"eventType": "INSTALLED"
}
Lifecycle
e
{
"key": “com.atlassian.connect.atlascamp.inception”,
"clientKey": "Confluence:5358671948",
"publicKey": "MIGf....ZRWzwIDAQAB",
"sharedSecret": "fda9e230-ba1b-4e8d-a76e-c9e4e6c28ea8",
"serverVersion": "6437",
"pluginsVersion": "1.1.81",
"baseUrl": “http://vincentkok.atlassian.net",
"productType": "confluence",
"description": "Atlassian Confluene at https://example.atlassian.net",
"eventType": "INSTALLED"
}
"key": “com.atlassian.connect.atlascamp.inception”,
"clientKey": "Confluence:5358671948",
Lifecycle
e
{
"key": “com.atlassian.connect.atlascamp.inception”,
"clientKey": "Confluence:5358671948",
"publicKey": "MIGf....ZRWzwIDAQAB",
"sharedSecret": "fda9e230-ba1b-4e8d-a76e-c9e4e6c28ea8",
"serverVersion": "6437",
"pluginsVersion": "1.1.81",
"baseUrl": “http://vincentkok.atlassian.net",
"productType": "confluence",
"description": "Atlassian Confluene at https://example.atlassian.net",
"eventType": "INSTALLED"
}
"sharedSecret": "fda9e230-ba1b-4e8d-a76e-c9e4e6c28ea8",
Lifecycle
e
{
"key": “com.atlassian.connect.atlascamp.inception”,
"clientKey": "Confluence:5358671948",
"publicKey": "MIGf....ZRWzwIDAQAB",
"sharedSecret": "fda9e230-ba1b-4e8d-a76e-c9e4e6c28ea8",
"serverVersion": "6437",
"pluginsVersion": "1.1.81",
"baseUrl": “http://vincentkok.atlassian.net",
"productType": "confluence",
"description": "Atlassian Confluene at https://example.atlassian.net",
"eventType": "INSTALLED"
} “eventType": "INSTALLED",
JWT
e
<base64url-encoded header>.
<base64url-encoded claims>.
<base64url-encoded signature>
JWT
e
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEzODY4
OTkxMzEsImlzcyI6ImppcmE6MTU0ODk1OTUiLCJxc2giOiI4MDYzZ
mY0Y2ExZTQxZGY3YmM5MGM4YWI2ZDBmNjIwN2Q0OTFjZjZkYWQ3Yz
Y2ZWE3OTdiNDYxNGI3MTkyMmU5IiwiaWF0IjoxMzg2ODk4OTUxfQ.
uKqU9dTB6gKwG6jQCuXYAiMNdfNRw98Hw_IWuA5MaMo
JWT
e
{
"typ":"JWT",
"alg":"HS256"
}
{
"iss": "confluence:1314039",
"iat": 1300819370,
"exp": 1300819380,
"qsh": "8063ff4ca1e41df7bc90c8ab6d0f6207d491cf6dad7c66ea797b4614b71922e9",
"sub": "alana",
"context": {
"user": {
"userKey": "alana",
"username": "aaware",
"displayName": "Bruce Wayne"
}
}
}
JWT
e
{
"typ":"JWT",
"alg":"HS256"
}
{
"iss": "confluence:1314039",
"iat": 1300819370,
"exp": 1300819380,
"qsh": "8063ff4ca1e41df7bc90c8ab6d0f6207d491cf6dad7c66ea797b4614b71922e9",
"sub": "alana",
"context": {
"user": {
"userKey": "alana",
"username": "aaware",
"displayName": "Bruce Wayne"
}
}
}
{
"typ":"JWT",
"alg":"HS256"
}
JWT
e
{
"typ":"JWT",
"alg":"HS256"
}
{
"iss": "confluence:1314039",
"iat": 1300819370,
"exp": 1300819380,
"qsh": "8063ff4ca1e41df7bc90c8ab6d0f6207d491cf6dad7c66ea797b4614b71922e9",
"sub": "alana",
"context": {
"user": {
"userKey": "alana",
"username": "aaware",
"displayName": "Bruce Wayne"
}
}
}
"iss": "confluence:1314039",
"iat": 1300819370,
"exp": 1300819380,
"qsh": “8063ff4…2e9”,
"sub": "alana",
Authenticated requests
e
/inception-macro?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl…
Authenticated requests
e"Authorization" : "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl..."
/inception-macro?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJl…
• Big cool statistic
• 2,56
9
• Add-Ons in Marketplace
DRY
https://flic.kr/p/qkUpu
Atlassian Supported
Community Frameworks
Atlassian Supported
Community Frameworks
BETA
http://go.atlassian.com/ac-springboot
STARTERS
SPRING BOOT
CONNECT STARTER
IN UNDER 3 MINUTES
Agenda
INCEPTION
• Big cool statistic
• 2,56
9
• Add-Ons in Marketplace
Let’s build a Connect add-on
from scratch
https://flic.kr/p/rtmnT2
• Big cool statistic
• 2,56
9
• Add-Ons in Marketplace
A page in a page
https://flic.kr/p/216z4i
Connecting Connect with Spring Boot
1: inception-macro?pageId=5&jwt=eyJhbGciOiJIUz
1: inception-macro?pageId=5&jwt=eyJhbGciOiJIUz
2:/rest/api/content/5?expand=body.export_view
1: inception-macro?pageId=5&jwt=eyJhbGciOiJIUz
2:/rest/api/content/5?expand=body.export_view
3: Page content as JSON
1: inception-macro?pageId=5&jwt=eyJhbGciOiJIUz
2:/rest/api/content/5?expand=body.export_view
3: Page content as JSON
4: Rendered macro HTML
Create a project
e
$> mvn archetype:generate -DgroupId=com.atlassian.labs.atlascamp
-DartifactId=inception -DarchetypeArtifactId=maven-archetype-
quickstart -DinteractiveMode=false
Create a project
e
$ ls inception
pom.xml

src
Add dependencies
e
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atlassian.labs.atlascamp</groupId>
<artifactId>inception</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
Add dependencies
e
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atlassian.labs.atlascamp</groupId>
<artifactId>inception</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
</parent>
Add dependencies
e
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atlassian.labs.atlascamp</groupId>
<artifactId>inception</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.atlassian.connect</groupId>
<artifactId>atlassian—spring-boot-starter</artifactId>
<version>1.0.0-beta-1</version>
</dependency>
</dependencies>
Create the application
e
package com.atlassian.connect.atlascamp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class InceptionApplication {
public static void main( String[] args ) {
SpringApplication.run(InceptionApplication.class, args);
}
}
Create the application
e
package com.atlassian.connect.atlascamp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class InceptionApplication {
public static void main( String[] args ) {
SpringApplication.run(InceptionApplication.class, args);
}
}
@SpringBootApplication
public class InceptionApplication {
Create the application
e
package com.atlassian.connect.atlascamp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class InceptionApplication {
public static void main( String[] args ) {
SpringApplication.run(InceptionApplication.class, args);
}
}
public static void main(String[] args) {
SpringApplication.run(InceptionApplication.class, args);
}
Descriptor
e
$> touch src/main/resources/atlassian-connect.json
Descriptor
e
{
"name": "Inception",
"description": “A page in a page",
"key": “com.atlassian.connect.atlascamp.inception”,
"baseUrl": “http://localhost:8080”,
"vendor": {
"name": "Atlassian",
"url": "http://www.atlassian.com"
},
"authentication": {
"type": "jwt"
},
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled",
"enabled": "/enabled",
"disabled": "/disabled"
},
"apiVersion": 1,
"scopes": [
"read"
],
"modules": {
}
}
Descriptor
e
{
"name": "Inception",
"description": “A page in a page",
"key": “com.atlassian.connect.atlascamp.inception”,
"baseUrl": “http://localhost:8080”,
"vendor": {
"name": "Atlassian",
"url": "http://www.atlassian.com"
},
"authentication": {
"type": "jwt"
},
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled",
"enabled": "/enabled",
"disabled": "/disabled"
},
"apiVersion": 1,
"scopes": [
"read"
],
"modules": {
}
}
"name": "Inception",
"description": “A page in a page",
"key": “com.atlassian.connect.atlascamp.inception”,
"baseUrl": “https://1c12a2cd.ngrok.io”,
"vendor": {
"name": "Atlassian",
"url": "http://www.atlassian.com"
},
Descriptor
e
{
"name": "Inception",
"description": “A page in a page",
"key": “com.atlassian.connect.atlascamp.inception”,
"baseUrl": “http://localhost:8080”,
"vendor": {
"name": "Atlassian",
"url": "http://www.atlassian.com"
},
"authentication": {
"type": "jwt"
},
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled",
"enabled": "/enabled",
"disabled": "/disabled"
},
"apiVersion": 1,
"scopes": [
"read"
],
"modules": {
}
}
"modules": {
}
Descriptor
e
"modules": {
"dynamicContentMacros": [ {
"url": "/inception-macro?pageId={page.id}",
"description": {
"value": "A page in a page"
},
"name": {
"value": "Inception"
},
"categories": [
"visuals"
],
"outputType": "block",
"bodyType": "none",
"aliases": [
"inception"
],
"featured": true,
"parameters": [],
"key": "inception-macro"
}
]
}
Descriptor
e
"modules": {
"dynamicContentMacros": [ {
"url": "/inception-macro?pageId={page.id}",
"description": {
"value": "A page in a page"
},
"name": {
"value": "Inception"
},
"categories": [
"visuals"
],
"outputType": "block",
"bodyType": "none",
"aliases": [
"inception"
],
"featured": true,
"parameters": [],
"key": "inception-macro"
}
]
}
"dynamicContentMacros": [ {
"url": "/inception-macro?pageId={page.id}",
"description": {
"value": "A page in a page"
},
Tenant storage
e
HHH000227: Running hbm2ddl schema export
Tenant storage
e
spring.jpa.database=POSTGRESQL
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:postgresql://localhost:5432/springbootdb
Macro template
e
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.atlassian.connect</groupId>
<artifactId>atlassian-connect-spring-boot-starter</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
Macro template
e
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.atlassian.connect</groupId>
<artifactId>atlassian-connect-spring-boot-starter</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Macro template
e
$> touch src/main/resources/templates/inception-macro.html
Macro template
e
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" href="//aui-cdn.atlassian.com/aui.min.css" media="all"/>
<script th:src=“${js-all-url}” type="text/javascript"></script>
</head>
<body>
<section id="content" class="ac-content">
<p th:utext="${body}"/>
</section>
</body>
</html>
Macro template
e
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" href="//aui-cdn.atlassian.com/aui.min.css" media="all"/>
<script th:src=“${js-all-url}” type="text/javascript"></script>
</head>
<body>
<section id="content" class="ac-content">
<p th:utext="${body}"/>
</section>
</body>
</html>
<script th:src=“${js-all-url}” type="text/javascript"></script>
Macro template
e
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" href="//aui-cdn.atlassian.com/aui.min.css" media="all"/>
<script th:src=“${js-all-url}” type="text/javascript"></script>
</head>
<body>
<section id="content" class="ac-content">
<p th:utext="${body}"/>
</section>
</body>
</html>
<section id="content" class="ac-content">
<p th:utext="${body}"/>
</section>
Controller
e
package com.atlassian.connect.atlascamp;
@Controller
public class InceptionController {
private static final String PAGE_URL = "%s/rest/api/content/%s?expand=body.export_view";
private static final String JS_URL = "%s/atlassian-connect/all.js";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/inception-macro")
public String render(@RequestParam long pageId,
@AuthenticationPrincipal AtlassianHostUser hostUser, Model model) {
final String baseURL = hostUser.getHost().getBaseUrl();
final String contentUrl = String.format(PAGE_URL, baseURL, pageId);
final String pageContent = restTemplate.getForObject(contentUrl, String.class);
final String pageBody = extractPageBody(pageContent);
model.addAttribute("body", pageBody);
model.addAttribute("jsurl", String.format(JS_URL, baseURL));
return "inception-macro";
}
Controller
e
package com.atlassian.connect.atlascamp;
@Controller
public class InceptionController {
private static final String PAGE_URL = "%s/rest/api/content/%s?expand=body.export_view";
private static final String JS_URL = "%s/atlassian-connect/all.js";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/inception-macro")
public String render(@RequestParam long pageId,
@AuthenticationPrincipal AtlassianHostUser hostUser, Model model) {
final String baseURL = hostUser.getHost().getBaseUrl();
final String contentUrl = String.format(PAGE_URL, baseURL, pageId);
final String pageContent = restTemplate.getForObject(contentUrl, String.class);
final String pageBody = extractPageBody(pageContent);
model.addAttribute("body", pageBody);
model.addAttribute("jsurl", String.format(JS_URL, baseURL));
return "inception-macro";
}
@Controller
public class InceptionController {
Controller
e
package com.atlassian.connect.atlascamp;
@Controller
public class InceptionController {
private static final String PAGE_URL = "%s/rest/api/content/%s?expand=body.export_view";
private static final String JS_URL = "%s/atlassian-connect/all.js";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/inception-macro")
public String render(@RequestParam long pageId,
@AuthenticationPrincipal AtlassianHostUser hostUser, Model model) {
final String baseURL = hostUser.getHost().getBaseUrl();
final String contentUrl = String.format(PAGE_URL, baseURL, pageId);
final String pageContent = restTemplate.getForObject(contentUrl, String.class);
final String pageBody = extractPageBody(pageContent);
model.addAttribute("body", pageBody);
model.addAttribute("jsurl", String.format(JS_URL, baseURL));
return "inception-macro";
}
private static final String PAGE_URL
private static final String JS_URL
Controller
e
package com.atlassian.connect.atlascamp;
@Controller
public class InceptionController {
private static final String PAGE_URL = "%s/rest/api/content/%s?expand=body.export_view";
private static final String JS_URL = "%s/atlassian-connect/all.js";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/inception-macro")
public String render(@RequestParam long pageId,
@AuthenticationPrincipal AtlassianHostUser hostUser, Model model) {
final String baseURL = hostUser.getHost().getBaseUrl();
final String contentUrl = String.format(PAGE_URL, baseURL, pageId);
final String pageContent = restTemplate.getForObject(contentUrl, String.class);
final String pageBody = extractPageBody(pageContent);
model.addAttribute("body", pageBody);
model.addAttribute("jsurl", String.format(JS_URL, baseURL));
return "inception-macro";
}
@Autowired
private RestTemplate restTemplate;
Controller
e
package com.atlassian.connect.atlascamp;
@Controller
public class InceptionController {
private static final String PAGE_URL = "%s/rest/api/content/%s?expand=body.export_view";
private static final String JS_URL = "%s/atlassian-connect/all.js";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/inception-macro")
public String render(@RequestParam long pageId,
@AuthenticationPrincipal AtlassianHostUser hostUser, Model model) {
final String baseURL = hostUser.getHost().getBaseUrl();
final String contentUrl = String.format(PAGE_URL, baseURL, pageId);
final String pageContent = restTemplate.getForObject(contentUrl, String.class);
final String pageBody = extractPageBody(pageContent);
model.addAttribute("body", pageBody);
model.addAttribute("jsurl", String.format(JS_URL, baseURL));
return "inception-macro";
}
@RequestMapping(value = "/inception-macro")
public String render(@RequestParam long pageId,
Controller
e
package com.atlassian.connect.atlascamp;
@Controller
public class InceptionController {
private static final String PAGE_URL = "%s/rest/api/content/%s?expand=body.export_view";
private static final String JS_URL = "%s/atlassian-connect/all.js";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/inception-macro")
public String render(@RequestParam long pageId,
@AuthenticationPrincipal AtlassianHostUser hostUser, Model model) {
final String baseURL = hostUser.getHost().getBaseUrl();
final String contentUrl = String.format(PAGE_URL, baseURL, pageId);
final String pageContent = restTemplate.getForObject(contentUrl, String.class);
final String pageBody = extractPageBody(pageContent);
model.addAttribute("body", pageBody);
model.addAttribute("jsurl", String.format(JS_URL, baseURL));
return "inception-macro";
}
@AuthenticationPrincipal AtlassianHostUser hostUser, Model model) {
final String baseURL = hostUser.getHost().getBaseUrl();
Controller
e
package com.atlassian.connect.atlascamp;
@Controller
public class InceptionController {
private static final String PAGE_URL = "%s/rest/api/content/%s?expand=body.export_view";
private static final String JS_URL = "%s/atlassian-connect/all.js";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/inception-macro")
public String render(@RequestParam long pageId,
@AuthenticationPrincipal AtlassianHostUser hostUser, Model model) {
final String baseURL = hostUser.getHost().getBaseUrl();
final String contentUrl = String.format(PAGE_URL, baseURL, pageId);
final String pageContent = restTemplate.getForObject(contentUrl, String.class);
final String pageBody = extractPageBody(pageContent);
model.addAttribute("body", pageBody);
model.addAttribute("jsurl", String.format(JS_URL, baseURL));
return "inception-macro";
}
final String pageContent = restTemplate.getForObject(contentUrl, String.class);
final String pageBody = extractPageBody(pageContent);
Controller
e
package com.atlassian.connect.atlascamp;
@Controller
public class InceptionController {
private static final String PAGE_URL = "%s/rest/api/content/%s?expand=body.export_view";
private static final String JS_URL = "%s/atlassian-connect/all.js";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/inception-macro")
public String render(@RequestParam long pageId,
@AuthenticationPrincipal AtlassianHostUser hostUser, Model model) {
final String baseURL = hostUser.getHost().getBaseUrl();
final String contentUrl = String.format(PAGE_URL, baseURL, pageId);
final String pageContent = restTemplate.getForObject(contentUrl, String.class);
final String pageBody = extractPageBody(pageContent);
model.addAttribute("body", pageBody);
model.addAttribute("jsurl", String.format(JS_URL, baseURL));
return "inception-macro";
}
model.addAttribute("body", pageBody);
model.addAttribute("jsurl", String.format(JS_URL, baseURL));
return "inception-macro";
Secure
e
$> mvn spring-boot:run
Secure
e
$> mvn spring-boot:run
$> curl http://localhost:8080/inception-macro
401
Install
e
$> npm install -g ngrok
$> ngrok http 8080
Forwarding https://1c12a2cd.ngrok.io -> localhost:8080
Install
$> mvn spring-boot:run
$> curl http://localhost:8080/inception-macro
401
Install
$> mvn spring-boot:run
$> curl http://localhost:8080/inception-macro
401
Inception
Inception
Executed requests
e
HTTP Requests
-------------
GET /inception-macro 200 OK
POST /installed 204 No Content
GET /atlassian-connect.json 200 OK
http://go.atlassian.com/inception
Connecting Atlassian Connect with Spring Boot
Why again?
Leverage skills Fast DRY Care free Connect
VINCENT KOK • DEVELOPMENT MANAGER • ATLASSIAN • @VINCENTKOK
Thank you!
Ad

More Related Content

What's hot (20)

Spring Boot
Spring BootSpring Boot
Spring Boot
HongSeong Jeon
 
Introduction to Spring's Dependency Injection
Introduction to Spring's Dependency InjectionIntroduction to Spring's Dependency Injection
Introduction to Spring's Dependency Injection
Richard Paul
 
Spring Boot Interview Questions | Edureka
Spring Boot Interview Questions | EdurekaSpring Boot Interview Questions | Edureka
Spring Boot Interview Questions | Edureka
Edureka!
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
Joshua Long
 
Selenium Concepts
Selenium ConceptsSelenium Concepts
Selenium Concepts
Swati Bansal
 
Xke spring boot
Xke spring bootXke spring boot
Xke spring boot
sourabh aggarwal
 
Spring Boot
Spring BootSpring Boot
Spring Boot
Jiayun Zhou
 
Spring Boot & Actuators
Spring Boot & ActuatorsSpring Boot & Actuators
Spring Boot & Actuators
VMware Tanzu
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
Jakub Kubrynski
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot Introduction
Jeevesh Pandey
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UK
José Paumard
 
Introduction to Maven
Introduction to MavenIntroduction to Maven
Introduction to Maven
Onkar Deshpande
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
Alex Movila
 
Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introduction
Jonathan Holloway
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
07.pallav
 
Introduction to Protractor
Introduction to ProtractorIntroduction to Protractor
Introduction to Protractor
Florian Fesseler
 
Mockito a simple, intuitive mocking framework
Mockito   a simple, intuitive mocking frameworkMockito   a simple, intuitive mocking framework
Mockito a simple, intuitive mocking framework
Phat VU
 
Introduction to spring boot
Introduction to spring bootIntroduction to spring boot
Introduction to spring boot
Santosh Kumar Kar
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
guest11106b
 
Spring boot
Spring bootSpring boot
Spring boot
Pradeep Shanmugam
 
Introduction to Spring's Dependency Injection
Introduction to Spring's Dependency InjectionIntroduction to Spring's Dependency Injection
Introduction to Spring's Dependency Injection
Richard Paul
 
Spring Boot Interview Questions | Edureka
Spring Boot Interview Questions | EdurekaSpring Boot Interview Questions | Edureka
Spring Boot Interview Questions | Edureka
Edureka!
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
Joshua Long
 
Spring Boot & Actuators
Spring Boot & ActuatorsSpring Boot & Actuators
Spring Boot & Actuators
VMware Tanzu
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
Jakub Kubrynski
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot Introduction
Jeevesh Pandey
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UK
José Paumard
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
Alex Movila
 
Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introduction
Jonathan Holloway
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
07.pallav
 
Introduction to Protractor
Introduction to ProtractorIntroduction to Protractor
Introduction to Protractor
Florian Fesseler
 
Mockito a simple, intuitive mocking framework
Mockito   a simple, intuitive mocking frameworkMockito   a simple, intuitive mocking framework
Mockito a simple, intuitive mocking framework
Phat VU
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
guest11106b
 

Similar to Connecting Connect with Spring Boot (20)

Spring Live Sample Chapter
Spring Live Sample ChapterSpring Live Sample Chapter
Spring Live Sample Chapter
Syed Shahul
 
Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0
Steven Smith
 
Session 3 - SPRING BOOT - Accessing Actuator EndPoint.pptx
Session 3 - SPRING BOOT - Accessing Actuator EndPoint.pptxSession 3 - SPRING BOOT - Accessing Actuator EndPoint.pptx
Session 3 - SPRING BOOT - Accessing Actuator EndPoint.pptx
trainingdecorpo
 
JavaDo#09 Spring boot入門ハンズオン
JavaDo#09 Spring boot入門ハンズオンJavaDo#09 Spring boot入門ハンズオン
JavaDo#09 Spring boot入門ハンズオン
haruki ueno
 
Play Support in Cloud Foundry
Play Support in Cloud FoundryPlay Support in Cloud Foundry
Play Support in Cloud Foundry
rajdeep
 
2-0. Spring ecosytem.pdf
2-0. Spring ecosytem.pdf2-0. Spring ecosytem.pdf
2-0. Spring ecosytem.pdf
DeoDuaNaoHet
 
Spring MVC 5 & Hibernate 5 Integration
Spring MVC 5 & Hibernate 5 IntegrationSpring MVC 5 & Hibernate 5 Integration
Spring MVC 5 & Hibernate 5 Integration
Majurageerthan Arumugathasan
 
Initiation the Java web application project in the Google App Engine
Initiation the Java web application project in the Google App EngineInitiation the Java web application project in the Google App Engine
Initiation the Java web application project in the Google App Engine
University of Economics in Katowice
 
Spring Bootを触ってみた
Spring Bootを触ってみたSpring Bootを触ってみた
Spring Bootを触ってみた
onozaty
 
FullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + AngularFullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + Angular
Loiane Groner
 
Spring MVC 5 & Hibernate 5 Integration.pdf
Spring MVC 5 & Hibernate 5 Integration.pdfSpring MVC 5 & Hibernate 5 Integration.pdf
Spring MVC 5 & Hibernate 5 Integration.pdf
Patiento Del Mar
 
Comparing Native Java REST API Frameworks - Seattle JUG 2022
Comparing Native Java REST API Frameworks - Seattle JUG 2022Comparing Native Java REST API Frameworks - Seattle JUG 2022
Comparing Native Java REST API Frameworks - Seattle JUG 2022
Matt Raible
 
Webpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San FranciscoWebpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San Francisco
Ryan Weaver
 
Maven
MavenMaven
Maven
Shraddha
 
RichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesRichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile Devices
Pavol Pitoňák
 
Enterprise Build And Test In The Cloud
Enterprise Build And Test In The CloudEnterprise Build And Test In The Cloud
Enterprise Build And Test In The Cloud
Carlos Sanchez
 
Building a Spring Boot Application - Ask the Audience!
Building a Spring Boot Application - Ask the Audience!Building a Spring Boot Application - Ask the Audience!
Building a Spring Boot Application - Ask the Audience!
🎤 Hanno Embregts 🎸
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoas
Zeid Hassan
 
20130528 solution linux_frousseau_nopain_webdev
20130528 solution linux_frousseau_nopain_webdev20130528 solution linux_frousseau_nopain_webdev
20130528 solution linux_frousseau_nopain_webdev
Frank Rousseau
 
Maven
MavenMaven
Maven
feng lee
 
Spring Live Sample Chapter
Spring Live Sample ChapterSpring Live Sample Chapter
Spring Live Sample Chapter
Syed Shahul
 
Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0
Steven Smith
 
Session 3 - SPRING BOOT - Accessing Actuator EndPoint.pptx
Session 3 - SPRING BOOT - Accessing Actuator EndPoint.pptxSession 3 - SPRING BOOT - Accessing Actuator EndPoint.pptx
Session 3 - SPRING BOOT - Accessing Actuator EndPoint.pptx
trainingdecorpo
 
JavaDo#09 Spring boot入門ハンズオン
JavaDo#09 Spring boot入門ハンズオンJavaDo#09 Spring boot入門ハンズオン
JavaDo#09 Spring boot入門ハンズオン
haruki ueno
 
Play Support in Cloud Foundry
Play Support in Cloud FoundryPlay Support in Cloud Foundry
Play Support in Cloud Foundry
rajdeep
 
2-0. Spring ecosytem.pdf
2-0. Spring ecosytem.pdf2-0. Spring ecosytem.pdf
2-0. Spring ecosytem.pdf
DeoDuaNaoHet
 
Initiation the Java web application project in the Google App Engine
Initiation the Java web application project in the Google App EngineInitiation the Java web application project in the Google App Engine
Initiation the Java web application project in the Google App Engine
University of Economics in Katowice
 
Spring Bootを触ってみた
Spring Bootを触ってみたSpring Bootを触ってみた
Spring Bootを触ってみた
onozaty
 
FullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + AngularFullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + Angular
Loiane Groner
 
Spring MVC 5 & Hibernate 5 Integration.pdf
Spring MVC 5 & Hibernate 5 Integration.pdfSpring MVC 5 & Hibernate 5 Integration.pdf
Spring MVC 5 & Hibernate 5 Integration.pdf
Patiento Del Mar
 
Comparing Native Java REST API Frameworks - Seattle JUG 2022
Comparing Native Java REST API Frameworks - Seattle JUG 2022Comparing Native Java REST API Frameworks - Seattle JUG 2022
Comparing Native Java REST API Frameworks - Seattle JUG 2022
Matt Raible
 
Webpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San FranciscoWebpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San Francisco
Ryan Weaver
 
RichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesRichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile Devices
Pavol Pitoňák
 
Enterprise Build And Test In The Cloud
Enterprise Build And Test In The CloudEnterprise Build And Test In The Cloud
Enterprise Build And Test In The Cloud
Carlos Sanchez
 
Building a Spring Boot Application - Ask the Audience!
Building a Spring Boot Application - Ask the Audience!Building a Spring Boot Application - Ask the Audience!
Building a Spring Boot Application - Ask the Audience!
🎤 Hanno Embregts 🎸
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoas
Zeid Hassan
 
20130528 solution linux_frousseau_nopain_webdev
20130528 solution linux_frousseau_nopain_webdev20130528 solution linux_frousseau_nopain_webdev
20130528 solution linux_frousseau_nopain_webdev
Frank Rousseau
 
Ad

More from Vincent Kok (14)

Tales of modernizing trello's web stack
Tales of modernizing trello's web stackTales of modernizing trello's web stack
Tales of modernizing trello's web stack
Vincent Kok
 
Why you're failing your remote workers - DWSC18
Why you're failing your remote workers - DWSC18Why you're failing your remote workers - DWSC18
Why you're failing your remote workers - DWSC18
Vincent Kok
 
Microservices 5 things i wish i'd known java with the best 2018
Microservices 5 things i wish i'd known   java with the best 2018Microservices 5 things i wish i'd known   java with the best 2018
Microservices 5 things i wish i'd known java with the best 2018
Vincent Kok
 
Dev opstalks 2018 releasing the monolith on a daily basis
Dev opstalks 2018   releasing the monolith on a daily basisDev opstalks 2018   releasing the monolith on a daily basis
Dev opstalks 2018 releasing the monolith on a daily basis
Vincent Kok
 
Microservices: 5 Things I Wish I'd Known - Code Motion Milan 2017
Microservices: 5 Things I Wish I'd Known - Code Motion Milan 2017Microservices: 5 Things I Wish I'd Known - Code Motion Milan 2017
Microservices: 5 Things I Wish I'd Known - Code Motion Milan 2017
Vincent Kok
 
Microservices 5 Things I Wish I'd Known - JFall 2017
Microservices 5 Things I Wish I'd Known - JFall 2017Microservices 5 Things I Wish I'd Known - JFall 2017
Microservices 5 Things I Wish I'd Known - JFall 2017
Vincent Kok
 
Need to-know patterns building microservices - java one
Need to-know patterns building microservices - java oneNeed to-know patterns building microservices - java one
Need to-know patterns building microservices - java one
Vincent Kok
 
Microservices 5 things i wish i'd known code motion
Microservices 5 things i wish i'd known   code motionMicroservices 5 things i wish i'd known   code motion
Microservices 5 things i wish i'd known code motion
Vincent Kok
 
Releasing the monolith on a daily basis - CodeMash
Releasing the monolith on a daily basis - CodeMashReleasing the monolith on a daily basis - CodeMash
Releasing the monolith on a daily basis - CodeMash
Vincent Kok
 
Confluence of Broken Windows JavaOne 2016
Confluence of Broken Windows JavaOne 2016Confluence of Broken Windows JavaOne 2016
Confluence of Broken Windows JavaOne 2016
Vincent Kok
 
Microservices 5 things i wish i'd known - The MeetUp edition
Microservices 5 things i wish i'd known - The MeetUp edition  Microservices 5 things i wish i'd known - The MeetUp edition
Microservices 5 things i wish i'd known - The MeetUp edition
Vincent Kok
 
Microservices 5 things i wish i'd known
Microservices 5 things i wish i'd knownMicroservices 5 things i wish i'd known
Microservices 5 things i wish i'd known
Vincent Kok
 
Irina Winterreis 2011
Irina Winterreis 2011Irina Winterreis 2011
Irina Winterreis 2011
Vincent Kok
 
Irina Winterreis 2011
Irina Winterreis 2011Irina Winterreis 2011
Irina Winterreis 2011
Vincent Kok
 
Tales of modernizing trello's web stack
Tales of modernizing trello's web stackTales of modernizing trello's web stack
Tales of modernizing trello's web stack
Vincent Kok
 
Why you're failing your remote workers - DWSC18
Why you're failing your remote workers - DWSC18Why you're failing your remote workers - DWSC18
Why you're failing your remote workers - DWSC18
Vincent Kok
 
Microservices 5 things i wish i'd known java with the best 2018
Microservices 5 things i wish i'd known   java with the best 2018Microservices 5 things i wish i'd known   java with the best 2018
Microservices 5 things i wish i'd known java with the best 2018
Vincent Kok
 
Dev opstalks 2018 releasing the monolith on a daily basis
Dev opstalks 2018   releasing the monolith on a daily basisDev opstalks 2018   releasing the monolith on a daily basis
Dev opstalks 2018 releasing the monolith on a daily basis
Vincent Kok
 
Microservices: 5 Things I Wish I'd Known - Code Motion Milan 2017
Microservices: 5 Things I Wish I'd Known - Code Motion Milan 2017Microservices: 5 Things I Wish I'd Known - Code Motion Milan 2017
Microservices: 5 Things I Wish I'd Known - Code Motion Milan 2017
Vincent Kok
 
Microservices 5 Things I Wish I'd Known - JFall 2017
Microservices 5 Things I Wish I'd Known - JFall 2017Microservices 5 Things I Wish I'd Known - JFall 2017
Microservices 5 Things I Wish I'd Known - JFall 2017
Vincent Kok
 
Need to-know patterns building microservices - java one
Need to-know patterns building microservices - java oneNeed to-know patterns building microservices - java one
Need to-know patterns building microservices - java one
Vincent Kok
 
Microservices 5 things i wish i'd known code motion
Microservices 5 things i wish i'd known   code motionMicroservices 5 things i wish i'd known   code motion
Microservices 5 things i wish i'd known code motion
Vincent Kok
 
Releasing the monolith on a daily basis - CodeMash
Releasing the monolith on a daily basis - CodeMashReleasing the monolith on a daily basis - CodeMash
Releasing the monolith on a daily basis - CodeMash
Vincent Kok
 
Confluence of Broken Windows JavaOne 2016
Confluence of Broken Windows JavaOne 2016Confluence of Broken Windows JavaOne 2016
Confluence of Broken Windows JavaOne 2016
Vincent Kok
 
Microservices 5 things i wish i'd known - The MeetUp edition
Microservices 5 things i wish i'd known - The MeetUp edition  Microservices 5 things i wish i'd known - The MeetUp edition
Microservices 5 things i wish i'd known - The MeetUp edition
Vincent Kok
 
Microservices 5 things i wish i'd known
Microservices 5 things i wish i'd knownMicroservices 5 things i wish i'd known
Microservices 5 things i wish i'd known
Vincent Kok
 
Irina Winterreis 2011
Irina Winterreis 2011Irina Winterreis 2011
Irina Winterreis 2011
Vincent Kok
 
Irina Winterreis 2011
Irina Winterreis 2011Irina Winterreis 2011
Irina Winterreis 2011
Vincent Kok
 
Ad

Recently uploaded (20)

Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven InsightsAndrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
TrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business ConsultingTrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business Consulting
Trs Labs
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Build Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For DevsBuild Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For Devs
Brian McKeiver
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven InsightsAndrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
TrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business ConsultingTrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business Consulting
Trs Labs
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Build Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For DevsBuild Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For Devs
Brian McKeiver
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 

Connecting Connect with Spring Boot