spring-cloud-gateway path route predicate don't accept "/" - java

I have a custom gateway filter that use the route written in application.yml,
When I want to change the route predicate from /test/myTest to /public the request return 404 it seemes like the "/" is not reconized because I tried to change /test-myTest to /public and it's work.
Any idea please how can I use a predicate with this format /name/name/**
this is my application.yml :
myTest-gateway:
default-uri: https://app
apps:
/test/myTest: mymicroservice-name
spring:
cloud:
gateway:
enabled: false
x-forwarded:
proto-enabled: false
routes:
- id: appsPrefixPathPublic
uri: ${myTest-gateway.default-uri}
predicates:
- AppPath=/test/myTest
filters:
- StripPrefix=1
- PrefixPath=/public
this is the error that I got it :
No content
< 404 NOT_FOUND Not Found < Content-Type: [application/json] <
Content-Length: [147]
{"timestamp":"2020-08-26T15:44:12.023+0000","path":"/test/myTest/whatever","status":404,"error":"Not
Found","message":null,"requestId":"e7baeeeb-6"}
java.lang.AssertionError: Status expected:<200 OK> but was:<404
NOT_FOUND>

From the documentation :
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
When a request is made through the gateway to /name/blue/red, the request made to nameservice looks like nameservice/red.
You should change 1 to 2.

Related

no cors header response after define cors policy in vs

I have deployed my service with below vs configuration but I am not getting getting any header response. I want to know do I need to define any configuration changes in my service also?
I want to achieve CORS at gateway level not at the service level. I am using Istio 1.12.6. This is the configuration I used for vs with istio.
http:
route:
- destination:
host: {{ $.Values.name | lower }}
subset: {{ $.Values.name | lower }}
port:
number: 80
corsPolicy:
allowOrigins:
- exact: https://example.com
allowCredentials: true
allowHeaders:
- content-type
- authorization
- x-token
- x-origin
- refresh-token
allowMethods:
- GET
- POST
- PUT
- DELETE
- PATCH
- OPTIONS
maxAge: 24h

SwaggerUi does not take the data from the yml file

I am new to the world of Swagger, trying to implement it for my own application. My problem is that SwaggerUi doesn't take my swagger.yml file but takes it into controller. In fact, I have problems with authentication.
Swagger.yml
swagger: "2.0"
info:
version: "1.1"
title: ABC Operations
termsOfService: http://swagger.io/terms/
host: <HOST>
basePath: /abc/operations
tags:
- name: Stored Message
description: Stored Message Operations
schemes:
- http
- https
security:
- basic_auth: []
paths:
/stored-message/{transactionId}:
get:
tags:
- Stored Message
summary: Stored Message Retrieval by TransactionId
produces:
- application/json
parameters:
- in: path
name: transactionId
required: true
type: string
responses:
200:
description: OK
schema:
type: object
404:
description: Not Found
500:
description: Internal Server Error
put:
tags:
- Stored Message
summary: Stored Message Update
consumes:
- application/json
produces:
- application/json
parameters:
- in: path
name: transactionId
required: true
type: string
- in: body
name: Modified Stored Message
schema:
type: object
responses:
200:
description: OK
404:
description: Not Found
500:
description: Internal Server Error
securityDefinitions:
basic_auth:
type: basic
externalDocs:
description: Find out more about Swagger
url: http://swagger.io
In fact in the SwaggerUi part it does not fill in the new field by default.
How can I make swagger Ui fetch data from swagger.yml?
In your "application.property" file you have to add this string
springdoc.swagger-ui.url: /yourfilename.yml
of and specify the yml file you want to use to start the swaggerUi.
The file must be inside src-> resource->static to be viewed. I recommend that you see the official documentation on the Springdoc website https://springdoc.org/faq.html.
Good day

Spring cloud stream RabbitMq - Set properties from source code

I am using Spring cloud stream with RabbitMQ.
I want to be able to configure message and query properties from source code and not from a property file (as they mention in their docs).
For example with the classic Java Client for RabbitMq i can do something like that to create a queue with the properties i want:
//qName, passive, durable, exclusive auto-delete
channel.queueDeclare("myQueue", true, false, false, , false , null);
Any ideas on how can i achieve the same thing using Spring cloud stream?
Inside of "application.yml" you can add all this values , following is example
spring:
cloud:
stream:
instance-count: 1
bindings:
input:
consumer:
concurrency: 2
maxAttempts: 1
group: geode-sink
destination: jdbc-event-result
binder: rabbit
rabbit:
bindings:
input:
consumer:
autoBindDlq: true
republishToDlq: true
requeueRejected: false
rabbitmq:
username: ur-user-name
password: ur-password
host: rabbitmq-url-replace-here
port: 5672
datasource:
platform: mysql
url: jdbc:mysql-url-replace-here
username: ur-user-name
password: ur-password
driverClassName: com.mysql.jdbc.Driver
datasource:
tomcat:
max-wait: 300
min-idle: 10
max-idle: 100
aggregator:
groupCount: 2
batchSize: 1000
batchTimeout: 1000
Updated :
https://cloud.spring.io/spring-cloud-static/spring-cloud-stream-binder-rabbit/2.2.0.M1/spring-cloud-stream-binder-rabbit.html
https://github.com/spring-projects/spring-xd/blob/master/spring-xd-dirt/src/main/resources/application.yml
After digging in their documentation and with the help of #vaquar khan I found out that the only way to do it is from your property file.
application.yml
spring:
cloud:
stream:
bindings:
queue_name :
destination: queue_name
group: your_group_name
durable-subscription : true
This will declare a durable, non-deleting and non-exclusive queue.

How to set Binders for Spring Cloud Stream Bindings on different RabbitMQ vhosts

I'm trying to set up RabbitMQ with Spring Cloud Stream Support
I have a couple consumers and producers. One of the producers should produce messages to a separate virtual host on a same RabbitMQ instance (later it might be different physical instances).
application.yaml
spring:
cloud:
stream:
binders:
binder1:
type: rabbit
defaultCandidate: false
inheritEnvironment: false
environment:
spring:
rabbitmq:
host: localhost
port: 5672
virtual-host: virtual-host-1
username: guest
password: guest
binder2:
type: rabbit
defaultCandidate: false
inheritEnvironment: false
environment:
spring:
rabbitmq:
host: localhost
port: 5672
virtual-host: virtual-host-2
username: guest
password: guest
bindings:
test:
binder: binder1
coordinates:
destination: coordinates
binder: binder1
events:
destination: events
binder: binder1
events_output:
destination: events
binder: binder1
tasks:
destination: tasks
binder: binder2
The goal is that binding tasks should use vhost virtual-host-2. Other bindings should use vhost virtual-host-1.
However binder value seems to be ignored and default rabbit binder is taken into account with default settings on application startup.
I noticed it while debugging the runtime:
The binder value on each binding is NULL. Although the value is explicitly provided in properties.
If I set defaultCandidate of any of the binders to true then that binder settings will be used as a replacement for default one.
Is something misconfigured?
This is one of the reasons why I don't like yaml. It's hard to track what may be misconfigured. In any event, here is the working example I just tried.
spring:
cloud:
stream:
bindings:
input:
binder: rabbit1
group: vhost1-group
destination: vhost1-queue
output:
binder: rabbit2
destination: vhost2-queue
binders:
rabbit1:
type: rabbit
environment:
spring:
rabbitmq:
host: localhost
virtual-host: vhost1
rabbit2:
type: rabbit
environment:
spring:
rabbitmq:
host: localhost
virtual-host: vhost2
I just copied/pasted your config; fixed some indentation and it worked fine for me...
spring:
cloud:
stream:
binders:
binder1:
type: rabbit
defaultCandidate: false
inheritEnvironment: false
environment:
spring:
rabbitmq:
host: localhost
port: 5672
virtual-host: virtual-host-1
username: guest
password: guest
binder2:
type: rabbit
defaultCandidate: false
inheritEnvironment: false
environment:
spring:
rabbitmq:
host: localhost
port: 5672
virtual-host: virtual-host-2
username: guest
password: guest
bindings:
test:
binder: binder1
tasks:
destination: tasks
binder: binder2
#SpringBootApplication
#EnableBinding(Foo.class)
public class So56462671Application {
public static void main(String[] args) {
SpringApplication.run(So56462671Application.class, args);
}
}
interface Foo {
#Input
MessageChannel test();
#Input
MessageChannel tasks();
}
and
defaultCandidate: false
inheritEnvironment: false
were incorrectly indented, but I got a YAML parse error.

Spring cloud, Zuul https

I have problem with https services in my Gateway application ( which uses zuul )
it works great when proxying http services, but i have problems with proxying https services
I have exception
java.lang.IllegalStateException: Could not create URI object: Expected scheme-specific part at index 6: https:
at org.springframework.web.util.HierarchicalUriComponents.toUri(HierarchicalUriComponents.java:430) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
at org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration$OverrideRestClient.reconstructURIWithServer(RibbonClientConfiguration.java:184) ~[spring-cloud-netflix-core-1
at com.netflix.client.AbstractLoadBalancerAwareClient$1.call(AbstractLoadBalancerAwareClient.java:106) ~[ribbon-loadbalancer-2.1.5.jar:2.1.5]
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:303) ~[ribbon-loadbalancer-2.1.5.jar:2.1.5]
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:287) ~[ribbon-loadbalancer-2.1.5.jar:2.1.5]
at rx.internal.util.ScalarSynchronousObservable$4.call(ScalarSynchronousObservable.java:223) ~[rxjava-1.1.5.jar:1.1.5]
at rx.internal.util.ScalarSynchronousObservable$4.call(ScalarSynchronousObservable.java:220) ~[rxjava-1.1.5.jar:1.1.5]
at rx.Observable.unsafeSubscribe(Observable.java:8460) ~[rxjava-1.1.5.jar:1.1.5]
... 150 common frames omitted
aused by: java.net.URISyntaxException: Expected scheme-specific part at index 6: https:
at java.net.URI$Parser.fail(URI.java:2848) ~[na:1.8.0_92]
at java.net.URI$Parser.failExpecting(URI.java:2854) ~[na:1.8.0_92]
at java.net.URI$Parser.parse(URI.java:3057) ~[na:1.8.0_92]
at java.net.URI.<init>(URI.java:673) ~[na:1.8.0_92]
My Gateway config
server:
ssl:
key-store: classpath:my.jks
key-store-password: secret
key-password: secret
spring:
application:
name: mille-gateway
cloud:
config:
discovery:
enabled: true
serviceId: mille-config-server
eureka:
client:
healthcheck:
enabled: true
ribbon:
IsSecure: true
zuul:
ignoredServices: '*'
routes:
test:
path: /test/**
serviceId: mille-test2
test:
ribbon:
ReadTimeout: 5000
MaxAutoRetries: 2
IsSecure: true
My Registry ( Eureka ) server
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
enableSelfPreservation: false
My client configuration
spring:
application:
name: mille-test2
cloud:
config:
discovery:
enabled: true
serviceId: mille-config-server
eureka:
client:
healthcheck:
enabled: true
server:
port: 50000
ssl:
key-store: classpath:my.jks
key-store-password: secret
key-password: secret
eureka:
client:
enabled: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
nonSecurePortEnabled: false
securePortEnabled: true
securePort: ${server.port}
instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
statusPageUrl: https://${eureka.hostname}:${server.port}/info
healthCheckUrl: https://${eureka.hostname}:${server.port}/health
homePageUrl: https://${eureka.instance.hostname}:${server.port}/
secureVirtualHostName: ${spring.application.name}
metadataMap:
hostname: ${eureka.instance.hostname}
securePort: ${server.port}
What could be a problem ?
I have traced this problem in the debugger in Brixton.SR6.
The FeignLoadBalancer.reconstructURIWithServer(...) calls RibbonUtils.updateToHttpsIfNeeded(...) before calling the superclass method that actually adds the server to the uri.
The uri passed in is "", which is the normal case when the incoming url matches the zuul mapping exactly and using service discovery to get the server/port.
updateToHttpsIfNeeded() adds "https" and calls UriComponentsBuilder via build(true) to create an instance of HierarchicalUriComponents.
It then calls toUri() on that instance, which, because of the true passed in to build(), follows the encode == true path and calls new URI(toString()) (line 415). That toString() returns "https:" since we have set the scheme, but not the server or port.
The URI does not like that at all and throws java.net.URISyntaxException: Expected scheme-specific part at index 6: https:.
As to solving the problem, perhaps FeignLoadBalancer should not ensure https until after the server and port are set in the URI? Or perhaps RibbonUtils.updateToHttpsIfNeeded should set the server and port in the UriComponentsBuilder before calling toUri() - it has the Server instance.
This accounts for why it only happens for secure connections. I have not yet found any workaround when using exact url matches in the mapping, other than reverting to Brixton.SR5, which works fine, because the call to build() does not pass the true flag, so new URI() is not called. HTH
Edit: see also spring-cloud-netflix issue 1099.
spring-cloud spring-cloud-netflix netflix-zuul netflix-ribbon
Not sure if you were able to resolve this but I just ran into the same thing. It appears to only occur though when Zuul attempts to proxy a request via https (as you've indicated) to a service endpoint "root".
For instance, taking your Zuul config above - hitting the endpoint /test will likely cause that exception, however hitting any other endpoint proxied to the mille-test2 service (that isn't mapped to the root) will probably work test/something. At least it has for me. So as a temporary work around I've simply created different endpoints that extend the root such as /test/new. Kludgy, yes - but workable.
I'm curently using spring cloud Brixton.SR4.

Categories