PUT request returns HTTP 400 Bas Request in Spring Mvc - only occasionally - spring

I have a strange issue using Spring mvc: while I'm trying to update one of my resources via PUT, it returns 400 Bad Request for the very same request - but only occasionally.
In Firebug, I use right click "resend" function, so assume all my PUT requests are completely the same.
I also set the log level to ALL for org.springframework.web to find out what's happening on the server side. In case of the response is 200 OK, everything seems fine:
2015-04-10 10:40:20,794 [http-8443-exec-12] TRACE servlet.DispatcherServlet:1048 - Bound request context to thread: SecurityContextHolderAwareRequestWrapper[ FirewalledRequest[ org.apache.catalina.connector.RequestFacade#321fa1b9]]
2015-04-10 10:40:20,795 [http-8443-exec-12] DEBUG servlet.DispatcherServlet:845 - DispatcherServlet with name 'springRestAPI' processing PUT request for [/rest/sites/25]
2015-04-10 10:40:20,796 [http-8443-exec-12] TRACE servlet.DispatcherServlet:1101 - Testing handler map [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#6c9ddcc4] in DispatcherServlet with name 'springRestAPI'
2015-04-10 10:40:20,796 [http-8443-exec-12] DEBUG annotation.RequestMappingHandlerMapping:297 - Looking up handler method for path /sites/25
2015-04-10 10:40:20,797 [http-8443-exec-12] TRACE annotation.RequestMappingHandlerMapping:335 - Found 1 matching mapping(s) for [/sites/25] : [{[/sites/{siteId}],methods=[PUT],params=[],headers=[],consumes=[],produces=[],custom=[]}]
2015-04-10 10:40:20,797 [http-8443-exec-12] DEBUG annotation.RequestMappingHandlerMapping:302 - Returning handler method [public void something.SiteController.updateSite(long,something.resources.UpdatedSiteResource,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]
2015-04-10 10:40:20,797 [http-8443-exec-12] TRACE servlet.DispatcherServlet:1141 - Testing handler adapter [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#5ec2c20d]
2015-04-10 10:40:20,798 [http-8443-exec-12] DEBUG mvc.WebContentInterceptor:146 - Looking up cache seconds for [/sites/25]
2015-04-10 10:40:20,798 [http-8443-exec-12] DEBUG mvc.WebContentInterceptor:158 - Applying default cache seconds to [/sites/25]
2015-04-10 10:40:20,799 [http-8443-exec-12] DEBUG annotation.RequestResponseBodyMethodProcessor:135 - Reading [class something.resources.UpdatedSiteResource] as "application/json;charset=utf-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#4de52e6]
2015-04-10 10:40:21,280 [http-8443-exec-12] DEBUG servlet.DispatcherServlet:1018 - Null ModelAndView returned to DispatcherServlet with name 'springRestAPI': assuming HandlerAdapter completed request handling
2015-04-10 10:40:21,281 [http-8443-exec-12] TRACE servlet.DispatcherServlet:1058 - Cleared thread-bound request context: SecurityContextHolderAwareRequestWrapper[ FirewalledRequest[ org.apache.catalina.connector.RequestFacade#321fa1b9]]
2015-04-10 10:40:21,281 [http-8443-exec-12] DEBUG servlet.DispatcherServlet:996 - Successfully completed request
But when the response is 400, there is nothing in the log: it does not even reaches the DispatcherServlet!
Any idea, how to proceed with this?

Related

Debezium - Oracle Connector - Service Not Starting

DebeziumEngine looking for kafka topic eventhough i have not specified KafkaOffsetBackingStore for offset.storage
Reference : DebeziumEngine Config
Config
Configuration config = Configuration.create()
.with("name", "oracle_debezium_connector")
.with("connector.class", "io.debezium.connector.oracle.OracleConnector")
.with("offset.storage", "org.apache.kafka.connect.storage.FileOffsetBackingStore")
.with("offset.storage.file.filename", "/Users/dk/Documents/work/ACET/offset.dat")
.with("offset.flush.interval.ms", 2000)
.with("database.hostname", "localhost")
.with("database.port", "1521")
.with("database.user", "pravin")
.with("database.password", "*****")
.with("database.sid", "ORCLCDB")
.with("database.server.name", "mServer")
.with("database.out.server.name", "dbzxout")
.with("database.history", "io.debezium.relational.history.FileDatabaseHistory")
.with("database.history.file.filename", "/Users/dk/Documents/work/ACET/dbhistory.dat")
.with("topic.prefix","cycowner")
.with("database.dbname", "ORCLCDB")
.build();
DebeziumEngine
DebeziumEngine<ChangeEvent<String, String>> engine = DebeziumEngine.create(Json.class)
.using(config.asProperties())
.using(connectorCallback)
.using(completionCallback)
.notifying(record -> {
System.out.println(record);
})
.build();
Error :
2022-10-29T16:06:16,457 ERROR [pool-2-thread-1] i.d.c.Configuration: The 'schema.history.internal.kafka.topic' value is invalid: A value is required
2022-10-29T16:06:16,457 ERROR [pool-2-thread-1] i.d.c.Configuration: The 'schema.history.internal.kafka.bootstrap.servers' value is invalid: A value is required**
2022-10-29T16:06:16,458 INFO [pool-2-thread-1] i.d.c.c.BaseSourceTask: Stopping down connector
2022-10-29T16:06:16,463 INFO [pool-3-thread-1] i.d.j.JdbcConnection: Connection gracefully closed
2022-10-29T16:06:16,465 INFO [pool-2-thread-1] o.a.k.c.s.FileOffsetBackingStore: Stopped FileOffsetBackingStore
connector stopped successfully
---------------------------------------------------
success status: false, message : Unable to initialize and start connector's task class 'io.debezium.connector.oracle.OracleConnectorTask' with config: {connector.class=io.debezium.connector.oracle.OracleConnector, database.history.file.filename=/Users/dkuma416/Documents/work/ACET/dbhistory.dat, database.user=pravin, database.dbname=ORCLCDB, offset.storage=org.apache.kafka.connect.storage.FileOffsetBackingStore, database.server.name=mServer, offset.flush.timeout.ms=5000, errors.retry.delay.max.ms=10000, database.port=1521, database.sid=ORCLCDB, offset.flush.interval.ms=2000, topic.prefix=cycowner, offset.storage.file.filename=/Users/dkuma416/Documents/work/ACET/offset.dat, errors.max.retries=-1, database.hostname=localhost, database.password=********, name=oracle_debezium_connector, database.out.server.name=dbzxout, errors.retry.delay.initial.ms=300, value.converter=org.apache.kafka.connect.json.JsonConverter, key.converter=org.apache.kafka.connect.json.JsonConverter, database.history=io.debezium.relational.history.MemoryDatabaseHistory}, **Error: Error configuring an instance of KafkaSchemaHistory; check the logs for details**

elasticsearch - Incorrect HTTP method for uri [/] and method [PUT], allowed: [DELETE, GET, HEAD]

This is my JSON data.
"{\"athena\":{\"settings\":{\"index\":{\"max_ngram_diff\":\"49\",\"mapping\":{\"total_fields\":{\"limit\":\"3000\"},\"ignore_malformed\":\"true\"},\"refresh_interval\":\"30s\",\"number_of_shards\":\"1\",\"max_shingle_diff\":\"4\",\"max_result_window\":\"100000\",\"analysis\":{\"filter\":{\"searchkick_index_shingle\":{\"token_separator\":\"\",\"type\":\"shingle\"},\"analyzed_ngram\":{\"token_chars\":[\"letter\",\"digit\"],\"min_gram\":\"2\",\"type\":\"edge_ngram\",\"max_gram\":\"10\"},\"location_synonym_filter\":{\"type\":\"synonym\",\"synonyms\":[\"e=>east\",\"w=>west\",\"n=>north\",\"s=>south\",\"rd=>road\",\"st=>street\",\"av=>avenue\",\"pkwy=>parkway\",\"hwy=>highway\"]},\"searchkick_stemmer\":{\"type\":\"snowball\",\"language\":\"English\"}},\"char_filter\":{\"ampersand\":{\"type\":\"mapping\",\"mappings\":[\"&=> and \"]}},\"normalizer\":{\"lowercase_normalizer\":{\"filter\":[\"lowercase\"],\"type\":\"custom\"}},\"analyzer\":{\"searchkick_index\":{\"filter\":[\"lowercase\",\"asciifolding\",\"searchkick_index_shingle\",\"searchkick_stemmer\"],\"char_filter\":[\"ampersand\"],\"type\":\"custom\",\"tokenizer\":\"standard\"},\"autocomplete_analyzer\":{\"filter\":[\"lowercase\",\"location_synonym_filter\"],\"token_chars\":[\"letter\",\"digit\"],\"type\":\"custom\",\"stopwords\":\"_none_\",\"tokenizer\":\"standard\"}}},\"number_of_replicas\":\"0\"}}}}"
and I am running this command.
elasticdump --input=./athena-analyzer.json --output=http://localhost:9200 --type=analyzer
and i am getting this error.
{"error":"Incorrect HTTP method for uri [/] and method [PUT], allowed: [DELETE, GET, HEAD]","status":405}

Oauth2 login with Apple ID returns request without CSRF token

I am trying to implement login with Apple ID in a Spring Boot application. I have it currently working so that I get the Apple login screen, and can authorize access. However, when Apple redirects back to https://example.com/myapp/login/oauth2/apple, I get the following error in my log :
2020-03-10 09:41:32.574 DEBUG 13644 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /login/oauth2/code/apple at position 3 of 16 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-03-10 09:41:32.574 DEBUG 13644 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /login/oauth2/code/apple at position 4 of 16 in additional filter chain; firing Filter: 'CsrfFilter'
2020-03-10 09:41:32.575 DEBUG 13644 --- [nio-8080-exec-5] o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for https://example.com/myapp/login/oauth2/code/apple
How can I make this work properly, without disabling CSRF facilities?
The problem is in the samesite=lax in 'session' cookie. Because of that, previous session related to login is being blocked by browser and new session is being created after Apple redirects to redirectUrl. This happens to all POST requests, since it is security issue and browsers drop cross-domain cookies. In order to resolve this issue, I disabled samesite in chrome and added the following config to my backend:
#Configuration
public class CookieConfiguration {
#Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setSameSite("none");
serializer.setUseSecureCookie(true);
return serializer;
}
}
And my csrf config is as following:
.csrf(c -> c
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers("/login/oauth2/code/apple")
)
At least, this gives me a chance to test my code. I will keep updating if I find how to resolve this in production.

Apache Camel Spring Boot - Graceful shutdown of the application after processing the routes

I have couple of routes (route 1 and route 2) in my Spring Boot application. I have been researching how to gracefully shutdown the application after processing both the routes. I have referred the documentation (https://camel.apache.org/manual/latest/graceful-shutdown.html) but couldn't successfully achieve what I needed. Maybe my understanding is wrong.
Below are my two routes
Route 1
from("timer://runOnce?repeatCount=1")
.to("{{sql.selectAll}}")
......... SOME PROCESSING
.to("direct:checkStatus")
Route 2
from("direct:checkStatus")
.delay(5000)
.loopDoWhile(CONDITION)
.process(DO_SOMETHING)
.end()
.to("jpa:com.pqr.MyClass)
.stop();
I have tried all these options
1. Automatic shutdown after 60 seconds
camel.springboot.duration-max-seconds = 60
It does GRACEFULLY shutdown the 2 routes but then WARNs about FORCEFUL shutdown ExecutorsService and also it doesn't stop the main thread to stop the application.
2020-03-01 18:28:25.507 WARN 30279 --- [otTerminateTask] o.a.c.i.e.BaseExecutorServiceManager : Forcing shutdown of ExecutorService: org.apache.camel.util.concurrent.SizedScheduledExecutorService#17fbfb02[CamelSpringBootTerminateTask] due first await termination elapsed.
2020-03-01 18:28:25.507 WARN 30279 --- [otTerminateTask] o.a.c.i.e.BaseExecutorServiceManager : Forcing shutdown of ExecutorService: org.apache.camel.util.concurrent.SizedScheduledExecutorService#17fbfb02[CamelSpringBootTerminateTask] due interrupted.
2020-03-01 18:28:25.508 INFO 30279 --- [otTerminateTask] o.a.c.i.e.BaseExecutorServiceManager : Shutdown of ExecutorService: org.apache.camel.util.concurrent.SizedScheduledExecutorService#17fbfb02[CamelSpringBootTerminateTask] is shutdown: true and terminated: false took: 10.004 seconds.
2020-03-01 18:28:25.508 WARN 30279 --- [otTerminateTask] o.a.c.i.e.BaseExecutorServiceManager : Forced shutdown of 1 ExecutorService's which has not been shutdown properly (acting as fail-safe)
2020-03-01 18:28:25.508 WARN 30279 --- [otTerminateTask] o.a.c.i.e.BaseExecutorServiceManager : forced -> org.apache.camel.util.concurrent.SizedScheduledExecutorService#17fbfb02[CamelSpringBootTerminateTask]
2. Initiate shutdown from the Route2
from("direct:checkStatus")
.delay(5000)
.loopDoWhile(CONDITION)
.process(DO_SOMETHING)
.end()
.to("jpa:com.pqr.MyClass)
.process(exchange -> {
exchange.getContext().getRouteController().stopRoute("route1");
exchange.getContext().getRouteController().stopRoute("route2");
System.out.println("Route1 -->"+exchange.getContext().getRouteController().getRouteStatus("route1"));
System.out.println("Route2 -->"+exchange.getContext().getRouteController().getRouteStatus("route2"));
exchange.getContext().shutdown();
});
"route1" is gracefully stopped but "route2" fails to be gracefully stopped with below message and waits for default timeout (300s).
2020-03-01 18:35:29.113 INFO 30504 --- [read #4 - Delay] o.a.c.i.engine.DefaultShutdownStrategy : Starting to graceful shutdown 1 routes (timeout 300 seconds)
2020-03-01 18:35:29.116 INFO 30504 --- [ - ShutdownTask] o.a.c.i.engine.DefaultShutdownStrategy : Route: route1 shutdown complete, was consuming from: timer://runOnce?repeatCount=1
2020-03-01 18:35:29.116 INFO 30504 --- [read #4 - Delay] o.a.c.i.engine.DefaultShutdownStrategy : Graceful shutdown of 1 routes completed in 0 seconds
2020-03-01 18:35:29.117 INFO 30504 --- [read #4 - Delay] o.a.c.s.boot.SpringBootCamelContext : Route: route1 is stopped, was consuming from: timer://runOnce?repeatCount=1
2020-03-01 18:35:29.117 INFO 30504 --- [read #4 - Delay] o.a.c.i.engine.DefaultShutdownStrategy : Starting to graceful shutdown 1 routes (timeout 300 seconds)
2020-03-01 18:35:29.118 INFO 30504 --- [ - ShutdownTask] o.a.c.i.engine.DefaultShutdownStrategy : Waiting as there are still 1 inflight and pending exchanges to complete, timeout in 300 seconds. Inflights per route: [route2 = 1]
It looks like there is a pending exchange message to be consumed. Do I need to manually clear/consume the exchange message in order to clear and facilitate a graceful shutdown?
Either option doesn't stop the main application. Do I have to write a custom Shutdown strategy instead of DefaultShutdownStrategy to achieve this? Can someone kindly point to an example to shut down the Spring Boot application after completion of the routes? Thanks in advance!!!
Did you try to use exchange.getContext().stop() to stop main application?
To force stop route without waiting for default timeout you can use exchange.getContext().stopRoute(routeId, 1L, TimeUnit.SECONDS); or set your timeout in seconds context.getShutdownStrategy().setTimeout(30);
You have to stop the currently running route from a new thread. The onCompletion() DSL is to make sure every message has been processed.
The attached code is in Kotlin, but it should be easy to transfer it to Java:
fromF(route).id(routeId)
.process(someProcessor)
.to("jdbc:dataSource")
.onCompletion()
.choice().`when`(exchangeProperty("CamelBatchComplete"))
.process(object : Processor {
override fun process(exchange: Exchange) {
Thread {
try {
exchange.context.routeController.stopRoute(routeId)
exchange.context.stop()
} catch (e: Exception) {
throw RuntimeException(e)
}
}.start()
}
}
)
// must use end to denote the end of the onCompletion route
.end()
If you want to stop the entire application, you can use this class and add a call of shutdownManager.initiateShutdown() after the exchange.context.stop().
#Component
class ShutdownManager {
companion object {
val logger = LoggerFactory.getLogger(ShutdownManager::class.java)
}
#Autowired
private val appContext: ApplicationContext? = null
fun initiateShutdown(returnCode: Int) {
logger.info("Shutting down with a Shutdown manager")
SpringApplication.exit(appContext, ExitCodeGenerator { returnCode })
System.exit(returnCode)
}
}

Spock test - RESTClient: HttpResponseException: Not Found

I want to write a test for a GET request when the API returns 404.
My test:
def "Should return 404 - object deleted before"() {
setup:
def advertisementEndpoint = new RESTClient( 'http://localhost:8080/' )
when:
def resp = advertisementEndpoint.get(
path: 'api/advertisement/1',
contentType: groovyx.net.http.ContentType.JSON
)
then:
resp.status == 404
}
My error:
14:24:59.294 [main] DEBUG o.a.h.impl.client.DefaultHttpClient -
Connection can be kept alive indefinitely 14:24:59.305 [main] DEBUG
groovyx.net.http.RESTClient - Response code: 404; found handler:
org.codehaus.groovy.runtime.MethodClosure#312aa7c 14:24:59.306 [main]
DEBUG groovyx.net.http.RESTClient - Parsing response as:
application/json 14:24:59.443 [main] DEBUG org.apache.http.wire - <<
"ba[\r][\n]" 14:24:59.444 [main] DEBUG org.apache.http.wire - <<
"{"timestamp":1436358299234,"status":404,"error":"Not
Found","exception":"com.pgssoft.exparo.web.ResourceNotFoundException","message":"No
message available","path":"/api/advertisement/1"}" 14:24:59.445 [main]
DEBUG org.apache.http.wire - << "[\r][\n]" 14:24:59.445 [main] DEBUG
org.apache.http.wire - << "0[\r][\n]" 14:24:59.446 [main] DEBUG
org.apache.http.wire - << "[\r][\n]" 14:24:59.446 [main] DEBUG
o.a.h.i.c.BasicClientConnectionManager - Releasing connection
org.apache.http.impl.conn.ManagedClientConnectionImpl#2ab4bc72
14:24:59.446 [main] DEBUG o.a.h.i.c.BasicClientConnectionManager -
Connection can be kept alive indefinitely 14:24:59.449 [main] DEBUG
groovyx.net.http.RESTClient - Parsed data to instance of: class
groovy.json.internal.LazyMap
groovyx.net.http.HttpResponseException: Not Found at
groovyx.net.http.RESTClient.defaultFailureHandler(RESTClient.java:263)
at groovy.lang.Closure.call(Closure.java:423) at
groovyx.net.http.HTTPBuilder$1.handleResponse(HTTPBuilder.java:503)
at
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:218)
at
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:160)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:515) at
groovyx.net.http.RESTClient.get(RESTClient.java:119) at
AdvertisementTest.Should return 404 - object delete
before(AdvertisementTest.groovy:79)
You need a failure handler for the underlying HTTPBuilder. From the HTTPBuilder javadoc:
You can also set a default response handler called for any status code
399 that is not matched to a specific handler. Setting the value outside a request closure means it will apply to all future requests
with this HTTPBuilder instance:
http.handler.failure = { resp ->
println "Unexpected failure: ${resp.statusLine}" }
Therefore:
#Grapes(
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1')
)
import groovyx.net.*
import groovyx.net.http.*
def restClient = new RESTClient('http://localhost/wrong')
restClient.handler.failure = { resp -> resp.status }
def response = restClient.get([:])
assert response == 404

Resources