diff --git a/pom.xml b/pom.xml index 5d07e63..5816e03 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.example camel-springboot-xml-example - 0.0.1 + 0.0.2 camel-springboot-xml-example org.springframework.boot @@ -13,7 +13,10 @@ UTF-8 + 17 + 17 4.7.0 + 2.17.2 ${project.parent.version} @@ -33,6 +36,13 @@ pom import + + com.fasterxml.jackson + jackson-bom + ${jackson.version} + pom + import + @@ -44,6 +54,18 @@ org.apache.camel camel-jsonpath + + org.apache.camel + camel-bean-validator + + + org.apache.camel + camel-cxf-rest + + + com.fasterxml.jackson.jakarta.rs + jackson-jakarta-rs-json-provider + org.slf4j slf4j-api @@ -56,6 +78,10 @@ ch.qos.logback logback-core + + jakarta.ws.rs + jakarta.ws.rs-api + @@ -63,8 +89,8 @@ org.apache.maven.plugins maven-compiler-plugin - 17 - 17 + ${maven.compiler.source} + ${maven.compiler.target} diff --git a/src/main/java/com/example/camel/CamelRouter.java b/src/main/java/com/example/camel/CamelRouter.java new file mode 100644 index 0000000..0d5c4f4 --- /dev/null +++ b/src/main/java/com/example/camel/CamelRouter.java @@ -0,0 +1,33 @@ +package com.example.camel; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.bean.validator.BeanValidationException; +import org.springframework.stereotype.Component; + +import jakarta.ws.rs.core.Response; + +@Component +public class CamelRouter extends RouteBuilder { + + @Override + public void configure() throws Exception { + onException(BeanValidationException.class) + .handled(true) + .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(Response.Status.BAD_REQUEST.getStatusCode())) + .setBody(simple("${exchangeProperty.CamelExceptionCaught.getMessage()}")); + + // @formatter:off + from("cxfrs:/api?" + + "resourceClasses=com.example.camel.UserService" + + "&bindingStyle=SimpleConsumer" + + "&providers=jaxrsProvider" + + "&loggingFeatureEnabled=true") + .to("bean-validator:user") + .to("log:camel-cxf-log?showAll=true") + .setHeader(Exchange.BEAN_METHOD_NAME, simple("${header.operationName}")) + .bean(UserServiceImpl.class); + // @formatter:on + } + +} \ No newline at end of file diff --git a/src/main/java/com/example/camel/CxfConfig.java b/src/main/java/com/example/camel/CxfConfig.java new file mode 100644 index 0000000..6970ced --- /dev/null +++ b/src/main/java/com/example/camel/CxfConfig.java @@ -0,0 +1,15 @@ +package com.example.camel; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider; + +@Configuration +public class CxfConfig { + + @Bean + public JacksonJsonProvider jaxrsProvider() { + return new JacksonJsonProvider(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/camel/User.java b/src/main/java/com/example/camel/User.java new file mode 100644 index 0000000..b244fcc --- /dev/null +++ b/src/main/java/com/example/camel/User.java @@ -0,0 +1,52 @@ +package com.example.camel; + +import java.util.StringJoiner; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +/** + * User entity + * + */ +public class User { + + @NotNull(message = "custom message") + private Integer id; + + @NotNull + @Size(min = 3, max = 20) + private String name; + + public User() { + } + + public User(Integer id, String name) { + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return new StringJoiner(", ", User.class.getSimpleName() + "[", "]") + .add("id=" + id) + .add("name='" + name + "'") + .toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/camel/UserService.java b/src/main/java/com/example/camel/UserService.java new file mode 100644 index 0000000..1edb41d --- /dev/null +++ b/src/main/java/com/example/camel/UserService.java @@ -0,0 +1,53 @@ +package com.example.camel; + +import java.util.Collection; + +import jakarta.validation.Valid; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +/** + * Service interface for managing users. + */ +public interface UserService { + + /** + * Find a user by the given ID + * + * @param id + * the ID of the user + * @return the user, or null if user not found. + */ + @GET + @Path("/user/{id}") + @Produces(MediaType.APPLICATION_JSON) + User findUser(@PathParam("id") Integer id); + + /** + * Find all users + * + * @return a collection of all users + */ + @GET + @Path("/user") + @Produces(MediaType.APPLICATION_JSON) + Collection findUsers(); + + /** + * Update the given user + * + * @param user + * the user + */ + @PUT + @Path("/user") + @Consumes(MediaType.APPLICATION_JSON) + Response updateUser(@Valid User user); + +} \ No newline at end of file diff --git a/src/main/java/com/example/camel/UserServiceImpl.java b/src/main/java/com/example/camel/UserServiceImpl.java new file mode 100644 index 0000000..6bba16f --- /dev/null +++ b/src/main/java/com/example/camel/UserServiceImpl.java @@ -0,0 +1,35 @@ +package com.example.camel; + +import java.util.Collection; +import java.util.Map; +import java.util.TreeMap; + +import jakarta.ws.rs.core.Response; + +public class UserServiceImpl implements UserService { + + private final Map users = new TreeMap<>(); + + public UserServiceImpl() { + users.put(1, new User(1, "John Coltrane")); + users.put(2, new User(2, "Miles Davis")); + users.put(3, new User(3, "Sonny Rollins")); + } + + @Override + public User findUser(Integer id) { + return users.get(id); + } + + @Override + public Collection findUsers() { + return users.values(); + } + + @Override + public Response updateUser(User user) { + users.put(user.getId(), user); + return Response.noContent().status(Response.Status.CREATED).build(); + } + +} \ No newline at end of file