(Go: >> BACK << -|- >> HOME <<)

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!

More Related Content

What's hot

Spring boot
Spring bootSpring boot
Spring boot
Gyanendra Yadav
 
Spring boot jpa
Spring boot jpaSpring boot jpa
Spring boot jpa
Hamid Ghorbani
 
Maven tutorial
Maven tutorialMaven tutorial
Maven tutorial
Dragos Balan
 
Introduction to angular with a simple but complete project
Introduction to angular with a simple but complete projectIntroduction to angular with a simple but complete project
Introduction to angular with a simple but complete project
Jadson Santos
 
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
 
Angular Dependency Injection
Angular Dependency InjectionAngular Dependency Injection
Angular Dependency Injection
Nir Kaufman
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
Joshua Long
 
Spring Boot
Spring BootSpring Boot
Spring Boot
Pei-Tang Huang
 
Angular 8
Angular 8 Angular 8
Angular 8
Sunil OS
 
Spring Boot Tutorial
Spring Boot TutorialSpring Boot Tutorial
Spring Boot Tutorial
Naphachara Rattanawilai
 
Spring User Guide
Spring User GuideSpring User Guide
Spring User Guide
Muthuselvam RS
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
Dzmitry Naskou
 
Spring boot
Spring bootSpring boot
Spring boot
Bhagwat Kumar
 
Spring Boot
Spring BootSpring Boot
Spring Boot
HongSeong Jeon
 
Selenium WebDriver
Selenium WebDriverSelenium WebDriver
Selenium WebDriver
Yuriy Bezgachnyuk
 
Angular modules in depth
Angular modules in depthAngular modules in depth
Angular modules in depth
Christoffer Noring
 
Selenium Maven With Eclipse | Edureka
Selenium Maven With Eclipse | EdurekaSelenium Maven With Eclipse | Edureka
Selenium Maven With Eclipse | Edureka
Edureka!
 
.Net Core
.Net Core.Net Core
.Net Core
Bertrand Le Roy
 
Angular 4 and TypeScript
Angular 4 and TypeScriptAngular 4 and TypeScript
Angular 4 and TypeScript
Ahmed El-Kady
 

What's hot (20)

Spring boot
Spring bootSpring boot
Spring boot
 
Spring boot jpa
Spring boot jpaSpring boot jpa
Spring boot jpa
 
Maven tutorial
Maven tutorialMaven tutorial
Maven tutorial
 
Introduction to angular with a simple but complete project
Introduction to angular with a simple but complete projectIntroduction to angular with a simple but complete project
Introduction to angular with a simple but complete project
 
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
 
Angular Dependency Injection
Angular Dependency InjectionAngular Dependency Injection
Angular Dependency Injection
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Angular 8
Angular 8 Angular 8
Angular 8
 
Spring Boot Tutorial
Spring Boot TutorialSpring Boot Tutorial
Spring Boot Tutorial
 
Spring User Guide
Spring User GuideSpring User Guide
Spring User Guide
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
 
Spring boot
Spring bootSpring boot
Spring boot
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Selenium WebDriver
Selenium WebDriverSelenium WebDriver
Selenium WebDriver
 
Angular modules in depth
Angular modules in depthAngular modules in depth
Angular modules in depth
 
Selenium Maven With Eclipse | Edureka
Selenium Maven With Eclipse | EdurekaSelenium Maven With Eclipse | Edureka
Selenium Maven With Eclipse | Edureka
 
.Net Core
.Net Core.Net Core
.Net Core
 
Angular 4 and TypeScript
Angular 4 and TypeScriptAngular 4 and TypeScript
Angular 4 and TypeScript
 

Similar to Connecting Connect with Spring Boot

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
 
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_webdev
Frank 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 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
 

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

K2G - Insurtech Innovation EMEA Award 2024
K2G - Insurtech Innovation EMEA Award 2024K2G - Insurtech Innovation EMEA Award 2024
K2G - Insurtech Innovation EMEA Award 2024
The Digital Insurer
 
The Increasing Use of the National Research Platform by the CSU Campuses
The Increasing Use of the National Research Platform by the CSU CampusesThe Increasing Use of the National Research Platform by the CSU Campuses
The Increasing Use of the National Research Platform by the CSU Campuses
Larry Smarr
 
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdfWhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
ArgaBisma
 
Transcript: Details of description part II: Describing images in practice - T...
Transcript: Details of description part II: Describing images in practice - T...Transcript: Details of description part II: Describing images in practice - T...
Transcript: Details of description part II: Describing images in practice - T...
BookNet Canada
 
this resume for sadika shaikh bca student
this resume for sadika shaikh bca studentthis resume for sadika shaikh bca student
this resume for sadika shaikh bca student
SadikaShaikh7
 
Performance Budgets for the Real World by Tammy Everts
Performance Budgets for the Real World by Tammy EvertsPerformance Budgets for the Real World by Tammy Everts
Performance Budgets for the Real World by Tammy Everts
ScyllaDB
 
Why do You Have to Redesign?_Redesign Challenge Day 1
Why do You Have to Redesign?_Redesign Challenge Day 1Why do You Have to Redesign?_Redesign Challenge Day 1
Why do You Have to Redesign?_Redesign Challenge Day 1
FellyciaHikmahwarani
 
STKI Israeli Market Study 2024 final v1
STKI Israeli Market Study 2024 final  v1STKI Israeli Market Study 2024 final  v1
STKI Israeli Market Study 2024 final v1
Dr. Jimmy Schwarzkopf
 
How Netflix Builds High Performance Applications at Global Scale
How Netflix Builds High Performance Applications at Global ScaleHow Netflix Builds High Performance Applications at Global Scale
How Netflix Builds High Performance Applications at Global Scale
ScyllaDB
 
Lessons Of Binary Analysis - Christien Rioux
Lessons Of Binary Analysis - Christien RiouxLessons Of Binary Analysis - Christien Rioux
Lessons Of Binary Analysis - Christien Rioux
crioux1
 
DealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 editionDealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 edition
Yevgen Sysoyev
 
Quality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of TimeQuality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of Time
Aurora Consulting
 
HTTP Adaptive Streaming – Quo Vadis (2024)
HTTP Adaptive Streaming – Quo Vadis (2024)HTTP Adaptive Streaming – Quo Vadis (2024)
HTTP Adaptive Streaming – Quo Vadis (2024)
Alpen-Adria-Universität
 
Observability For You and Me with OpenTelemetry
Observability For You and Me with OpenTelemetryObservability For You and Me with OpenTelemetry
Observability For You and Me with OpenTelemetry
Eric D. Schabell
 
How to Avoid Learning the Linux-Kernel Memory Model
How to Avoid Learning the Linux-Kernel Memory ModelHow to Avoid Learning the Linux-Kernel Memory Model
How to Avoid Learning the Linux-Kernel Memory Model
ScyllaDB
 
Pigging Solutions Sustainability brochure.pdf
Pigging Solutions Sustainability brochure.pdfPigging Solutions Sustainability brochure.pdf
Pigging Solutions Sustainability brochure.pdf
Pigging Solutions
 
Knowledge and Prompt Engineering Part 2 Focus on Prompt Design Approaches
Knowledge and Prompt Engineering Part 2 Focus on Prompt Design ApproachesKnowledge and Prompt Engineering Part 2 Focus on Prompt Design Approaches
Knowledge and Prompt Engineering Part 2 Focus on Prompt Design Approaches
Earley Information Science
 
5G bootcamp Sep 2020 (NPI initiative).pptx
5G bootcamp Sep 2020 (NPI initiative).pptx5G bootcamp Sep 2020 (NPI initiative).pptx
5G bootcamp Sep 2020 (NPI initiative).pptx
SATYENDRA100
 
Hire a private investigator to get cell phone records
Hire a private investigator to get cell phone recordsHire a private investigator to get cell phone records
Hire a private investigator to get cell phone records
HackersList
 
UiPath Community Day Kraków: Devs4Devs Conference
UiPath Community Day Kraków: Devs4Devs ConferenceUiPath Community Day Kraków: Devs4Devs Conference
UiPath Community Day Kraków: Devs4Devs Conference
UiPathCommunity
 

Recently uploaded (20)

K2G - Insurtech Innovation EMEA Award 2024
K2G - Insurtech Innovation EMEA Award 2024K2G - Insurtech Innovation EMEA Award 2024
K2G - Insurtech Innovation EMEA Award 2024
 
The Increasing Use of the National Research Platform by the CSU Campuses
The Increasing Use of the National Research Platform by the CSU CampusesThe Increasing Use of the National Research Platform by the CSU Campuses
The Increasing Use of the National Research Platform by the CSU Campuses
 
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdfWhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
 
Transcript: Details of description part II: Describing images in practice - T...
Transcript: Details of description part II: Describing images in practice - T...Transcript: Details of description part II: Describing images in practice - T...
Transcript: Details of description part II: Describing images in practice - T...
 
this resume for sadika shaikh bca student
this resume for sadika shaikh bca studentthis resume for sadika shaikh bca student
this resume for sadika shaikh bca student
 
Performance Budgets for the Real World by Tammy Everts
Performance Budgets for the Real World by Tammy EvertsPerformance Budgets for the Real World by Tammy Everts
Performance Budgets for the Real World by Tammy Everts
 
Why do You Have to Redesign?_Redesign Challenge Day 1
Why do You Have to Redesign?_Redesign Challenge Day 1Why do You Have to Redesign?_Redesign Challenge Day 1
Why do You Have to Redesign?_Redesign Challenge Day 1
 
STKI Israeli Market Study 2024 final v1
STKI Israeli Market Study 2024 final  v1STKI Israeli Market Study 2024 final  v1
STKI Israeli Market Study 2024 final v1
 
How Netflix Builds High Performance Applications at Global Scale
How Netflix Builds High Performance Applications at Global ScaleHow Netflix Builds High Performance Applications at Global Scale
How Netflix Builds High Performance Applications at Global Scale
 
Lessons Of Binary Analysis - Christien Rioux
Lessons Of Binary Analysis - Christien RiouxLessons Of Binary Analysis - Christien Rioux
Lessons Of Binary Analysis - Christien Rioux
 
DealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 editionDealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 edition
 
Quality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of TimeQuality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of Time
 
HTTP Adaptive Streaming – Quo Vadis (2024)
HTTP Adaptive Streaming – Quo Vadis (2024)HTTP Adaptive Streaming – Quo Vadis (2024)
HTTP Adaptive Streaming – Quo Vadis (2024)
 
Observability For You and Me with OpenTelemetry
Observability For You and Me with OpenTelemetryObservability For You and Me with OpenTelemetry
Observability For You and Me with OpenTelemetry
 
How to Avoid Learning the Linux-Kernel Memory Model
How to Avoid Learning the Linux-Kernel Memory ModelHow to Avoid Learning the Linux-Kernel Memory Model
How to Avoid Learning the Linux-Kernel Memory Model
 
Pigging Solutions Sustainability brochure.pdf
Pigging Solutions Sustainability brochure.pdfPigging Solutions Sustainability brochure.pdf
Pigging Solutions Sustainability brochure.pdf
 
Knowledge and Prompt Engineering Part 2 Focus on Prompt Design Approaches
Knowledge and Prompt Engineering Part 2 Focus on Prompt Design ApproachesKnowledge and Prompt Engineering Part 2 Focus on Prompt Design Approaches
Knowledge and Prompt Engineering Part 2 Focus on Prompt Design Approaches
 
5G bootcamp Sep 2020 (NPI initiative).pptx
5G bootcamp Sep 2020 (NPI initiative).pptx5G bootcamp Sep 2020 (NPI initiative).pptx
5G bootcamp Sep 2020 (NPI initiative).pptx
 
Hire a private investigator to get cell phone records
Hire a private investigator to get cell phone recordsHire a private investigator to get cell phone records
Hire a private investigator to get cell phone records
 
UiPath Community Day Kraków: Devs4Devs Conference
UiPath Community Day Kraków: Devs4Devs ConferenceUiPath Community Day Kraków: Devs4Devs Conference
UiPath Community Day Kraków: Devs4Devs Conference
 

Connecting Connect with Spring Boot