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
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
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!

More Related Content

What's hot

Spring boot
Spring bootSpring boot
Spring boot
Pradeep Shanmugam
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
07.pallav
 
Xke spring boot
Xke spring bootXke spring boot
Xke spring boot
sourabh aggarwal
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
Joshua Long
 
Maven Introduction
Maven IntroductionMaven Introduction
Maven Introduction
Sandeep Chawla
 
Spring boot
Spring bootSpring boot
Spring boot
Bhagwat Kumar
 
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
Rasheed Waraich
 
Spring Boot
Spring BootSpring Boot
Spring Boot
Jiayun Zhou
 
An Introduction to Maven
An Introduction to MavenAn Introduction to Maven
An Introduction to MavenVadym Lotar
 
Postman & API Testing by Amber Race
Postman & API Testing by Amber RacePostman & API Testing by Amber Race
Postman & API Testing by Amber Race
Postman
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
Dzmitry Naskou
 
Spring User Guide
Spring User GuideSpring User Guide
Spring User Guide
Muthuselvam RS
 
Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)Gunith Devasurendra
 
Spring Boot & Actuators
Spring Boot & ActuatorsSpring Boot & Actuators
Spring Boot & Actuators
VMware Tanzu
 
Junit
JunitJunit
Spring boot
Spring bootSpring boot
Spring boot
Gyanendra Yadav
 
Spring Boot
Spring BootSpring Boot
Spring Boot
koppenolski
 
Spring Boot
Spring BootSpring Boot
Spring Boot
Jaydeep Kale
 
Postman
PostmanPostman

What's hot (20)

Spring boot
Spring bootSpring boot
Spring boot
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
 
Xke spring boot
Xke spring bootXke spring boot
Xke spring boot
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Maven Introduction
Maven IntroductionMaven Introduction
Maven Introduction
 
Spring boot
Spring bootSpring boot
Spring boot
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
An Introduction to Maven
An Introduction to MavenAn Introduction to Maven
An Introduction to Maven
 
Postman & API Testing by Amber Race
Postman & API Testing by Amber RacePostman & API Testing by Amber Race
Postman & API Testing by Amber Race
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
 
Spring User Guide
Spring User GuideSpring User Guide
Spring User Guide
 
Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)
 
Spring Boot & Actuators
Spring Boot & ActuatorsSpring Boot & Actuators
Spring Boot & Actuators
 
Junit
JunitJunit
Junit
 
Spring boot
Spring bootSpring boot
Spring boot
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Postman
PostmanPostman
Postman
 

Similar to Connecting Connect with Spring Boot

Spring Live Sample Chapter
Spring Live Sample ChapterSpring Live Sample Chapter
Spring Live Sample ChapterSyed 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
 
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
 
Running Microservices and Docker on AWS Elastic Beanstalk - August 2016 Month...
Running Microservices and Docker on AWS Elastic Beanstalk - August 2016 Month...Running Microservices and Docker on AWS Elastic Beanstalk - August 2016 Month...
Running Microservices and Docker on AWS Elastic Beanstalk - August 2016 Month...
Amazon Web Services
 
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
 
Running Microservices on AWS Elastic Beanstalk
Running Microservices on AWS Elastic BeanstalkRunning Microservices on AWS Elastic Beanstalk
Running Microservices on AWS Elastic Beanstalk
Amazon Web Services
 
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
 
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_webdevFrank Rousseau
 
Maven
MavenMaven
Maven
feng lee
 

Similar to Connecting Connect with Spring Boot (20)

Spring Live Sample Chapter
Spring Live Sample ChapterSpring Live Sample Chapter
Spring Live Sample Chapter
 
Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0
 
JavaDo#09 Spring boot入門ハンズオン
JavaDo#09 Spring boot入門ハンズオンJavaDo#09 Spring boot入門ハンズオン
JavaDo#09 Spring boot入門ハンズオン
 
Play Support in Cloud Foundry
Play Support in Cloud FoundryPlay Support in Cloud Foundry
Play Support in Cloud Foundry
 
2-0. Spring ecosytem.pdf
2-0. Spring ecosytem.pdf2-0. Spring ecosytem.pdf
2-0. Spring ecosytem.pdf
 
Running Microservices and Docker on AWS Elastic Beanstalk - August 2016 Month...
Running Microservices and Docker on AWS Elastic Beanstalk - August 2016 Month...Running Microservices and Docker on AWS Elastic Beanstalk - August 2016 Month...
Running Microservices and Docker on AWS Elastic Beanstalk - August 2016 Month...
 
Spring MVC 5 & Hibernate 5 Integration
Spring MVC 5 & Hibernate 5 IntegrationSpring MVC 5 & Hibernate 5 Integration
Spring MVC 5 & Hibernate 5 Integration
 
Running Microservices on AWS Elastic Beanstalk
Running Microservices on AWS Elastic BeanstalkRunning Microservices on AWS Elastic Beanstalk
Running Microservices on AWS Elastic Beanstalk
 
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
 
Spring Bootを触ってみた
Spring Bootを触ってみたSpring Bootを触ってみた
Spring Bootを触ってみた
 
FullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + AngularFullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + Angular
 
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
 
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
 
Maven
MavenMaven
Maven
 
RichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesRichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile Devices
 
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
 
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!
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoas
 
20130528 solution linux_frousseau_nopain_webdev
20130528 solution linux_frousseau_nopain_webdev20130528 solution linux_frousseau_nopain_webdev
20130528 solution linux_frousseau_nopain_webdev
 
Maven
MavenMaven
Maven
 

More from 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 knownVincent 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
 

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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
Confluence of Broken Windows JavaOne 2016
Confluence of Broken Windows JavaOne 2016Confluence of Broken Windows JavaOne 2016
Confluence of Broken Windows JavaOne 2016
 
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
 
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
 
Irina Winterreis 2011
Irina Winterreis 2011Irina Winterreis 2011
Irina Winterreis 2011
 
Irina Winterreis 2011
Irina Winterreis 2011Irina Winterreis 2011
Irina Winterreis 2011
 

Recently uploaded

From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 

Recently uploaded (20)

From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 

Connecting Connect with Spring Boot