I am using the following starter for Graphql integration
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>6.0.1</version>
</dependency>
I am not sure how to override the SimpleDataFetcherExceptionHandler with my own CustomExceptionHandler. The library already autowires a lot of stuff. Do I need to create a separate configuration for graphQl object? The documentation is not much helpful.
I also tried to integrate #ControllerAdvice to my Graphql java spring boot application but the errors are not matched by the exception handlers inside it. They are handled by GraphQl error handler. How does error propagates inside Graphql?
How can I change this behaviour?
I have this and it's working for me. Pretty much regular spring stuff for exception handling, but there is no #ControllerAdvice (it's kotlin btw, if you can't understand - let me know, but I think it's pretty clear even without kotlin knowledge).
import org.springframework.web.bind.annotation.ExceptionHandler
import com.oembedler.moon.graphql.boot.error.ThrowableGraphQLError
internal class GraphQLExceptionHandler {
#ExceptionHandler(AppException::class)
fun handleGenericException(ex: AppException): ThrowableGraphQLError {
return ThrowableGraphQLError(ex)
}
#ExceptionHandler(Exception::class)
fun handleGenericException(ex: Exception): ThrowableGraphQLError {
return ThrowableGraphQLError(TechnicalException())
}
}
#Configuration
internal open class GraphQLConfiguration {
#Bean
open fun graphQLExceptionHandler(): GraphQLExceptionHandler {
return GraphQLExceptionHandler()
}
}
I have quite a few dependencies tho, in case they matter here:
<graphql.version>5.4.1</graphql.version>
<graphql-datetime-spring-boot-starter.version>1.4.0</graphql-datetime-spring-boot-starter.version>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>${graphql.version}</version>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphiql-spring-boot-starter</artifactId>
<version>${graphql.version}</version>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>voyager-spring-boot-starter</artifactId>
<version>${graphql.version}</version>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>${graphql.version}</version>
</dependency>
<dependency>
<groupId>com.zhokhov.graphql</groupId>
<artifactId>graphql-datetime-spring-boot-starter</artifactId>
<version>${graphql-datetime-spring-boot-starter.version}</version>
</dependency>
Related
I am trying to migrate my springboot application written in kotlin to azure.
I added spring-cloud-azure-starter-keyvault-secrets:4.5.0 dependency in my app, and added below configurations to application.properties.
my.secret=${my-azure-secret}
spring.cloud.azure.keyvault.secret.property-source-enabled=true
spring.cloud.azure.keyvault.secret.property-sources[0].endpoint=<my-vault>.vault.azure.net/
After I add this, the spring boot initialization doesn't work any more and i can't find any logs.
log.info { "Log before springboot initialize" }
SpringApplication(MyApplication::class.java).run(*args)
log.info { "Log after springboot initialize" }
So, Log before springboot initialize is logged, and after that nothing happens (or I can't find any logs afterwards)
I already verified it is not related to any logback settings because if I remove the property spring.cloud.azure.keyvault.secret.property-sources[0].endpoint from application.properties, it boots up properly.
(I also tried to add the additional dependency spring-cloud-azure-dependencies:4.5.0 )
Any clues/hints what is happening and how to resolve it ?
Thanks.
Here I was able to boot the spring application using the same dependencies.
But here I used the latest version of spring-cloud-azure-starter-keyvault-secrets i.e. 5.0.0 also my spring boot version is 3.0.2
my dependencies:
<dependencies>
<dependency> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!-- https://mvnrepository.com/artifact/com.azure.spring/spring-cloud-azure-starter-keyvault-secrets -->
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-keyvault-secrets</artifactId>
<version>5.0.0</version>
</dependency>
<dependency> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency></dependencies>
Also I use windows so instead of my_azure_secret instead of the my-azure-secret
output:
I used Jersey and Webflux with R2DBC. after send the POST via the postman I got this message " Cannot construct instance of reactor.core.publisher.Mono "
This is my JerseyConfiguration:
#Component
public class JerseyConfiguration
extends ResourceConfig {
public JerseyConfiguration() {
register(ProductController.class, 1);
}
}
and this is my Controller:
#Path("/v1")
#Controller
public class ProductController {
#Autowired
private ProductService productService;
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Path("/product")
public Mono<Product> createProduct(#RequestBody Mono<Product> productMono){
return productMono.flatMap(this.productService::createProduct);
}
}
and this sis my service:
#Service
public class ProductService {
#Autowired
private ProductRepository repository;
public Mono<Product> createProduct(final Product product){
return this.repository.save(product);
}
}
and also this my pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Now, this is my problem; I got this message from the postman:
Cannot construct instance of `reactor.core.publisher.Mono` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1]
Please let me know how to solve that problem.
Thank you
You cannot mix WebFlux and Jersey. You should choose one or the other, not both. They both provide an HTTP server engine, but:
Jersey is a Servlet JAX-RS implementation, it does not know anything about reactive streams, Mono, Flux, etc.
Webflux is the Spring HTTP server engine based on reactive streams and async Netty HTTP server.
If you look at Spring Boot reference documentation, section 3.5: Web, you will see that Jersey is one of the available engines, competing with other possible engines, i.e Web MVC and web reactive (webflux).
So, the answer is : Jersey is incompatible with Webflux, and you must choose between Webflux reactive Web and Spring rest annotation, or Jersey and Jax_RS without using Mono/Flux as return-type.
Note 1 : You should annotate your class with #RestController whe using webflux, so it understand that method return is the HTTP response body (see the last paragraph of reference documentation section 1.4.1: #Controller for details.
Note 2 : If you really want to use jersey, but you still require to consume Mono objects from other parts of your system, you might use one of the conversion functions provided by Reactor to return an object that jersey can work with. For example, on Mono object, you will find a toFuture() method. You could also block(), but it could be dangerous.
I am trying to implement the OAuth2 Client Credentials flow with Spring's WebClient like it's described by Baeldung (see here: https://www.baeldung.com/spring-webclient-oauth2).
When I write this line of code
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations,
new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
IntelliJ says that it doesn't know "ServerOAuth2AuthorizedClientExchangeFilterFunction".
The documentation of spring says that the package to import is as follows (see here: https://docs.spring.io/spring-security/site/docs/current-SNAPSHOT/api/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.html):
org.springframework.security.oauth2.client.web.reactive.function.client
I have the following dependencies concerning Spring Security OAuth2:
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.5.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>5.5.1</version>
<type>pom</type>
</dependency>
When I try to manually import it, I come until here:
org.springframework.security.oauth2.client
IntelliJ suggests me a few options, but I need .web which is not listed.
Here is an image of IntelliJs suggestions
And then no suggestions for ".web.reactive.function.client".
Why doesn't this work?
Many thanks
I am facing issues while disabling the introspection query in a spring boot graphql project on a get endpoint query parameter.
I was replicating this by using one of the GET endpoint and using the below parameter
baseurl/servicename/insight_graph?query=fragment+FullType+on+__Type+{++kind++name++description++fields(includeDeprecated%3a+true)+{++++name++++description++++args+{++++++...InputValue++++}++++type+{++++++...TypeRef++++}++++isDeprecated++++deprecationReason++}++inputFields+{++++...InputValue++}++interfaces+{++++...TypeRef++}++enumValues(includeDeprecated%3a+true)+{++++name++++description++++isDeprecated++++deprecationReason++}++possibleTypes+{++++...TypeRef++}}fragment+InputValue+on+__InputValue+{++name++description++type+{++++...TypeRef++}++defaultValue}fragment+TypeRef+on+__Type+{++kind++name++ofType+{++++kind++++name++++ofType+{++++++kind++++++name++++++ofType+{++++++++kind++++++++name++++++++ofType+{++++++++++kind++++++++++name++++++++++ofType+{++++++++++++kind++++++++++++name++++++++++++ofType+{++++++++++++++kind++++++++++++++name++++++++++++++ofType+{++++++++++++++++kind++++++++++++++++name++++++++++++++}++++++++++++}++++++++++}++++++++}++++++}++++}++}}query+IntrospectionQuery+{++__schema+{++++queryType+{++++++name++++}++++mutationType+{++++++name++++}++++types+{++++++...FullType++++}++++directives+{++++++name++++++description++++++locations++++++args+{++++++++...InputValue++++++}++++}++}}
and with the below dependencies
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>5.4.1</version>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>5.4.1</version>
<exclusions>
<exclusion>
<artifactId>jackson-module-kotlin</artifactId>
<groupId>com.fasterxml.jackson.module</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphiql-spring-boot-starter</artifactId>
<version>5.4.1</version>
</dependency>
This works pretty well when we request the same using post and with the below request body and using graphql.tools.introspection-enabled=false and
POST baseurl/servicename/insight_graph
[
{
"operationName": "IntrospectionQuery",
"variables": {},
"query": "query IntrospectionQuery {__schema {queryType { name },mutationType { name },subscriptionType { name },types {...FullType},directives {name,description,args {...InputValue},onOperation,onFragment,onField}}}\nfragment FullType on __Type {kind,name,description,fields(includeDeprecated: true) {name,description,args {...InputValue},type {...TypeRef},isDeprecated,deprecationReason},inputFields {...InputValue},interfaces {...TypeRef},enumValues(includeDeprecated: true) {name,description,isDeprecated,deprecationReason},possibleTypes {...TypeRef}}\nfragment InputValue on __InputValue {name,description,type { ...TypeRef },defaultValue}\nfragment TypeRef on __Type {kind,name,ofType {kind,name,ofType {kind,name,ofType {kind,name}}}}"
}
]
I also tried this via spring filters and it works fine
Is there any way to disable introspection via spring boot property for this?
I am trying to start my application with Apache camel and Quarkus but it giving me below error:
At least one bean matched the required type and qualifiers but was marked as unused and removed during build
Removed beans:
- CLASS bean org.apache.camel.component.servlet.CamelHttpTransportServlet [types=[class javax.servlet.http.HttpServlet, interface java.io.Serializable, class org.apache.camel.http.common.CamelServlet, interface javax.servlet.ServletConfig, interface org.apache.camel.http.common.HttpRegistryProvider, class org.apache.camel.component.servlet.CamelHttpTransportServlet, class javax.servlet.GenericServlet, interface javax.servlet.Servlet], qualifiers=[#javax.enterprise.inject.Default(),
#javax.enterprise.inject.Any()]]
Required type: class org.apache.camel.component.servlet.CamelHttpTransportServlet
Required qualifiers: [#javax.enterprise.inject.Default()]
Solutions:
- Application developers can eliminate false positives via the #Unremovable annotation
- Extensions can eliminate false positives via build items, e.g. using the UnremovableBeanBuildItem
I am not sure what am I missing:
application.properties
camel.context.name=aiv
quarkus.camel.servlet.url-patterns = /rest/*
pom.xml
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-main</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-platform-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-log</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-timer</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-servlet</artifactId>
</dependency>
public class CamelRoute extends RouteBuilder {
#Override
public void configure() {
restConfiguration()
.component("servlet");
...
}
}
Please let me know what wrong am I doing?
Unless you genuinely need Servlet support for some reason, then you can rely on camel-quarkus-platform-http to handle the HTTP transport for the Camel REST DSL.
You're dependencies can be simplified to:
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-main</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-log</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-timer</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-rest</artifactId>
</dependency>
There's more information in the Camel Quarkus documentation:
https://camel.apache.org/camel-quarkus/latest/reference/extensions/platform-http.html