simple rest-apis with dropwizard and swagger
TRANSCRIPT
![Page 1: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/1.jpg)
SimpleREST-APIswithDropwizard andSwagger
BerndSchönbachLeanIX GmbH
@boernd_s
![Page 2: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/2.jpg)
Motivation
2REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
- QuicklycreateREST-APIs
- Makethemtestable
- Makethemdeployablewithaclick
- Orevenbetterautomatically
- ProvideDocumentationwithoutMSOffice
- ProvideSDKwithnoextraactionneeded
![Page 3: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/3.jpg)
Overview
3REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Introduction• Aboutme• AboutLeanIX
Dropwizard• SetUp/BasicFeatures• Demo• AdvancedFeatures
Swagger+SwaggerUI• SetUp/BasicFeatures• Demo• AdvancedFeatures
![Page 4: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/4.jpg)
Introduction
![Page 5: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/5.jpg)
Aboutme
5REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
EnvironmentBernd Schönbach
• Est.:1982• FirstLanguage:PHP(2001)• SecondLanguage:Java(2010)• Java-Dev. @leanIX:2015-
![Page 6: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/6.jpg)
LeanIXwasborn,since pragmatic solutions forITArchitecture Managementdid notexist
6REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
JörgG.Beyer AndréChrist
Management-Team&FounderLeanIX GmbH
• Headquarter:Bonn• Founded:01/2012• Launch:08/2012
• 4yearsManagementConsulting@DHL
• 8yearsFreelancerSoftwareDesign&Architecture
• Speaker&AuthorforSoftwareArchitecture
• 10yearsITLeadership@DHL,e.g.globalCIO
• 4yearsMDfornewlyestablishedITManagementConsulting
• 10yearsConsulting:Andersen&self-employed
![Page 7: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/7.jpg)
LeanIXhelpscompaniestomanageandoptimizetheirITArchitectures
7REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Current ITArchitecture CreateTransparency Optimize ITArchitecture
• Missinginformation(e.g.interfaces,technologies)
• Hardtointroducenewproducts&saleschannels
• Highcostsandrisks
• ImportexistingdataintoLeanIX(viaExcelorAPI)
• Inviteexpertstosharetheirknowledge
• Usebest-practicereportstoidentifyissues
• Definetargetarchitectureandroadmaps
Learn more: https://www.leanix.net/en/product/index
![Page 8: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/8.jpg)
LeanIXisaweb-basedplatformtocaptureandshareknowledgeaboutIT
8REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
FactSheets&Tagging
Context-basedSearch
API,Import&Export
Comments&Threads
ITInventory CollaborationPlatform InteractiveReporting
ActivityStream&Notifications
Subscriptions
Print&Export(PDF)
BestPracticeReports
InteractiveAdaption
Learn more: https://www.leanix.net/en/product/index
![Page 9: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/9.jpg)
Marketleading companies already use LeanIX
9
Media
Insurance
Industry
e-Commerce
Telecoms
Chemical
Advisory
Government
Manufacturing
Logistics
Education
Health
Energy
See more: https://www.leanix.net/en/customers/index
![Page 10: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/10.jpg)
Dropwizard
![Page 11: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/11.jpg)
Dropwizard
11REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
LiveDemo
Overview
Whatisit?
TheBasics
Advanced Features
• JavaFrameworkfor RESTful WebServices
• QuickStartup(few seconds)
• Completely configurable
• Current Version:0.9.2(we willbe using 0.9.1)
![Page 12: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/12.jpg)
Dropwizard
12REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
LiveDemo
Overview
Whatisit?
TheBasics
Advanced Features
• FrameworkContents:• Jetty for HTTP• Jerseyfor REST• Jacksonfor JSONtransformation• Hibernate for DBAccess
•Otherusefull inclusions•Metrics• Liquibase• Slf4jand Logback• and much more...
![Page 13: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/13.jpg)
Dropwizard
13REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
FirstSteps:
Whatisit?
TheBasics
Advanced Features
• CreateMavenProject
• Adddependencytodropwizard
• ConfigureMavenShadePlugin
• Addconfigurationfile(optional)
• Startcoding
![Page 14: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/14.jpg)
Dropwizard
14REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Adddependency to pom.xmlStandardway (dropwizard only)
Whatisit?
TheBasics
Advanced Features
<properties><dropwizard.version>0.9.1</dropwizard.version></properties>
Step1:
Step2:
<dependencies><dependency><groupId>io.dropwizard</groupId><artifactId>dropwizard-core</artifactId><version>${dropwizard.version}</version></dependency></dependencies>
![Page 15: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/15.jpg)
Dropwizard
15REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Adddependency to pom.xmlOur way (Swagger &Dropwizard together)
Whatisit?
TheBasics
Advanced Features
<properties><dropwizard.version>0.9.1-1</dropwizard.version></properties>
Step1:
Step2:
<dependencies><dependency><groupId>com.smoketurner</groupId><artifactId>dropwizard-swagger</artifactId><version>${dropwizard.version}</version></dependency></dependencies>
![Page 16: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/16.jpg)
Dropwizard
16REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Configure Maven Shade Plugin
Whatisit?
TheBasics
Advanced Features
<plugin><artifactId>maven-shade-plugin</artifactId><version>2.4.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration combine.children="append"><createDependencyReducedPom>true</createDependencyReducedPom><outputFile>target/voxxed-test.jar</outputFile>[...]</configuration></execution></executions></plugin>
![Page 17: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/17.jpg)
Let’scode!
![Page 18: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/18.jpg)
Dropwizard
18REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Configure your Application
Whatisit?
TheBasics
Advanced Features
config.yml
server:applicationConnectors:type: httpport: 1337
adminConnectors:type: httpport: $env:ADMIN_PORT:1338
Logging:level: INFOFooBar: Value
![Page 19: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/19.jpg)
Dropwizard
19REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Resource Methods and Paths
Whatisit?
TheBasics
Advanced Features
@Path(“persons”)public class PersonResource {
@GETpublic String getPersons () {[…]}
@PUTpublic StringupdatePerson(){[…]}
@POSTpublic StringcreatePerson(){[…]}
@DELETEpublic StringdeletePerson(){[…]}
URL:localhost:1337/persons
@GET@Path("/address"}public StringgetPersonAddress(){[…]}
URL:localhost:1337/persons/address
![Page 20: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/20.jpg)
Dropwizard
20REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Queryand PathParams
Whatisit?
TheBasics
Advanced Features
Task1:SearchanEntity.URL:http://localhost:1337/persons?name=adam
Task2:RetrieveanEntity:URL:http://localhost:1337/persons/1234/
QueryParameterspublic class PersonResource {@GETpublic String getPerson(@QueryParam(“name”) String name) {[…]}
PathParameterspublic class PersonResource {@GET@Path(“/{id}”)public String getPersonById(@PathParam(“id”) String id) {[…]}
![Page 21: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/21.jpg)
Dropwizard
21REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
ResponseTypes
Whatisit?
TheBasics
Advanced Features
ReturnandretrieveJSON
@Produces(MediaType.APPLICATION_JSON)@Consumes(MediaType.APPLICATION_JSON)public class PersonResource {
@GETpublic String getPerson (@QueryParam(“name”) String name) {[…]}
@Produces(MediaType.APPLICATION_JSON)@Consumes(MediaType.APPLICATION_JSON)public class PersonResource {
@GETpublic String getPerson (@QueryParam(“name”) String name) {[…]}
@GET@Path(“xml”)@Produces(MediaType.APPLICATION_XML)public String getPersonXml (){[…]}
![Page 22: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/22.jpg)
Dropwizard
22REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Whatisit?
TheBasics
Advanced Features
AdvancedFeatures
- HATEOAS
- ValidatorsandDefaultsforQueryParameters
- AuthenticationHandling
![Page 23: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/23.jpg)
Dropwizard
23REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Pimping your Response(HATEOAS)
- AddMetaInformationtoResponseData
- ProvideLinkstoallowautomatedtraversal(bymachines)
{data:[{…},…,{…}]size:10total:150links:{next:“/persons/page=2&limit=10”,current:“/persons/page=1&limit=10”,previous:null}}
Whatisit?
TheBasics
Advanced Features
![Page 24: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/24.jpg)
Dropwizard
24REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Pimping your Response(HATEOAS)ResponseObjects
Whatisit?
TheBasics
Advanced Features
public class BasicResponse {protected ResponseStatus status = ResponseStatus.OK;protected String type;protected Stringmessage;protected Long total;[…]}
public class PersonResponse extends BasicResponse {protected Persondata;protected Linkslinks;
public class Links{protected String next;protected String previous;protected String current;}}
![Page 25: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/25.jpg)
Dropwizard
25REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Pimping your Response(HATEOAS)OptionB:JerseyLinks
Whatisit?
TheBasics
Advanced Features
public void run(AppConfig conf,Environmentenv)throws Ex{environment.jersey().getResourceConfig().packages(getClass().getPackage().getName()).register(DeclarativeLinkingFeature.class);
}
App.java
- Adddependencytojersey-server-linking- RegisterinrunfunctionofApp.java- Add@Linkor@RefAnnotations
ForfurtherInformationsee:https://jersey.java.net/documentation/1.19/linking.html
![Page 26: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/26.jpg)
Dropwizard
26REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Validators and DefaultsforQueryParameters
Whatisit?
TheBasics
Advanced Features
public class PersonResource {
@GETpublic String getPerson (@QueryParam(“name”) String name) {[…]}
public class PersonResource {
@GETpublic String getPerson (@QueryParam(“name”) @NotEmpty String name) {[…]}
Validating:
SuppliedbyHibernateValidator
@NotNull@Min(Integer);@Max(Integer)@Size(min=Integer,max=Integer)
@Future,@Past@Pattern(regex=String)
@Valid
![Page 27: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/27.jpg)
Dropwizard
27REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
AuthenticationHandling
Whatisit?
TheBasics
Advanced Features
Step1:CreateAuthenticationProvider:
public class ExampleAuthenticator implementsAuthenticator<BasicCredentials,User>{@Overridepublic Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException{if ("secret".equals(credentials.getPassword())) {return Optional.of(new User(credentials.getUsername()));}return Optional.absent();}}
![Page 28: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/28.jpg)
Dropwizard
28REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
AuthenticationHandling
Whatisit?
TheBasics
Advanced Features
Step2:RegisterAuthenticationProvider:
public void run(AppConfig conf,Environmentenv)throws Ex{environment.jersey().register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>().setAuthenticator(new ExampleAuthenticator()).setRealm("SUPERSECRETSTUFF") .buildAuthFilter()
));environment.jersey().register(RolesAllowedDynamicFeature.class);environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));}
![Page 29: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/29.jpg)
Dropwizard
29REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
AuthenticationHandling
Whatisit?
TheBasics
Advanced Features
Step3:UseAuth Parameter:
public class PersonResource {@GETpublic String getPerson (@QueryParam(“name”) @NotEmpty String name,@Auth Userauth ){[…]}}
![Page 30: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/30.jpg)
Swagger+
SwaggerUI
![Page 31: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/31.jpg)
Swagger
31REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
Swagger +Swagger UI
Whatisit?
TheBasics
Advanced Features
- SimpledocumentationforRESTAPIs
- AllowsautomaticSDKGeneration
- NiceandinteractiveUserInterface
![Page 32: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/32.jpg)
32
![Page 33: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/33.jpg)
Swagger Workflow
33REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
JSONSpecification
HTMLAPIUI
SDKGeneration
CodeAnnotation
![Page 34: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/34.jpg)
Let’scode!
![Page 35: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/35.jpg)
Swagger
35REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
BasicAnnotations
Whatisit?
TheBasics
Advanced Features
@Api(“Description”)
@ApiResponse@ApiResponses
@ApiOperation(value=String,notes=String,response=Class,responseContainer =String)
@ApiParam()@DefaultValue(mixed)
![Page 36: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/36.jpg)
Swagger
36REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
BasicAnnotations
Whatisit?
TheBasics
Advanced Features
@ApiParam(name=String,value=String,
defaultValue =String,required=Boolean,
allowableValues =String,example=String,hidden=Boolean)
![Page 37: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/37.jpg)
Swagger
37REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
FurtherAnnotations
Whatisit?
TheBasics
Advanced Features
@ApiModel(value=String,description=String)
@ApiModelProperty(value=String,allowableValues=String)
@Contact
@License
![Page 38: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/38.jpg)
Swagger
38REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
LiveDemo
Advanced FeaturesSDKGeneration
Whatisit?
TheBasics
Advanced Features
Example for PHPand Java:https://github.com/leanix/swagger-demo-codegen
Configuration for that:https://goo.gl/plH6pB
![Page 39: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/39.jpg)
Thank you!
Learn More about LeanIX
Share on LinkedIn
http://bit.ly/LeanIXDemoS
Request free demohttp://bit.ly/LeanIXDemoS
![Page 40: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/40.jpg)
Questions?
![Page 41: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/41.jpg)
Sources
REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
• Dropwizard: http://www.dropwizard.io/
• Swagger: http://swagger.io/
• Swagger-UI: http://swagger.io/swagger-ui/
• HibernateValidator: http://hibernate.org/validator/
• Dropwizard SwaggerPackage: https://github.com/smoketurner/dropwizard-swagger
![Page 42: Simple REST-APIs with Dropwizard and Swagger](https://reader034.vdocuments.site/reader034/viewer/2022042520/586fdcdb1a28ab18428b667d/html5/thumbnails/42.jpg)
Slideswillbeavailableat
REST-APIswith Dropwizard &Swagger – VoxxedDays Berlin2016– BerndSchönbach– LeanIX GmbH
LeanIXWebsite:https://www.leanix.net/
LeanIXBlog:http://blog.leanix.net/
Slideshare:http://slideshare.net/leanIX_net/
Share on LinkedIn