Add 'ldap-odm' sample

See gh-91
This commit is contained in:
Marcus Da Coregio
2022-08-15 13:59:16 -03:00
committed by Stephane Nicoll
parent b646d3e2cb
commit 2b450d6e8c
12 changed files with 446 additions and 0 deletions

View File

@@ -39,6 +39,7 @@ smoke_tests:
- jdbc-mariadb
- jdbc-mysql
- jdbc-postgresql
- ldap-odm
- liquibase
- logging-log4j2
- logging-logback

27
ldap-odm/build.gradle Normal file
View File

@@ -0,0 +1,27 @@
plugins {
id 'java'
id 'org.springframework.boot'
id 'org.springframework.aot.smoke-test'
id 'org.graalvm.buildtools.native'
}
apply plugin: "org.springframework.boot.aot"
dependencies {
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.ldap:spring-ldap-core")
implementation("com.unboundid:unboundid-ldapsdk")
testImplementation("org.springframework.boot:spring-boot-starter-test")
aotTestImplementation(project(":aot-smoke-test-support"))
}
aotSmokeTest {
webApplication = true
}
test {
useJUnitPlatform()
}

View File

@@ -0,0 +1,71 @@
package example.ldap.odm;
import org.junit.jupiter.api.Test;
import org.springframework.aot.smoketest.support.junit.AotSmokeTest;
import org.springframework.test.web.reactive.server.WebTestClient;
@AotSmokeTest
public class LdapOdmApplicationTests {
@Test
void shouldFindAllPeople(WebTestClient client) {
client.get().uri("/person").exchange().expectBody().json("""
[
{
"company": "company1",
"country": "Sweden",
"description": "Sweden, Company1, Some Person",
"fullName": "Some Person",
"lastName": "Person",
"phone": "+46 555-123456"
},
{
"company": "company1",
"country": "Sweden",
"description": "Sweden, Company1, Some Person2",
"fullName": "Some Person2",
"lastName": "Person2",
"phone": "+46 555-654321"
}
]
""");
}
@Test
void shouldFindPerson(WebTestClient client) {
// @formatter:off
client.get().uri((builder) -> builder.path("/person")
.queryParam("country", "Sweden")
.queryParam("company", "company1")
.queryParam("fullName", "Some Person2").build()
).exchange().expectBody().json("""
{
"company": "company1",
"country": "Sweden",
"description": "Sweden, Company1, Some Person2",
"fullName": "Some Person2",
"lastName": "Person2",
"phone": "+46 555-654321"
}
""");
// @formatter:on
}
@Test
void shouldAddNewPerson(WebTestClient client) {
client.post().uri("/person").exchange().expectStatus().isOk();
}
@Test
void shouldDeletePerson(WebTestClient client) {
// @formatter:off
client.delete().uri((builder) -> builder.path("/person")
.queryParam("country", "Sweden")
.queryParam("company", "company1")
.queryParam("fullName", "Some Person2").build()
).exchange().expectStatus().isOk();
// @formatter:on
}
}

View File

@@ -0,0 +1,29 @@
package example.ldap.odm;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportRuntimeHints;
@SpringBootApplication
@ImportRuntimeHints(LdapOdmApplication.Hints.class)
public class LdapOdmApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(LdapOdmApplication.class, args);
Thread.currentThread().join(); // To be able to measure memory consumption
}
static class Hints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
// TODO Should this be in Spring Boot?
// https://github.com/spring-projects/spring-boot/issues/32084
hints.resources().registerPattern(".*.ldif");
}
}
}

View File

@@ -0,0 +1,46 @@
package example.ldap.odm;
import java.util.List;
import javax.naming.ldap.LdapName;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.support.LdapNameBuilder;
import org.springframework.stereotype.Repository;
@Repository
public class OdmPersonDaoImpl implements PersonDao {
private final LdapTemplate ldapTemplate;
public OdmPersonDaoImpl(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
@Override
public void create(Person person) {
this.ldapTemplate.create(person);
}
@Override
public void delete(Person person) {
this.ldapTemplate.delete(person);
}
@Override
public List<Person> findAll() {
return this.ldapTemplate.findAll(Person.class);
}
@Override
public Person findByPrimaryKey(String country, String company, String fullName) {
LdapName dn = buildDn(country, company, fullName);
return this.ldapTemplate.findByDn(dn, Person.class);
}
private LdapName buildDn(String country, String company, String fullname) {
return LdapNameBuilder.newInstance().add("dc", "io").add("dc", "spring").add("c", country).add("ou", company)
.add("cn", fullname).build();
}
}

View File

@@ -0,0 +1,125 @@
package example.ldap.odm;
import java.util.Objects;
import javax.naming.Name;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.DnAttribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;
import org.springframework.ldap.odm.annotations.Transient;
@Entry(objectClasses = { "inetOrgPerson", "organizationalPerson", "person", "top" })
public final class Person {
@Id
@JsonIgnore
private Name dn;
@Attribute(name = "cn")
@DnAttribute(value = "cn")
private String fullName;
@Attribute(name = "sn")
private String lastName;
@Attribute(name = "description")
private String description;
@Transient
@DnAttribute(value = "c")
private String country;
@Transient
@DnAttribute(value = "ou")
private String company;
@Attribute(name = "telephoneNumber")
private String phone;
public Name getDn() {
return this.dn;
}
public void setDn(Name dn) {
this.dn = dn;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public String getFullName() {
return this.fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getCompany() {
return this.company;
}
public void setCompany(String company) {
this.company = company;
}
public String getCountry() {
return this.country;
}
public void setCountry(String country) {
this.country = country;
}
public String getPhone() {
return this.phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Person person = (Person) o;
return Objects.equals(this.dn, person.dn) && Objects.equals(this.fullName, person.fullName)
&& Objects.equals(this.lastName, person.lastName)
&& Objects.equals(this.description, person.description) && Objects.equals(this.country, person.country)
&& Objects.equals(this.company, person.company) && Objects.equals(this.phone, person.phone);
}
@Override
public int hashCode() {
return Objects.hash(this.dn, this.fullName, this.lastName, this.description, this.country, this.company,
this.phone);
}
@Override
public String toString() {
return "Person{" + "dn=" + this.dn + ", fullName='" + this.fullName + '\'' + ", lastName='" + this.lastName
+ '\'' + ", description='" + this.description + '\'' + ", country='" + this.country + '\''
+ ", company='" + this.company + '\'' + ", phone='" + this.phone + '\'' + '}';
}
}

View File

@@ -0,0 +1,62 @@
package example.ldap.odm;
import java.util.List;
import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/person")
public class PersonController {
private final PersonDao personDao;
public PersonController(PersonDao personDao) {
this.personDao = personDao;
}
@GetMapping
public List<Person> findAll() {
return this.personDao.findAll();
}
@GetMapping(params = { "country", "company", "fullName" })
public Person showPerson(@RequestParam String country, @RequestParam String company,
@RequestParam String fullName) {
return this.personDao.findByPrimaryKey(country, company, fullName);
}
@PostMapping
public Person addPerson() throws InvalidNameException {
Person person = getPerson();
this.personDao.create(person);
return person;
}
@DeleteMapping(params = { "country", "company", "fullName" })
public void removePerson(@RequestParam String country, @RequestParam String company,
@RequestParam String fullName) {
Person person = this.personDao.findByPrimaryKey(country, company, fullName);
this.personDao.delete(person);
}
private Person getPerson() throws InvalidNameException {
Person person = new Person();
person.setDn(new LdapName("cn=John Doe,ou=company1,c=Sweden,dc=spring,dc=io"));
person.setFullName("John Doe");
person.setLastName("Doe");
person.setCompany("company1");
person.setCountry("Sweden");
person.setDescription("Test user");
person.setPhone("+46 555-123123");
return person;
}
}

View File

@@ -0,0 +1,15 @@
package example.ldap.odm;
import java.util.List;
public interface PersonDao {
void create(Person person);
void delete(Person person);
List<Person> findAll();
Person findByPrimaryKey(String country, String company, String fullname);
}

View File

@@ -0,0 +1,8 @@
spring:
ldap:
embedded:
base-dn: dc=io
credential:
username: uid=admin,ou=system
password: secret
ldif: classpath:setup_data.ldif

View File

@@ -0,0 +1,45 @@
dn: dc=io
objectclass: top
objectclass: domain
objectclass: extensibleObject
dn: dc=spring,dc=io
objectclass: top
objectclass: domain
objectclass: extensibleObject
dn: c=Sweden,dc=spring,dc=io
objectclass: top
objectclass: country
c: Sweden
description: The country of Sweden
dn: ou=company1,c=Sweden,dc=spring,dc=io
objectclass: top
objectclass: organizationalUnit
ou: company1
description: First company in Sweden
dn: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=io
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.person
userPassword: password
cn: Some Person
sn: Person
description: Sweden, Company1, Some Person
telephoneNumber: +46 555-123456
dn: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=io
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: some.person2
userPassword: password
cn: Some Person2
sn: Person2
description: Sweden, Company1, Some Person2
telephoneNumber: +46 555-654321

View File

@@ -0,0 +1,15 @@
package example.ldap.odm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class LdapOdmApplicationTests {
@Test
void contextLoads() {
}
}

View File

@@ -67,6 +67,7 @@ include "jdbc-h2"
include "jdbc-mariadb"
include "jdbc-mysql"
include "jdbc-postgresql"
include "ldap-odm"
include "liquibase"
include "logging-log4j2"
include "logging-logback"
@@ -102,3 +103,4 @@ include "webmvc-tomcat"
include "webmvc-tomcat-tls"
include "websocket"
include "websocket-stomp"